diff --git a/evaluator.py b/evaluator.py index 269dc06..c1b258b 100644 --- a/evaluator.py +++ b/evaluator.py @@ -1,5 +1,5 @@ from typing import Dict, List, Optional, cast -from position import Node +from position import Node, Span from utils import Err, Ok, Result import parsed @@ -30,6 +30,9 @@ class Bool(Value): super().__init__() self.value = value +class Type: + pass + class EvalResult: pass @@ -60,16 +63,36 @@ class PanicResult(EvalResult): class SymbolTable: def __init__(self) -> None: - self.symbols: Dict[str, Value] = {} + self.values: Dict[str, Value] = {} + self.types: Dict[str, Type] = {} - def define(self, symbol_id: str, value: Value) -> Result[None, str]: - if symbol_id in self.symbols: + def define_value(self, symbol_id: str, value: Value) -> Result[None, str]: + if symbol_id in self.values: return Err("symbol already defined") + self.values[symbol_id] = value return Ok(None) + def define_type(self, symbol_id: str, value_type: Type) -> Result[None, str]: + if symbol_id in self.types: + return Err("symbol already defined") + self.types[symbol_id] = value_type + return Ok(None) + + def value(self, symbol_id: str) -> Optional[Value]: + if symbol_id not in self.values: + return None + else: + return self.values[symbol_id] + + def type(self, symbol_id: str) -> Optional[Type]: + if symbol_id not in self.types: + return None + else: + return self.types[symbol_id] + class Evaluator: def __init__(self) -> None: - pass + self.table = SymbolTable() def evaluate(self, ast: List[Node[parsed.Expr]]) -> None: for node in ast: @@ -77,59 +100,140 @@ class Evaluator: 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}") + return self.eval_expr_error(cast(parsed.ExprError, node.value), node.span) elif isinstance(node.value, parsed.Id): - raise NotImplementedError() + return self.eval_id(cast(parsed.Id, node.value), node.span) elif isinstance(node.value, parsed.Int): - return ValueResult(Int(cast(parsed.Int, node.value).value)) + return self.eval_int(cast(parsed.Int, node.value), node.span) elif isinstance(node.value, parsed.Char): - return ValueResult(Char(cast(parsed.Char, node.value).value)) + return self.eval_char(cast(parsed.Char, node.value), node.span) elif isinstance(node.value, parsed.String): - return ValueResult(String(cast(parsed.String, node.value).value)) + return self.eval_string(cast(parsed.String, node.value), node.span) elif isinstance(node.value, parsed.Bool): - return ValueResult(Bool(cast(parsed.Bool, node.value).value)) + return self.eval_bool(cast(parsed.Bool, node.value), node.span) elif isinstance(node.value, parsed.Unit): - return ValueResult(Unit()) + return self.eval_unit(cast(parsed.Unit, node.value), node.span) elif isinstance(node.value, parsed.Tuple): - raise NotImplementedError() + return self.eval_tuple(cast(parsed.Tuple, node.value), node.span) elif isinstance(node.value, parsed.Block): - raise NotImplementedError() + return self.eval_block(cast(parsed.Block, node.value), node.span) elif isinstance(node.value, parsed.Lambda): - raise NotImplementedError() + return self.eval_lambda(cast(parsed.Lambda, node.value), node.span) elif isinstance(node.value, parsed.If): - raise NotImplementedError() + return self.eval_if(cast(parsed.If, node.value), node.span) elif isinstance(node.value, parsed.Match): - raise NotImplementedError() + return self.eval_match(cast(parsed.Match, node.value), node.span) elif isinstance(node.value, parsed.Loop): - raise NotImplementedError() + return self.eval_loop(cast(parsed.Loop, node.value), node.span) elif isinstance(node.value, parsed.While): - raise NotImplementedError() + return self.eval_while(cast(parsed.While, node.value), node.span) elif isinstance(node.value, parsed.For): - raise NotImplementedError() + return self.eval_for(cast(parsed.For, node.value), node.span) elif isinstance(node.value, parsed.StructMember): - raise NotImplementedError() + return self.eval_struct_member(cast(parsed.StructMember, node.value), node.span) elif isinstance(node.value, parsed.TupleMember): - raise NotImplementedError() + return self.eval_tuple_member(cast(parsed.TupleMember, node.value), node.span) elif isinstance(node.value, parsed.Index): - raise NotImplementedError() + return self.eval_index(cast(parsed.Index, node.value), node.span) elif isinstance(node.value, parsed.Call): - raise NotImplementedError() + return self.eval_call(cast(parsed.Call, node.value), node.span) elif isinstance(node.value, parsed.Unary): - raise NotImplementedError() + return self.eval_unary(cast(parsed.Unary, node.value), node.span) elif isinstance(node.value, parsed.Binary): - raise NotImplementedError() + return self.eval_binary(cast(parsed.Binary, node.value), node.span) elif isinstance(node.value, parsed.Assign): - raise NotImplementedError() + return self.eval_assign(cast(parsed.Assign, node.value), node.span) elif isinstance(node.value, parsed.Let): - raise NotImplementedError() + return self.eval_let(cast(parsed.Let, node.value), node.span) elif isinstance(node.value, parsed.Function): - raise NotImplementedError() + return self.eval_function(cast(parsed.Function, node.value), node.span) elif isinstance(node.value, parsed.Return): - raise NotImplementedError() + return self.eval_return(cast(parsed.Return, node.value), node.span) elif isinstance(node.value, parsed.Break): - raise NotImplementedError() + return self.eval_break(cast(parsed.Break, node.value), node.span) elif isinstance(node.value, parsed.Continue): - raise NotImplementedError() + return self.eval_continue(cast(parsed.Continue, node.value), node.span) else: raise NotImplementedError(str(node)) + def eval_expr_error(self, expr: parsed.ExprError, span: Span) -> EvalResult: + return PanicResult(f"error: {expr.message}, at {span}") + + def eval_id(self, expr: parsed.Id, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_int(self, expr: parsed.Int, span: Span) -> EvalResult: + return ValueResult(Int(expr.value)) + + def eval_char(self, expr: parsed.Char, span: Span) -> EvalResult: + return ValueResult(Char(expr.value)) + + def eval_string(self, expr: parsed.String, span: Span) -> EvalResult: + return ValueResult(String(expr.value)) + + def eval_bool(self, expr: parsed.Bool, span: Span) -> EvalResult: + return ValueResult(Bool(expr.value)) + + def eval_unit(self, expr: parsed.Unit, span: Span) -> EvalResult: + return ValueResult(Unit()) + + def eval_tuple(self, expr: parsed.Tuple, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_block(self, expr: parsed.Block, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_lambda(self, expr: parsed.Lambda, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_if(self, expr: parsed.If, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_match(self, expr: parsed.Match, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_loop(self, expr: parsed.Loop, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_while(self, expr: parsed.While, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_for(self, expr: parsed.For, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_struct_member(self, expr: parsed.StructMember, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_tuple_member(self, expr: parsed.TupleMember, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_index(self, expr: parsed.Index, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_call(self, expr: parsed.Call, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_unary(self, expr: parsed.Unary, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_binary(self, expr: parsed.Binary, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_assign(self, expr: parsed.Assign, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_let(self, expr: parsed.Let, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_function(self, expr: parsed.Function, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_return(self, expr: parsed.Return, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_break(self, expr: parsed.Break, span: Span) -> EvalResult: + raise NotImplementedError() + + def eval_continue(self, expr: parsed.Continue, span: Span) -> EvalResult: + raise NotImplementedError() +