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