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,
|
IntegerBuiltInType,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Optional: import builtins loader if you have one
|
from .builtin import load_builtins
|
||||||
# from .builtin import load_builtins # (expected: Callable[[InterpreterState], bool])
|
|
||||||
|
|
||||||
|
|
||||||
class StackType(Enum):
|
class StackType(Enum):
|
||||||
|
|
@ -74,7 +73,7 @@ class InterpreterState:
|
||||||
- functions: dict mapping names to FunctionItem
|
- functions: dict mapping names to FunctionItem
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, load_builtins: Optional[Callable[["InterpreterState"], bool]] = None):
|
def __init__(self):
|
||||||
self.stack: List[StackEntry] = []
|
self.stack: List[StackEntry] = []
|
||||||
self.functions: Dict[str, FunctionItem] = {}
|
self.functions: Dict[str, FunctionItem] = {}
|
||||||
# Optionally load builtins; caller can pass a loader function
|
# Optionally load builtins; caller can pass a loader function
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
from .meta import print_version
|
from .meta import print_version
|
||||||
from .lexer import Lexer
|
from .lexer import LexerInfo, lexical_analysis
|
||||||
from .interpreter import InterpreterState
|
from .interpreter import InterpreterState
|
||||||
from .errors import SlsError
|
|
||||||
|
|
||||||
|
|
||||||
REPL_FILE_NAME = "<STDIN>"
|
REPL_FILE_NAME = "<STDIN>"
|
||||||
|
|
@ -58,12 +57,12 @@ def repl() -> int:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# Create a fresh lexer each iteration
|
# Create a fresh lexer each iteration
|
||||||
lexer = Lexer(REPL_FILE_NAME, line)
|
lexer_info = LexerInfo(filename=REPL_FILE_NAME, source_code=line)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tokens = lexer.lexical_analysis()
|
tokens = lexical_analysis(lexer_info)
|
||||||
except SlsError as err:
|
except Exception as err:
|
||||||
print(err.message)
|
print(err)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Execute tokens in order
|
# Execute tokens in order
|
||||||
|
|
@ -73,8 +72,8 @@ def repl() -> int:
|
||||||
if not ok:
|
if not ok:
|
||||||
print("A runtime error occurred!")
|
print("A runtime error occurred!")
|
||||||
break
|
break
|
||||||
except SlsError as err:
|
except Exception as err:
|
||||||
print(err.message)
|
print(err)
|
||||||
break
|
break
|
||||||
|
|
||||||
print_top_of_stack(interpreter)
|
print_top_of_stack(interpreter)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue