Add a repl
This commit is contained in:
parent
0383bc5b82
commit
224ec0bc98
5
genir.py
5
genir.py
|
@ -1,9 +1,8 @@
|
||||||
from emis_funky_funktions import *
|
from emis_funky_funktions import *
|
||||||
from typing import *
|
from typing import *
|
||||||
|
|
||||||
from silly_thing import *
|
|
||||||
from pattern import lex_and_parse_pattern
|
from pattern import lex_and_parse_pattern
|
||||||
from ir import Function, Application, Int, Variable, LetBinding, Unit
|
from ir import Expression, Function, Application, Int, Variable, LetBinding, ReplHole
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ def json_to_ir(j: JsonType) -> Expression:
|
||||||
case [first, *rest]:
|
case [first, *rest]:
|
||||||
return Application(json_to_ir(first), [json_to_ir(a) for a in rest])
|
return Application(json_to_ir(first), [json_to_ir(a) for a in rest])
|
||||||
case []:
|
case []:
|
||||||
return Unit()
|
return ReplHole()
|
||||||
raise Exception('Unreachable')
|
raise Exception('Unreachable')
|
||||||
else:
|
else:
|
||||||
return Int(j)
|
return Int(j)
|
10
ir.py
10
ir.py
|
@ -3,7 +3,7 @@ from emis_funky_funktions import *
|
||||||
from typing import Mapping, Sequence, Tuple, TypeAlias
|
from typing import Mapping, Sequence, Tuple, TypeAlias
|
||||||
|
|
||||||
|
|
||||||
Expression: TypeAlias = 'Function | Application | Int | Variable | Builtin | LetBinding | Unit'
|
Expression: TypeAlias = 'Function | Application | Int | Variable | Builtin | LetBinding | ReplHole'
|
||||||
Pattern: TypeAlias = 'NamePattern | IntPattern | SPattern | IgnorePattern'
|
Pattern: TypeAlias = 'NamePattern | IntPattern | SPattern | IgnorePattern'
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
@ -119,9 +119,11 @@ class SPattern:
|
||||||
return 'S ' + repr(self.pred)
|
return 'S ' + repr(self.pred)
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Unit:
|
class ReplHole:
|
||||||
|
bindings: Sequence[Tuple[str, Expression]] = tuple()
|
||||||
|
|
||||||
def subst(self, expression: Expression, variable: str) -> Expression:
|
def subst(self, expression: Expression, variable: str) -> Expression:
|
||||||
return self
|
return ReplHole((*self.bindings, (variable, expression)))
|
||||||
|
|
||||||
def is_value(self) -> bool:
|
def is_value(self) -> bool:
|
||||||
return True
|
return True
|
||||||
|
@ -280,7 +282,7 @@ class Application:
|
||||||
body = rest
|
body = rest
|
||||||
match body:
|
match body:
|
||||||
case []:
|
case []:
|
||||||
return Some(Unit())
|
return Some(ReplHole())
|
||||||
case [body_first, *body_rest]:
|
case [body_first, *body_rest]:
|
||||||
return Some(LetBinding(lhs, rhs, Application(body_first, body_rest)))
|
return Some(LetBinding(lhs, rhs, Application(body_first, body_rest)))
|
||||||
else:
|
else:
|
||||||
|
|
12
main.py
12
main.py
|
@ -1,8 +1,16 @@
|
||||||
from emis_funky_funktions import *
|
from emis_funky_funktions import *
|
||||||
|
|
||||||
from genir import json_to_ir
|
from genir import json_to_ir
|
||||||
from silly_thing import evaluate
|
from silly_thing import repl, repl_expr
|
||||||
|
|
||||||
import json, sys
|
import json, sys
|
||||||
|
|
||||||
print(evaluate(json_to_ir(json.loads(open(sys.argv[1]).read()))))
|
def main():
|
||||||
|
match sys.argv:
|
||||||
|
case [_, file]:
|
||||||
|
repl_expr(json_to_ir(json.loads(open(sys.argv[1]).read())))
|
||||||
|
case _:
|
||||||
|
repl()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -1,8 +1,10 @@
|
||||||
from emis_funky_funktions import *
|
from emis_funky_funktions import *
|
||||||
from typing import Collection, Sequence, TypeAlias
|
from typing import Collection, Sequence, TypeAlias
|
||||||
|
|
||||||
from ir import Expression
|
from ir import Expression, ReplHole, subst_all
|
||||||
|
from genir import json_to_ir
|
||||||
|
|
||||||
|
import json
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from operator import add
|
from operator import add
|
||||||
|
|
||||||
|
@ -35,6 +37,30 @@ def evaluate(expr: Expression) -> Expression:
|
||||||
raise AssertionError('Evaluate called on a value which cannot step:', expr)
|
raise AssertionError('Evaluate called on a value which cannot step:', expr)
|
||||||
raise Exception('Unreachable')
|
raise Exception('Unreachable')
|
||||||
|
|
||||||
|
def repl_expr(expr: Expression, bindings: Sequence[Tuple[str, Expression]] = tuple()):
|
||||||
|
expr_subst = subst_all(bindings, expr)
|
||||||
|
result = evaluate(expr_subst)
|
||||||
|
if isinstance(result, ReplHole):
|
||||||
|
print('Environment updated\n')
|
||||||
|
repl(result.bindings)
|
||||||
|
else:
|
||||||
|
print(result, end='\n\n')
|
||||||
|
repl(bindings)
|
||||||
|
|
||||||
|
def repl(bindings: Sequence[Tuple[str, Expression]] = tuple()):
|
||||||
|
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)
|
||||||
|
repl_expr(json_to_ir(ast), bindings)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import doctest
|
import doctest
|
||||||
doctest.testmod()
|
doctest.testmod()
|
Loading…
Reference in a new issue