add some eval
This commit is contained in:
parent
1f3d16aef1
commit
82a56e1d47
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
|
||||
__pycache__
|
||||
.mypy_cache
|
||||
session.vim
|
||||
|
||||
|
61
evaluator.py
61
evaluator.py
@ -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:
|
||||
|
26
parser.py
26
parser.py
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user