From 2c8e459cac84a076941fa6dcba335ea45abb262c Mon Sep 17 00:00:00 2001 From: Kyler Date: Tue, 2 Dec 2025 23:34:29 -0700 Subject: [PATCH] Added file and main --- SLS_Python/sls/__main__.py | 33 +++++++++++++++++++++++++++++++ SLS_Python/sls/builtin.py | 9 +++++++++ SLS_Python/sls/file.py | 37 +++++++++++++++++++++++++++++++++++ SLS_Python/sls/interpreter.py | 5 ++--- SLS_Python/sls/repl.py | 15 +++++++------- 5 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 SLS_Python/sls/__main__.py create mode 100644 SLS_Python/sls/file.py diff --git a/SLS_Python/sls/__main__.py b/SLS_Python/sls/__main__.py new file mode 100644 index 0000000..f6e7fe1 --- /dev/null +++ b/SLS_Python/sls/__main__.py @@ -0,0 +1,33 @@ +import sys +from .meta import print_version +from .repl import repl +from .file import run_file + + +def main() -> int: + args = sys.argv[1:] + + version = False + filename = None + + if len(args) == 1: + if args[0] in ("--version", "-v"): + version = True + else: + filename = args[0] + elif len(args) > 1: + print("Too many arguments!") + return 1 + + if version: + print_version() + return 0 + + if filename is not None: + return run_file(filename) + + return repl() + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/SLS_Python/sls/builtin.py b/SLS_Python/sls/builtin.py index e69de29..d8b9d23 100644 --- a/SLS_Python/sls/builtin.py +++ b/SLS_Python/sls/builtin.py @@ -0,0 +1,9 @@ + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .interpreter import InterpreterState + + +def load_builtins(interpreter_state: "InterpreterState") -> bool: + return True diff --git a/SLS_Python/sls/file.py b/SLS_Python/sls/file.py new file mode 100644 index 0000000..3d0c7f7 --- /dev/null +++ b/SLS_Python/sls/file.py @@ -0,0 +1,37 @@ +from pathlib import Path +from sls.lexer import LexerInfo, lexical_analysis, Token +from sls.interpreter import InterpreterState + + +def exec_file(interpreter_state: InterpreterState, filename: str) -> bool: + path = Path(filename) + + if not path.exists(): + print(f"Cannot read file: {filename}") + return False + + try: + code = path.read_text() + except Exception: + print(f"Cannot read file: {filename}") + return False + + lexer_info = LexerInfo(filename=filename, source_code=code) + + tokens: list[Token] = lexical_analysis(lexer_info) + + for tok in tokens: + if not interpreter_state.execute(tok): + print("A runtime error occurred!") + return False + + return True + +def run_file(filename: str) -> int: + print(f"Executing file: {filename}") + + interpreter_state = InterpreterState() + + success = exec_file(interpreter_state, filename) + + return 0 if success else 1 diff --git a/SLS_Python/sls/interpreter.py b/SLS_Python/sls/interpreter.py index c7eb0e1..fc059f1 100644 --- a/SLS_Python/sls/interpreter.py +++ b/SLS_Python/sls/interpreter.py @@ -19,8 +19,7 @@ from .lexer import ( IntegerBuiltInType, ) -# Optional: import builtins loader if you have one -# from .builtin import load_builtins # (expected: Callable[[InterpreterState], bool]) +from .builtin import load_builtins class StackType(Enum): @@ -74,7 +73,7 @@ class InterpreterState: - functions: dict mapping names to FunctionItem """ - def __init__(self, load_builtins: Optional[Callable[["InterpreterState"], bool]] = None): + def __init__(self): self.stack: List[StackEntry] = [] self.functions: Dict[str, FunctionItem] = {} # Optionally load builtins; caller can pass a loader function diff --git a/SLS_Python/sls/repl.py b/SLS_Python/sls/repl.py index 39fc85e..e8b3fa6 100644 --- a/SLS_Python/sls/repl.py +++ b/SLS_Python/sls/repl.py @@ -1,7 +1,6 @@ from .meta import print_version -from .lexer import Lexer +from .lexer import LexerInfo, lexical_analysis from .interpreter import InterpreterState -from .errors import SlsError REPL_FILE_NAME = "" @@ -58,12 +57,12 @@ def repl() -> int: return 0 # Create a fresh lexer each iteration - lexer = Lexer(REPL_FILE_NAME, line) + lexer_info = LexerInfo(filename=REPL_FILE_NAME, source_code=line) try: - tokens = lexer.lexical_analysis() - except SlsError as err: - print(err.message) + tokens = lexical_analysis(lexer_info) + except Exception as err: + print(err) continue # Execute tokens in order @@ -73,8 +72,8 @@ def repl() -> int: if not ok: print("A runtime error occurred!") break - except SlsError as err: - print(err.message) + except Exception as err: + print(err) break print_top_of_stack(interpreter)