mirror of
https://github.com/lloeki/wasp.git
synced 2025-12-06 02:34:39 +01:00
eval + basic stdlib
This commit is contained in:
parent
5bb94d2dda
commit
b6560c6484
5 changed files with 115 additions and 17 deletions
16
repl.py
16
repl.py
|
|
@ -1,5 +1,4 @@
|
|||
import wasp
|
||||
import wasp.parser
|
||||
import readline
|
||||
|
||||
|
||||
|
|
@ -29,21 +28,20 @@ if __name__ == "__main__":
|
|||
# http://stackoverflow.com/questions/5637124
|
||||
#readline.set_completer(complete)
|
||||
|
||||
context = wasp.Context()
|
||||
|
||||
for line in Reader(">> ", banner="WASP %s" % wasp.VERSION):
|
||||
if line == "" or line is None:
|
||||
continue
|
||||
|
||||
try:
|
||||
ptree = wasp.parser.parse(line)
|
||||
except ValueError, e:
|
||||
ast = context['read'](line)
|
||||
except wasp.lib.ReadError, e:
|
||||
print "Parse error:", e.message
|
||||
continue
|
||||
|
||||
print " ^ %s" % ptree
|
||||
try:
|
||||
ast = ptree.ast()
|
||||
except ValueError, e:
|
||||
print "AST error:", e.message
|
||||
print context['eval'](ast, context)
|
||||
except wasp.SymbolError, e:
|
||||
print "Undefined symbol:", e.message
|
||||
continue
|
||||
print " ‡ %r" % ast
|
||||
#ast.eval()
|
||||
|
|
|
|||
6
test.py
6
test.py
|
|
@ -40,6 +40,12 @@ class TestParser(TestCase):
|
|||
self.assertRaises(ValueError, parser.parse("(42"))
|
||||
|
||||
|
||||
class TestAST(TestCase):
|
||||
def test_lists_in_list(self):
|
||||
ptree = parser.parse("(+ (* 4 5) (* 3 2))")
|
||||
repr(ptree.ast())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import unittest
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -1 +1,31 @@
|
|||
from __future__ import print_function
|
||||
|
||||
|
||||
import wasp.lib as lib
|
||||
|
||||
|
||||
VERSION = '0.0.1'
|
||||
|
||||
|
||||
class SymbolError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Context(object):
|
||||
symbols = {
|
||||
'+': lib.plus,
|
||||
'-': lib.minus,
|
||||
'*': lib.multiply,
|
||||
'/': lib.div,
|
||||
'read': lib.read,
|
||||
'eval': lib.eval,
|
||||
'print': lib.print,
|
||||
'apply': lib.apply,
|
||||
'quote': lib.quote,
|
||||
}
|
||||
|
||||
def __getitem__(self, symbol):
|
||||
try:
|
||||
return self.symbols[symbol]
|
||||
except KeyError:
|
||||
raise SymbolError(symbol)
|
||||
|
|
|
|||
16
wasp/ast.py
16
wasp/ast.py
|
|
@ -7,8 +7,8 @@ class List(Node):
|
|||
self.car = car
|
||||
self.cdr = cdr
|
||||
|
||||
def eval(self):
|
||||
pass
|
||||
def eval(self, context):
|
||||
return context['apply'](self.car, self.cdr, context)
|
||||
|
||||
def __repr__(self):
|
||||
return "<List %r %r>" % (self.car, self.cdr)
|
||||
|
|
@ -26,7 +26,7 @@ class Number(Atom):
|
|||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def eval(self):
|
||||
def eval(self, context):
|
||||
return self.value
|
||||
|
||||
def __repr__(self):
|
||||
|
|
@ -45,8 +45,8 @@ class Symbol(Atom):
|
|||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def eval(self):
|
||||
return self.value
|
||||
def eval(self, context):
|
||||
return context[self.value]
|
||||
|
||||
def __repr__(self):
|
||||
return "<Symbol %s>" % self.value
|
||||
|
|
@ -56,7 +56,7 @@ class String(Atom):
|
|||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def eval(self):
|
||||
def eval(self, context):
|
||||
return self.value
|
||||
|
||||
def __repr__(self):
|
||||
|
|
@ -67,8 +67,8 @@ class Quote(Node):
|
|||
def __init__(self, sexpr):
|
||||
self.sexpr = sexpr
|
||||
|
||||
def eval(self):
|
||||
return self.sexpr.eval()
|
||||
def eval(self, context):
|
||||
return context['quote'](self.sexpr)
|
||||
|
||||
def __repr__(self):
|
||||
return "<Quote %r>" % self.sexpr
|
||||
|
|
|
|||
64
wasp/lib.py
Normal file
64
wasp/lib.py
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import wasp.parser
|
||||
|
||||
|
||||
py_print = print
|
||||
py_eval = eval
|
||||
|
||||
|
||||
class ReadError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def plus(a, b):
|
||||
return a + b
|
||||
|
||||
|
||||
def minus(a, b):
|
||||
return a - b
|
||||
|
||||
|
||||
def multiply(a, b):
|
||||
return a * b
|
||||
|
||||
|
||||
def div(a, b):
|
||||
return a / b
|
||||
|
||||
|
||||
def read(string):
|
||||
try:
|
||||
ptree = wasp.parser.parse(string)
|
||||
except ValueError, e:
|
||||
raise ReadError(e.message)
|
||||
py_print(" ^ %s" % ptree)
|
||||
|
||||
try:
|
||||
ast = ptree.ast()
|
||||
except ValueError, e:
|
||||
raise ReadError(e.message)
|
||||
py_print(" ‡ %r" % ast)
|
||||
|
||||
return ast
|
||||
|
||||
|
||||
def eval(ast, context):
|
||||
# eval value unless list
|
||||
# eval args unless lazy
|
||||
# eval call
|
||||
return ast.eval(context)
|
||||
|
||||
|
||||
def apply(a, b, context):
|
||||
# move to eval
|
||||
args = [arg.eval(context) for arg in b]
|
||||
return a.eval(context)(*args)
|
||||
|
||||
|
||||
def quote(a):
|
||||
return a
|
||||
|
||||
|
||||
def print(string):
|
||||
py_print(string)
|
||||
Loading…
Add table
Add a link
Reference in a new issue