from io import TextIOWrapper
from exceptions import *
from consts import *
+import logging
+
+logger: logging.Logger = logging.getLogger(__name__)
class Remilia:
def parse_file(self: Self) -> bool:
done: bool = False
- with open(self.src) as src:
- imports: dict[int, list[int]] = {}
- import_paths: dict[int, list[str]] = {}
- for i, line in enumerate(src.readlines(), 1):
+ cont: bool = False
+ with open(self.src) as srccnt:
+ src: list[str] = srccnt.readlines()
+ logger.debug(f"{src = }")
+ imports: dict[int, list[int]] = {}
+ import_paths: dict[int, list[str]] = {}
+ while True:
+ for i, line in enumerate(src, 1):
if KW_IMPORT in line:
inter: list[int] = []
inter.append(line.index(KW_IMPORT))
try:
asz: int = loc + SIZEOF
end: int = line.index('"', asz + 1)
- print(f"{end = }")
+ logger.debug(f"{end = }")
new_path: str = line[asz:end]
- print(f"{new_path = }")
+ logger.debug(f"{new_path = }")
paths.append(new_path)
except ValueError:
raise UnterminatedQuoteException(
f"Could not find another quote at line {i}"
)
import_paths[i] = paths
+ logger.debug(f"{imports = }")
+ logger.debug(f"{import_paths = }")
if len(imports) == 0:
done = True
- if not done:
- self.__read_and_replace(imports, import_paths)
- return done
+ logger.debug(f"{done = }")
+ logger.debug(f"{len(imports) = }")
+ logger.debug(f"{imports.keys() = }")
+ for i in list(imports.keys()):
+ logger.debug(f"{i = }")
+ if not done:
+ self.__read_and_replace(imports, import_paths)
+ cont = True
+ imports.pop(i)
+ import_paths.pop(i)
+ if cont:
+ logger.debug(f"if cont: {imports = }")
+ logger.debug(f"if cont: {import_paths = }")
+ cont = False
+ if len(imports) == 0 and len(import_paths) == 0:
+ return True
+ continue
+ if done:
+ return True
- def printall(self):
- self.parse_file()
-
- # TODO: make this private
- def import_file(self: Self, path: str) -> None:
+ def __import_file(self: Self, path: str) -> None:
if path in self.__seen_files:
raise CircularImportException(
f"Circular import! I've already seen file {path}!"
def __read_and_replace(
self: Self, imports: dict[int, list[int]], import_paths: dict[int, list[str]]
) -> None:
- with open(self.src.replace(FILE_EXT, HTML_EXT), "rw") as src:
- final_str: str = ""
+ final_str: str = ""
+ logger.debug(f"{self.__seen_files = }")
+ with open(self.src, "r") as src:
for i, line in enumerate(src.readlines(), 1):
+ tmp: str = line
if i in imports.keys():
+ delta: int = 0
for n, __import in enumerate(imports[i]):
+ logger.debug("=" * 20)
+ logger.debug(f"{__import = }")
+ logger.debug(f"{delta = }")
+ logger.debug(f"{tmp[__import] = }")
+ logger.debug(f"{tmp[__import - delta] = }")
+ logger.debug(f"{tmp = }")
+ logger.debug(f"{line = }")
+ fc: str = self.__get_file_contents(import_paths[i][n])
+ lenfc: int = len(fc)
repl_str = (
- line[:__import]
- + self.__get_file_contents(import_paths[i][n])
- + line[__import + len(import_paths[i][n]) + 1]
+ tmp[: __import - delta]
+ + fc
+ + tmp[
+ (__import - delta)
+ + SIZEOF
+ + len(import_paths[i][n])
+ + 2 :
+ ]
)
- pass
+ logger.debug(f"{repl_str = }")
+ tmp = repl_str
+ if n < len(imports[i]) - 1:
+ delta = lenfc - imports[i][n + 1] + 2
+ if n == len(imports[i]) - 1:
+ final_str += repl_str
+ logger.debug("=" * 20)
+ if i not in imports.keys():
+ final_str += line
+ logger.debug(f"{final_str = }")
+ with open(self.src.replace(FILE_EXT, HTML_EXT), "w") as f:
+ f.write(final_str)
def __get_file_contents(self: Self, file: str) -> str:
- self.import_file(file)
+ logger.debug(f"{file = }")
+ self.__import_file(file)
with open(file) as f:
- return f.read()
-
-
-def replace_at_location(original_string, start_index, length, replacement_string):
- # Calculate the end index of the string to be replaced
- end_index = start_index + length
-
- # Create the new string by slicing and concatenating
- new_string = (
- original_string[:start_index] + replacement_string + original_string[end_index:]
- )
-
- return new_string
+ return "".join(f.readlines())
#!/usr/bin/env python3
from importer import Remilia
+from consts import FLAG_DEBUG
+import logging
import sys
-def mmain() -> int:
+logger: logging.Logger = logging.getLogger(__name__)
+
+def main() -> int:
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <file>")
return -1
compiler: Remilia = Remilia(sys.argv[1])
- while True:
- done: bool = compiler.parse_file()
- if done: break
+ compiler.parse_file()
+
+ print(f"Compiled {sys.argv[1]}")
return 0
-def main() -> int:
- test: Remilia = Remilia("./test.txt")
- test.import_file("./test2.txt")
- test.printall()
+def debugmain() -> int:
+ compiler: Remilia = Remilia("./test1.rem")
+ compiler.parse_file()
+ print(f"Compiled ./test1.rem")
return 0
if __name__ == '__main__':
- raise SystemExit(main())
+ logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format="%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s")
+ if FLAG_DEBUG: fn = debugmain
+ else: fn = main
+ raise SystemExit(fn())