1414import sys
1515import os
1616import argparse
17- from typing import NamedTuple , List
17+
18+ from typing import Any
19+ from typing import List
20+ from typing import NamedTuple
21+ from typing import Optional
1822
1923from .zxbpplex import tokens # noqa
2024from src .libzxbpp import zxbpplex
4751CURRENT_DIR = None
4852
4953# Default include path
50- INCLUDEPATH = ['library' , 'library-asm' ]
54+ INCLUDEPATH : List [ str ] = ['library' , 'library-asm' ]
5155
5256# Enabled to FALSE if IFDEF failed
5357ENABLED : bool = True
@@ -100,7 +104,7 @@ def init():
100104 del output .CURRENT_FILE [:]
101105
102106
103- def get_include_path ():
107+ def get_include_path () -> str :
104108 """ Default include path using a tricky sys calls.
105109 """
106110 return os .path .realpath (os .path .join (
@@ -117,7 +121,7 @@ def set_include_path():
117121 INCLUDEPATH = [os .path .join (pwd , 'library' ), os .path .join (pwd , 'library-asm' )]
118122
119123
120- def setMode (mode ) :
124+ def setMode (mode : str ) -> None :
121125 global LEXER
122126
123127 mode = mode .upper ()
@@ -130,14 +134,17 @@ def setMode(mode):
130134 LEXER = zxbpplex .Lexer ()
131135
132136
133- def search_filename (fname , lineno , local_first ) :
137+ def search_filename (fname : str , lineno : int , local_first : bool ) -> str :
134138 """ Search a filename into the list of the include path.
135139 If local_first is true, it will try first in the current directory of
136140 the file being analyzed.
137141 """
138142 fname = src .api .utils .sanitize_filename (fname )
139- i_path = [CURRENT_DIR ] + INCLUDEPATH if local_first else list (INCLUDEPATH )
143+
144+ assert CURRENT_DIR is not None
145+ i_path : List [str ] = [CURRENT_DIR ] + INCLUDEPATH if local_first else list (INCLUDEPATH )
140146 i_path .extend (OPTIONS .include_path .split (':' ) if OPTIONS .include_path else [])
147+
141148 if os .path .isabs (fname ):
142149 if os .path .isfile (fname ):
143150 return fname
@@ -151,7 +158,7 @@ def search_filename(fname, lineno, local_first):
151158 return ''
152159
153160
154- def include_file (filename , lineno , local_first ) :
161+ def include_file (filename : str , lineno : int , local_first : bool ) -> str :
155162 """ Performs a file inclusion (#include) in the preprocessor.
156163 Writes down that "filename" was included at the current file,
157164 at line <lineno>.
@@ -174,7 +181,7 @@ def include_file(filename, lineno, local_first):
174181 return LEXER .include (filename )
175182
176183
177- def include_once (filename , lineno , local_first ) :
184+ def include_once (filename : str , lineno : int , local_first : bool ) -> str :
178185 """ Performs a file inclusion (#include) in the preprocessor.
179186 Writes down that "filename" was included at the current file,
180187 at line <lineno>.
@@ -201,6 +208,20 @@ def include_once(filename, lineno, local_first):
201208 return ''
202209
203210
211+ def expand_macros (macros : List [Any ], lineno : int ) -> Optional [str ]:
212+ try :
213+ tmp = '' .join (remove_spaces (str (x ())) if isinstance (x , MacroCall ) else x for x in macros )
214+ except PreprocError as v :
215+ error (v .lineno , v .message )
216+ return None
217+
218+ if '\n ' in tmp :
219+ tmp += f'\n #line { lineno + 1 } '
220+ tmp += '\n '
221+
222+ return tmp
223+
224+
204225# -------- GRAMMAR RULES for the preprocessor ---------
205226def p_start (p ):
206227 """ start : program
@@ -227,15 +248,12 @@ def p_program(p):
227248def p_program_tokenstring (p ):
228249 """ program : defs NEWLINE
229250 """
230- try :
231- tmp = [remove_spaces (str (x ())) if isinstance (x , MacroCall ) else x for x in p [1 ]]
232- except PreprocError as v :
233- error (v .lineno , v .message )
251+ tmp = expand_macros (p [1 ], p .lineno (2 ))
252+ if tmp is None :
234253 p [0 ] = []
235254 return
236255
237- tmp .append (p [2 ])
238- p [0 ] = tmp
256+ p [0 ] = [tmp ]
239257
240258
241259def p_program_tokenstring_2 (p ):
@@ -261,22 +279,19 @@ def p_program_char(p):
261279def p_program_newline (p ):
262280 """ program : program defs NEWLINE
263281 """
264- try :
265- tmp = [remove_spaces (str (x ())) if isinstance (x , MacroCall ) else x for x in p [2 ]]
266- except PreprocError as v :
267- error (v .lineno , v .message )
282+ tmp = expand_macros (p [2 ], p .lineno (3 ))
283+ if tmp is None :
268284 p [0 ] = []
269285 return
270286
271287 p [0 ] = p [1 ]
272- p [0 ].extend (tmp )
273- p [0 ].append (p [3 ])
288+ p [0 ].append (tmp )
274289
275290
276291def p_program_newline_2 (p ):
277292 """ program : program define NEWLINE
278293 """
279- p [0 ] = p [1 ] + p [ 2 ] + [ p [ 3 ] ]
294+ p [0 ] = p [1 ] + [ f'#line { p . lineno ( 3 ) + 1 } " { output . CURRENT_FILE [ - 1 ] } " \n ' ]
280295
281296
282297def p_token (p ):
0 commit comments