from typing import Dict, List, Optional, cast from position import Node from utils import Err, Ok, Result import parsed class Value: pass class Unit(Value): def __init__(self) -> None: super().__init__() class Int(Value): def __init__(self, value: int) -> None: super().__init__() self.value = value class Char(Value): def __init__(self, value: str) -> None: super().__init__() self.value = value class String(Value): def __init__(self, value: str) -> None: super().__init__() self.value = value class Bool(Value): def __init__(self, value: bool) -> None: super().__init__() self.value = value class EvalResult: pass class ValueResult(EvalResult): def __init__(self, value: Value) -> None: super().__init__() self.value = value class ReturnResult(EvalResult): def __init__(self, value: Optional[Value]) -> None: super().__init__() self.value = value class BreakResult(EvalResult): def __init__(self, value: Optional[Value]) -> None: super().__init__() self.value = value class ContinueResult(EvalResult): def __init__(self, value: Optional[Value]) -> None: super().__init__() self.value = value class PanicResult(EvalResult): def __init__(self, message: str) -> None: super().__init__() self.message = message class SymbolTable: def __init__(self) -> None: self.symbols: Dict[str, Value] = {} def define(self, symbol_id: str, value: Value) -> Result[None, str]: if symbol_id in self.symbols: return Err("symbol already defined") return Ok(None) class Evaluator: def __init__(self) -> None: pass def evaluate(self, ast: List[Node[parsed.Expr]]) -> None: for node in ast: self.eval_expr(node) def eval_expr(self, node: Node[parsed.Expr]) -> EvalResult: if isinstance(node.value, parsed.ExprError): return PanicResult(f"error: {cast(parsed.ExprError, node.value).message}, at {node.span}") elif isinstance(node.value, parsed.Id): raise NotImplementedError() elif isinstance(node.value, parsed.Int): return ValueResult(Int(cast(parsed.Int, node.value).value)) elif isinstance(node.value, parsed.Char): return ValueResult(Char(cast(parsed.Char, node.value).value)) elif isinstance(node.value, parsed.String): return ValueResult(String(cast(parsed.String, node.value).value)) elif isinstance(node.value, parsed.Bool): return ValueResult(Bool(cast(parsed.Bool, node.value).value)) elif isinstance(node.value, parsed.Unit): return ValueResult(Unit()) elif isinstance(node.value, parsed.Tuple): raise NotImplementedError() elif isinstance(node.value, parsed.Block): raise NotImplementedError() elif isinstance(node.value, parsed.Lambda): raise NotImplementedError() elif isinstance(node.value, parsed.If): raise NotImplementedError() elif isinstance(node.value, parsed.Match): raise NotImplementedError() elif isinstance(node.value, parsed.Loop): raise NotImplementedError() elif isinstance(node.value, parsed.While): raise NotImplementedError() elif isinstance(node.value, parsed.For): raise NotImplementedError() elif isinstance(node.value, parsed.StructMember): raise NotImplementedError() elif isinstance(node.value, parsed.TupleMember): raise NotImplementedError() elif isinstance(node.value, parsed.Index): raise NotImplementedError() elif isinstance(node.value, parsed.Call): raise NotImplementedError() elif isinstance(node.value, parsed.Unary): raise NotImplementedError() elif isinstance(node.value, parsed.Binary): raise NotImplementedError() elif isinstance(node.value, parsed.Assign): raise NotImplementedError() elif isinstance(node.value, parsed.Let): raise NotImplementedError() elif isinstance(node.value, parsed.Function): raise NotImplementedError() elif isinstance(node.value, parsed.Return): raise NotImplementedError() elif isinstance(node.value, parsed.Break): raise NotImplementedError() elif isinstance(node.value, parsed.Continue): raise NotImplementedError() else: raise NotImplementedError(str(node))