1313import sys
1414from dataclasses import dataclass
1515from enum import Enum , unique
16- from typing import Any , NamedTuple
16+ from typing import Any , Final , NamedTuple
1717
1818from src import arch
1919from src .api import config , global_ , utils
20+ from src .arch import AVAILABLE_ARCHITECTURES
2021from src .ply import yacc
2122from src .zxbpp import zxbasmpplex , zxbpplex
2223from src .zxbpp .base_pplex import STDIN
@@ -51,6 +52,9 @@ class PreprocMode(str, Enum):
5152# Default include path
5253INCLUDEPATH : list [str ] = ["stdlib" , "runtime" ]
5354
55+ # Include paths for every arch
56+ INCLUDE_MAP : Final [dict [str , list [str ]]] = {}
57+
5458# Enabled to FALSE if IFDEF failed
5559ENABLED : bool = True
5660
@@ -71,12 +75,12 @@ class ParentIncludingFile(NamedTuple):
7175
7276@dataclass
7377class IncludedFileInfo :
74- once : bool # whether this file is
78+ once : bool # whether this file is to be included only once (e.g. #pragma once)
7579 parents : list [ParentIncludingFile ]
7680
7781
78- # Files already includes , with a list of file, line where they were
79- # included sinc a file can be included more than once.
82+ # Files already included , with a list of ( file, line) tuples where they were
83+ # included, since a file can be included more than once.
8084INCLUDED : dict [str , IncludedFileInfo ] = {}
8185
8286# IFDEFS array
@@ -135,17 +139,29 @@ def init():
135139 reset_id_table ()
136140
137141
138- def get_include_path () -> str :
139- """Default include path using a tricky sys calls ."""
142+ def get_include_path (arch : str = "" ) -> str :
143+ """Default include path using a tricky sys call ."""
140144 return os .path .realpath (
141- os .path .join (os .path .dirname (__file__ ), os .path .pardir , "lib" , "arch" , config .OPTIONS .architecture or "" )
145+ os .path .join (
146+ os .path .dirname (__file__ ),
147+ os .path .pardir ,
148+ "lib" ,
149+ "arch" ,
150+ arch or config .OPTIONS .architecture or "" ,
151+ )
142152 )
143153
144154
145155def set_include_path ():
146156 global INCLUDEPATH
147- pwd = get_include_path ()
148- INCLUDEPATH = [os .path .join (pwd , "stdlib" ), os .path .join (pwd , "runtime" )]
157+
158+ INCLUDE_MAP .clear ()
159+
160+ for arch_ in AVAILABLE_ARCHITECTURES :
161+ pwd = get_include_path (arch_ )
162+ INCLUDE_MAP [arch_ ] = [os .path .join (pwd , "stdlib" ), os .path .join (pwd , "runtime" )]
163+
164+ INCLUDEPATH = INCLUDE_MAP .get (config .OPTIONS .architecture , [])
149165
150166
151167def setMode (mode : PreprocMode ) -> None :
@@ -163,15 +179,17 @@ def setMode(mode: PreprocMode) -> None:
163179 LEXER = lexers [PreprocMode (mode )]
164180
165181
166- def search_filename (fname : str , lineno : int , local_first : bool ) -> str :
182+ def search_filename (fname : str , lineno : int , local_first : bool , arch : str = "" ) -> str :
167183 """Search a filename into the list of the include path.
168184 If local_first is true, it will try first in the current directory of
169185 the file being analyzed.
170186 """
171187 fname = utils .sanitize_filename (fname )
172188
173189 assert CURRENT_DIR is not None
174- i_path : list [str ] = [CURRENT_DIR ] + INCLUDEPATH if local_first else list (INCLUDEPATH )
190+ include_path = INCLUDE_MAP .get (arch , INCLUDEPATH )
191+
192+ i_path : list [str ] = [CURRENT_DIR ] + include_path if local_first else list (include_path )
175193 i_path .extend (config .OPTIONS .include_path .split (":" ) if config .OPTIONS .include_path else [])
176194
177195 if os .path .isabs (fname ):
@@ -187,7 +205,7 @@ def search_filename(fname: str, lineno: int, local_first: bool) -> str:
187205 return ""
188206
189207
190- def include_file (filename : str , lineno : int , local_first : bool ) -> str :
208+ def include_file (filename : str , lineno : int , local_first : bool , arch : str = "" ) -> str :
191209 """Performs a file inclusion (#include) in the preprocessor.
192210 Writes down that "filename" was included at the current file,
193211 at line <lineno>.
@@ -216,7 +234,7 @@ def include_file(filename: str, lineno: int, local_first: bool) -> str:
216234 return LEXER .include (filename )
217235
218236
219- def include_once (filename : str , lineno : int , local_first : bool ) -> str :
237+ def include_once (filename : str , lineno : int , local_first : bool , arch : str = "" ) -> str :
220238 """Performs a file inclusion (#include) in the preprocessor.
221239 Writes down that "filename" was included at the current file,
222240 at line <lineno>.
@@ -231,15 +249,12 @@ def include_once(filename: str, lineno: int, local_first: bool) -> str:
231249 abs_filename = search_filename (filename , lineno , local_first )
232250
233251 if abs_filename not in INCLUDED : # If not already included
234- return include_file (filename , lineno , local_first ) # include it and return
252+ return include_file (filename , lineno , local_first , arch ) # include it and return
235253
236254 # Now checks if the file has been included more than once
237255 if len (INCLUDED [abs_filename ].parents ) > 1 :
238256 parent_file , lineno = INCLUDED [abs_filename ].parents [0 ]
239- warning (
240- lineno ,
241- "file '%s' already included more than once, in file '%s' at line %i" % (filename , parent_file , lineno ),
242- )
257+ warning (lineno , f"file '{ filename } ' already included more than once, in file '{ parent_file } ' at line { lineno } " )
243258
244259 # Empty file (already included)
245260 LEXER .next_token = "_ENDFILE_"
@@ -875,6 +890,7 @@ def main(argv):
875890 output .CURRENT_FILE .append (argv [0 ])
876891 else :
877892 output .CURRENT_FILE .append (global_ .FILENAME )
893+
878894 CURRENT_DIR = os .path .dirname (output .CURRENT_FILE [- 1 ])
879895
880896 if config .OPTIONS .sinclair :
0 commit comments