add some eval

This commit is contained in:
SimonFJ20 2023-06-14 22:35:06 +02:00
parent 1f3d16aef1
commit 82a56e1d47
3 changed files with 62 additions and 28 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
__pycache__ __pycache__
.mypy_cache .mypy_cache
session.vim

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from typing import Dict, List, Optional, cast from typing import Dict, List, Optional, cast
from position import Node, Span from position import Node, Span
from utils import Err, Ok, Result from utils import Err, Ok, Result
@ -6,41 +7,59 @@ import parsed
class Value: class Value:
pass pass
class Unit(Value): class UnitValue(Value):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
class Int(Value): class IntValue(Value):
def __init__(self, value: int) -> None: def __init__(self, value: int) -> None:
super().__init__() super().__init__()
self.value = value self.value = value
class Char(Value): class CharValue(Value):
def __init__(self, value: str) -> None: def __init__(self, value: str) -> None:
super().__init__() super().__init__()
self.value = value self.value = value
class String(Value): class StringValue(Value):
def __init__(self, value: str) -> None: def __init__(self, value: str) -> None:
super().__init__() super().__init__()
self.value = value self.value = value
class Bool(Value): class BoolValue(Value):
def __init__(self, value: bool) -> None: def __init__(self, value: bool) -> None:
super().__init__() super().__init__()
self.value = value self.value = value
class TupleValue(Value):
def __init__(self, values: List[Value]) -> None:
super().__init__()
self.values = values
class Type: class Type:
pass pass
class EvalResult: class EvalResult:
def __init__(self) -> None:
pass pass
def is_value(self) -> bool:
return False
def as_value(self) -> ValueResult:
raise Exception("guess it wasn't a value")
class ValueResult(EvalResult): class ValueResult(EvalResult):
def __init__(self, value: Value) -> None: def __init__(self, value: Value) -> None:
super().__init__() super().__init__()
self.value = value self.value = value
def is_value(self) -> bool:
return True
def as_value(self) -> ValueResult:
return self
class ReturnResult(EvalResult): class ReturnResult(EvalResult):
def __init__(self, value: Optional[Value]) -> None: def __init__(self, value: Optional[Value]) -> None:
super().__init__() super().__init__()
@ -57,8 +76,9 @@ class ContinueResult(EvalResult):
self.value = value self.value = value
class PanicResult(EvalResult): class PanicResult(EvalResult):
def __init__(self, message: str) -> None: def __init__(self, span: Span, message: str) -> None:
super().__init__() super().__init__()
self.span = span
self.message = message self.message = message
class SymbolTable: class SymbolTable:
@ -157,30 +177,43 @@ class Evaluator:
raise NotImplementedError(str(node)) raise NotImplementedError(str(node))
def eval_expr_error(self, expr: parsed.ExprError, span: Span) -> EvalResult: def eval_expr_error(self, expr: parsed.ExprError, span: Span) -> EvalResult:
return PanicResult(f"error: {expr.message}, at {span}") return PanicResult(span, f"error: {expr.message}, at {span}")
def eval_id(self, expr: parsed.Id, span: Span) -> EvalResult: def eval_id(self, expr: parsed.Id, span: Span) -> EvalResult:
raise NotImplementedError() value = self.table.value(expr.value)
if not value:
return PanicResult(span, f"undeclared identifier \"{expr.value}\"")
return ValueResult(value)
def eval_int(self, expr: parsed.Int, span: Span) -> EvalResult: def eval_int(self, expr: parsed.Int, span: Span) -> EvalResult:
return ValueResult(Int(expr.value)) return ValueResult(IntValue(expr.value))
def eval_char(self, expr: parsed.Char, span: Span) -> EvalResult: def eval_char(self, expr: parsed.Char, span: Span) -> EvalResult:
return ValueResult(Char(expr.value)) return ValueResult(CharValue(expr.value))
def eval_string(self, expr: parsed.String, span: Span) -> EvalResult: def eval_string(self, expr: parsed.String, span: Span) -> EvalResult:
return ValueResult(String(expr.value)) return ValueResult(StringValue(expr.value))
def eval_bool(self, expr: parsed.Bool, span: Span) -> EvalResult: def eval_bool(self, expr: parsed.Bool, span: Span) -> EvalResult:
return ValueResult(Bool(expr.value)) return ValueResult(BoolValue(expr.value))
def eval_unit(self, expr: parsed.Unit, span: Span) -> EvalResult: def eval_unit(self, expr: parsed.Unit, span: Span) -> EvalResult:
return ValueResult(Unit()) return ValueResult(UnitValue())
def eval_tuple(self, expr: parsed.Tuple, span: Span) -> EvalResult: def eval_tuple(self, expr: parsed.Tuple, span: Span) -> EvalResult:
raise NotImplementedError() values: List[Value] = []
for value in expr.values:
evaluated = self.eval_expr(value)
if not evaluated.is_value():
return evaluated
values.append(evaluated.as_value().value)
return ValueResult(TupleValue(values))
def eval_block(self, expr: parsed.Block, span: Span) -> EvalResult: def eval_block(self, expr: parsed.Block, span: Span) -> EvalResult:
for statement in expr.statements:
evaluated = self.eval_expr(statement)
if not evaluated.is_value():
return evaluated
raise NotImplementedError() raise NotImplementedError()
def eval_lambda(self, expr: parsed.Lambda, span: Span) -> EvalResult: def eval_lambda(self, expr: parsed.Lambda, span: Span) -> EvalResult:

View File

@ -40,7 +40,7 @@ class Parser:
while self.current_is(TokenType.KwOr): while self.current_is(TokenType.KwOr):
self.step() self.step()
right = self.parse_and() right = self.parse_and()
left = Node(Binary(BinaryType.Or, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.Or, left, right), left.span.to(right.span))
return left return left
@ -49,7 +49,7 @@ class Parser:
while self.current_is(TokenType.KwOr): while self.current_is(TokenType.KwOr):
self.step() self.step()
right = self.parse_equal() right = self.parse_equal()
left = Node(Binary(BinaryType.And, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.And, left, right), left.span.to(right.span))
return left return left
def parse_equal(self) -> Node[Expr]: def parse_equal(self) -> Node[Expr]:
@ -58,11 +58,11 @@ class Parser:
if self.current_is(TokenType.EqualEqual): if self.current_is(TokenType.EqualEqual):
self.step() self.step()
right = self.parse_compare() right = self.parse_compare()
left = Node(Binary(BinaryType.Equal, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.Equal, left, right), left.span.to(right.span))
elif self.current_is(TokenType.ExclamationEqual): elif self.current_is(TokenType.ExclamationEqual):
self.step() self.step()
right = self.parse_compare() right = self.parse_compare()
left = Node(Binary(BinaryType.Inequal, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.Inequal, left, right), left.span.to(right.span))
else: else:
break break
return left return left
@ -73,19 +73,19 @@ class Parser:
if self.current_is(TokenType.LT): if self.current_is(TokenType.LT):
self.step() self.step()
right = self.parse_add_subtract() right = self.parse_add_subtract()
left = Node(Binary(BinaryType.LT, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.LT, left, right), left.span.to(right.span))
elif self.current_is(TokenType.GT): elif self.current_is(TokenType.GT):
self.step() self.step()
right = self.parse_add_subtract() right = self.parse_add_subtract()
left = Node(Binary(BinaryType.LT, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.LT, left, right), left.span.to(right.span))
elif self.current_is(TokenType.LTEqual): elif self.current_is(TokenType.LTEqual):
self.step() self.step()
right = self.parse_add_subtract() right = self.parse_add_subtract()
left = Node(Binary(BinaryType.LTEqual, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.LTEqual, left, right), left.span.to(right.span))
elif self.current_is(TokenType.GTEqual): elif self.current_is(TokenType.GTEqual):
self.step() self.step()
right = self.parse_add_subtract() right = self.parse_add_subtract()
left = Node(Binary(BinaryType.GTEqual, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.GTEqual, left, right), left.span.to(right.span))
else: else:
break break
return left return left
@ -96,11 +96,11 @@ class Parser:
if self.current_is(TokenType.Plus): if self.current_is(TokenType.Plus):
self.step() self.step()
right = self.parse_multiply_divide_modulo() right = self.parse_multiply_divide_modulo()
left = Node(Binary(BinaryType.Add, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.Add, left, right), left.span.to(right.span))
elif self.current_is(TokenType.Minus): elif self.current_is(TokenType.Minus):
self.step() self.step()
right = self.parse_multiply_divide_modulo() right = self.parse_multiply_divide_modulo()
left = Node(Binary(BinaryType.Subtract, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.Subtract, left, right), left.span.to(right.span))
else: else:
break break
return left return left
@ -111,15 +111,15 @@ class Parser:
if self.current_is(TokenType.Asterisk): if self.current_is(TokenType.Asterisk):
self.step() self.step()
right = self.parse_negate() right = self.parse_negate()
left = Node(Binary(BinaryType.Multiply, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.Multiply, left, right), left.span.to(right.span))
elif self.current_is(TokenType.Slash): elif self.current_is(TokenType.Slash):
self.step() self.step()
right = self.parse_negate() right = self.parse_negate()
left = Node(Binary(BinaryType.Divide, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.Divide, left, right), left.span.to(right.span))
elif self.current_is(TokenType.Percent): elif self.current_is(TokenType.Percent):
self.step() self.step()
right = self.parse_negate() right = self.parse_negate()
left = Node(Binary(BinaryType.Modulo, left, right), left.span.to(right.span)) left = Node[Expr](Binary(BinaryType.Modulo, left, right), left.span.to(right.span))
else: else:
break break
return left return left