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__
.mypy_cache
session.vim

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from typing import Dict, List, Optional, cast
from position import Node, Span
from utils import Err, Ok, Result
@ -6,41 +7,59 @@ import parsed
class Value:
pass
class Unit(Value):
class UnitValue(Value):
def __init__(self) -> None:
super().__init__()
class Int(Value):
class IntValue(Value):
def __init__(self, value: int) -> None:
super().__init__()
self.value = value
class Char(Value):
class CharValue(Value):
def __init__(self, value: str) -> None:
super().__init__()
self.value = value
class String(Value):
class StringValue(Value):
def __init__(self, value: str) -> None:
super().__init__()
self.value = value
class Bool(Value):
class BoolValue(Value):
def __init__(self, value: bool) -> None:
super().__init__()
self.value = value
class TupleValue(Value):
def __init__(self, values: List[Value]) -> None:
super().__init__()
self.values = values
class Type:
pass
class EvalResult:
def __init__(self) -> None:
pass
def is_value(self) -> bool:
return False
def as_value(self) -> ValueResult:
raise Exception("guess it wasn't a value")
class ValueResult(EvalResult):
def __init__(self, value: Value) -> None:
super().__init__()
self.value = value
def is_value(self) -> bool:
return True
def as_value(self) -> ValueResult:
return self
class ReturnResult(EvalResult):
def __init__(self, value: Optional[Value]) -> None:
super().__init__()
@ -57,8 +76,9 @@ class ContinueResult(EvalResult):
self.value = value
class PanicResult(EvalResult):
def __init__(self, message: str) -> None:
def __init__(self, span: Span, message: str) -> None:
super().__init__()
self.span = span
self.message = message
class SymbolTable:
@ -157,30 +177,43 @@ class Evaluator:
raise NotImplementedError(str(node))
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:
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:
return ValueResult(Int(expr.value))
return ValueResult(IntValue(expr.value))
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:
return ValueResult(String(expr.value))
return ValueResult(StringValue(expr.value))
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:
return ValueResult(Unit())
return ValueResult(UnitValue())
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:
for statement in expr.statements:
evaluated = self.eval_expr(statement)
if not evaluated.is_value():
return evaluated
raise NotImplementedError()
def eval_lambda(self, expr: parsed.Lambda, span: Span) -> EvalResult:

View File

@ -40,7 +40,7 @@ class Parser:
while self.current_is(TokenType.KwOr):
self.step()
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
@ -49,7 +49,7 @@ class Parser:
while self.current_is(TokenType.KwOr):
self.step()
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
def parse_equal(self) -> Node[Expr]:
@ -58,11 +58,11 @@ class Parser:
if self.current_is(TokenType.EqualEqual):
self.step()
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):
self.step()
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:
break
return left
@ -73,19 +73,19 @@ class Parser:
if self.current_is(TokenType.LT):
self.step()
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):
self.step()
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):
self.step()
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):
self.step()
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:
break
return left
@ -96,11 +96,11 @@ class Parser:
if self.current_is(TokenType.Plus):
self.step()
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):
self.step()
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:
break
return left
@ -111,15 +111,15 @@ class Parser:
if self.current_is(TokenType.Asterisk):
self.step()
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):
self.step()
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):
self.step()
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:
break
return left