Added file and main
This commit is contained in:
parent
a754cd4df4
commit
2c8e459cac
|
|
@ -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())
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = "<STDIN>"
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue