70 lines
1.7 KiB
Python
70 lines
1.7 KiB
Python
from emis_funky_funktions import *
|
|
from typing import Collection, Sequence, TypeAlias
|
|
|
|
from ir import Expression, ReplHole, subst_all
|
|
from genir import json_to_ir
|
|
from types_ import BUILTINS_CONTEXT
|
|
|
|
import json
|
|
from dataclasses import dataclass
|
|
from operator import add
|
|
|
|
def evaluate(expr: Expression) -> Expression:
|
|
"""
|
|
>>> funktion = Function((
|
|
... (SPattern(NamePattern('n')), (
|
|
... Application((
|
|
... Variable('+'),
|
|
... Variable('n'),
|
|
... Variable('n'),
|
|
... ))
|
|
... )),
|
|
... (NamePattern('0'), (
|
|
... Int(1312)
|
|
... )),
|
|
... ))
|
|
>>> evaluate(Application((funktion, Int(3))))
|
|
4
|
|
>>> evaluate(Application((funktion, Int(0))))
|
|
1312
|
|
"""
|
|
if expr.is_value():
|
|
return expr
|
|
else:
|
|
match expr.step():
|
|
case Some(next):
|
|
return evaluate(next)
|
|
case None:
|
|
raise AssertionError('Evaluate called on a value which cannot step:', expr)
|
|
raise Exception('Unreachable')
|
|
|
|
def repl_expr(expr: Expression, bindings: ReplHole = ReplHole(BUILTINS_CONTEXT)):
|
|
expr_subst = subst_all(bindings.val_bindings, expr)
|
|
result = evaluate(expr_subst)
|
|
if isinstance(result, ReplHole):
|
|
print('Environment updated\n')
|
|
print(result.typ_bindings)
|
|
repl(result)
|
|
else:
|
|
print(result, end='\n\n')
|
|
repl(bindings)
|
|
|
|
def repl(bindings: ReplHole = ReplHole(BUILTINS_CONTEXT)):
|
|
print('Enter a JSON expression:')
|
|
try:
|
|
expr = input('-> ')
|
|
except EOFError:
|
|
print('<exit>')
|
|
return
|
|
try:
|
|
ast = json.loads(expr)
|
|
except json.decoder.JSONDecodeError as e:
|
|
print(f'Bad json: ', e.args[0], end='\n\n')
|
|
return repl(bindings)
|
|
# TODO handle this
|
|
new_expr, new_ty, substs = unwrap_r(json_to_ir(ast, bindings.typ_bindings))
|
|
repl_expr(new_expr, bindings)
|
|
|
|
if __name__ == '__main__':
|
|
import doctest
|
|
doctest.testmod() |