vorgabe tests
This commit is contained in:
86
test/test_builtin.py
Normal file
86
test/test_builtin.py
Normal file
@ -0,0 +1,86 @@
|
||||
import py
|
||||
|
||||
from simpleparser import parse
|
||||
from objmodel import W_NormalObject
|
||||
from interpreter import Interpreter
|
||||
|
||||
def test_builtin_simple():
|
||||
builtincode = """
|
||||
x = 1
|
||||
object None:
|
||||
1
|
||||
def pass:
|
||||
None
|
||||
"""
|
||||
# construct the builtin module by running builtincode within the context of
|
||||
# a new empty module
|
||||
interpreter = Interpreter(builtincode)
|
||||
w_module = interpreter.make_module()
|
||||
# the parent of a normal module is the builtin module
|
||||
builtins = w_module.getparents()[0]
|
||||
assert builtins.getvalue('x').value == 1
|
||||
|
||||
ast = parse("""
|
||||
tx = x
|
||||
object a:
|
||||
pass
|
||||
ax = a x
|
||||
""")
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("ax").value == 1
|
||||
assert w_module.getvalue("tx").value == 1
|
||||
|
||||
def test_inttrait():
|
||||
builtincode = """
|
||||
object inttrait:
|
||||
x = 1
|
||||
def maybe_fortytwo:
|
||||
if self:
|
||||
42
|
||||
else:
|
||||
x
|
||||
"""
|
||||
interpreter = Interpreter(builtincode)
|
||||
w_module = interpreter.make_module()
|
||||
# the parent of a normal module is the builtin module
|
||||
builtins = w_module.getparents()[0]
|
||||
inttrait = builtins.getvalue("inttrait")
|
||||
|
||||
ast = parse("""
|
||||
x = 5 x # this returns 1, because it looks in the inttrait defined above
|
||||
m0 = 0 maybe_fortytwo
|
||||
m1 = x maybe_fortytwo
|
||||
inttrait x = 2
|
||||
m2 = 0 maybe_fortytwo
|
||||
tr = inttrait
|
||||
""")
|
||||
interpreter.eval(ast, w_module)
|
||||
x = w_module.getvalue("x")
|
||||
assert w_module.getvalue("tr") is inttrait
|
||||
# the inttrait is defined in the builtin module, so its __parent__ is that
|
||||
# module
|
||||
assert inttrait.getparents() == [builtins]
|
||||
assert x.value == 1
|
||||
assert x.getparents() == [inttrait]
|
||||
assert w_module.getvalue("m0").value == 1
|
||||
assert w_module.getvalue("m1").value == 42
|
||||
assert w_module.getvalue("m2").value == 2
|
||||
|
||||
|
||||
def test_builtin_default():
|
||||
ast = parse("""
|
||||
def sumupto(x):
|
||||
r = 0
|
||||
while x:
|
||||
r = r add(x)
|
||||
x = x add(-1)
|
||||
r
|
||||
x = sumupto(100)
|
||||
""")
|
||||
# the constructor is called without arguments, so the default builtins are
|
||||
# used
|
||||
interpreter = Interpreter()
|
||||
# test that the default inttrait defines a method ``add``
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == 5050
|
206
test/test_bytecode.py
Normal file
206
test/test_bytecode.py
Normal file
@ -0,0 +1,206 @@
|
||||
import py
|
||||
|
||||
from simpleparser import parse
|
||||
from objmodel import W_NormalObject
|
||||
from interpreter import Interpreter
|
||||
|
||||
empty_builtins = """
|
||||
1
|
||||
"""
|
||||
|
||||
|
||||
def test_assignment():
|
||||
ast = parse("""
|
||||
x = 1
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == 1
|
||||
|
||||
|
||||
def test_negative_intliteral():
|
||||
ast = parse("""
|
||||
x = -1
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == -1
|
||||
|
||||
|
||||
def test_huge_intliteral():
|
||||
ast = parse("""
|
||||
x = 10000
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == 10000
|
||||
|
||||
|
||||
def test_huge_negative_intliteral():
|
||||
ast = parse("""
|
||||
x = -10000
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == -10000
|
||||
|
||||
|
||||
def test_primitive():
|
||||
ast = parse("""
|
||||
x = 1 $int_add(2)
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == 3
|
||||
|
||||
|
||||
def test_pop():
|
||||
ast = parse("""
|
||||
x = 1 # the result of this will be popped from the stack
|
||||
x = 2
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == 2
|
||||
|
||||
|
||||
def test_condition():
|
||||
ast = parse("""
|
||||
x = 1
|
||||
if x:
|
||||
x = 2
|
||||
else:
|
||||
x = 3
|
||||
if 0:
|
||||
y = 3
|
||||
else:
|
||||
y = 4
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == 2
|
||||
assert w_module.getvalue("y").value == 4
|
||||
|
||||
|
||||
def test_objectdefinition_simple():
|
||||
ast = parse("""
|
||||
object x:
|
||||
a = 1
|
||||
b = 2
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").getvalue("a").value == 1
|
||||
assert w_module.getvalue("x").getvalue("b").value == 2
|
||||
|
||||
|
||||
def test_objectdefinition_parents():
|
||||
ast = parse("""
|
||||
object x:
|
||||
a = 1
|
||||
b = 2
|
||||
object y(parent=x):
|
||||
b = 3
|
||||
a = y a
|
||||
b = y b
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("a").value == 1
|
||||
assert w_module.getvalue("b").value == 3
|
||||
|
||||
|
||||
def test_objectdefinition___parent__():
|
||||
ast = parse("""
|
||||
object x:
|
||||
a = 1
|
||||
b = 2
|
||||
object y(__parent__=x):
|
||||
b = 3
|
||||
a = y a
|
||||
b = y b
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("a").value == 1
|
||||
assert w_module.getvalue("b").value == 3
|
||||
|
||||
|
||||
def test_functiondefinition_noargs():
|
||||
ast = parse("""
|
||||
def f:
|
||||
if x:
|
||||
1
|
||||
else:
|
||||
2
|
||||
x = 0
|
||||
x = f
|
||||
y = f
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == 2
|
||||
assert w_module.getvalue("y").value == 1
|
||||
|
||||
|
||||
def test_functiondefinition_args():
|
||||
ast = parse("""
|
||||
def f(x):
|
||||
if x:
|
||||
1
|
||||
else:
|
||||
2
|
||||
x = f(0)
|
||||
y = f(1)
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == 2
|
||||
assert w_module.getvalue("y").value == 1
|
||||
|
||||
|
||||
def test_whileloop():
|
||||
ast = parse("""
|
||||
def f(x):
|
||||
sum = 0
|
||||
while x:
|
||||
sum = sum $int_add(x)
|
||||
x = x $int_add(-1)
|
||||
sum
|
||||
x = f(100)
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").value == 5050
|
||||
|
||||
|
||||
def test_method_cascade():
|
||||
ast = parse("""
|
||||
object x:
|
||||
a = 1
|
||||
object y:
|
||||
a = 2
|
||||
x next = y
|
||||
y next = x
|
||||
|
||||
a = x next next next next next next a
|
||||
b = x next next next next next next next a
|
||||
""")
|
||||
interpreter = Interpreter(empty_builtins)
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("a").value == 1
|
||||
assert w_module.getvalue("b").value == 2
|
123
test/test_interpreter.py
Normal file
123
test/test_interpreter.py
Normal file
@ -0,0 +1,123 @@
|
||||
import py
|
||||
|
||||
from simpleparser import parse
|
||||
from objmodel import W_NormalObject
|
||||
from interpreter import Interpreter
|
||||
|
||||
|
||||
#
|
||||
# The Interpreter class needs a method 'eval(ast, w_context)' that is
|
||||
# doing "AST visiting", as follows:
|
||||
#
|
||||
# def eval(self, ast, w_context):
|
||||
# method = getattr(self, "eval_" + ast.__class__.__name__)
|
||||
# return method(ast, w_context)
|
||||
#
|
||||
# This calls a method called "eval_Xxx" on self for every class
|
||||
# called Xxx of the simpleast.py module.
|
||||
#
|
||||
def test_simplxe():
|
||||
ast = parse("""
|
||||
10
|
||||
11
|
||||
12
|
||||
""")
|
||||
w_module = W_NormalObject()
|
||||
interpreter = Interpreter()
|
||||
interpreter.eval(ast, w_module)
|
||||
|
||||
|
||||
def test_simple():
|
||||
ast = parse("""
|
||||
k = 10
|
||||
j = 11
|
||||
i = 12
|
||||
""")
|
||||
w_module = W_NormalObject()
|
||||
interpreter = Interpreter()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("i").value == 12
|
||||
assert w_module.getvalue("j").value == 11
|
||||
assert w_module.getvalue("k").value == 10
|
||||
|
||||
|
||||
def test_if():
|
||||
ast = parse("""
|
||||
k = 10
|
||||
if k:
|
||||
j = 11
|
||||
else:
|
||||
i = 12
|
||||
""")
|
||||
w_module = W_NormalObject()
|
||||
interpreter = Interpreter()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("i") is None
|
||||
assert w_module.getvalue("j").value == 11
|
||||
assert w_module.getvalue("k").value == 10
|
||||
|
||||
|
||||
def test_def():
|
||||
ast = parse("""
|
||||
def f(x, y):
|
||||
if x:
|
||||
x
|
||||
else:
|
||||
y
|
||||
i = f(6, 3)
|
||||
j = f(0, 9)
|
||||
""")
|
||||
w_module = W_NormalObject()
|
||||
interpreter = Interpreter()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("i").value == 6
|
||||
assert w_module.getvalue("j").value == 9
|
||||
|
||||
|
||||
def test_object():
|
||||
ast = parse("""
|
||||
object x:
|
||||
i = 4
|
||||
j = i
|
||||
object z:
|
||||
i = 5
|
||||
""")
|
||||
w_module = W_NormalObject()
|
||||
interpreter = Interpreter()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("x").getvalue("i").value == 4
|
||||
assert w_module.getvalue("x").getvalue("j").value == 4
|
||||
assert w_module.getvalue("x").getvalue("z").getvalue("i").value == 5
|
||||
|
||||
|
||||
def test_obscure_recursion():
|
||||
ast = parse("""
|
||||
object a:
|
||||
def f(a):
|
||||
if a:
|
||||
x = 5
|
||||
a f(0)
|
||||
else:
|
||||
x = 7
|
||||
x
|
||||
i = a f(a)
|
||||
""")
|
||||
w_module = W_NormalObject()
|
||||
interpreter = Interpreter()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("i").value == 5
|
||||
|
||||
|
||||
def test_assign():
|
||||
ast = parse("""
|
||||
object a:
|
||||
b = 5
|
||||
def set(n):
|
||||
self b = n
|
||||
a set(7)
|
||||
i = a b
|
||||
""")
|
||||
w_module = W_NormalObject()
|
||||
interpreter = Interpreter()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("i").value == 7
|
82
test/test_method.py
Normal file
82
test/test_method.py
Normal file
@ -0,0 +1,82 @@
|
||||
import py
|
||||
|
||||
from simpleparser import parse
|
||||
from objmodel import W_NormalObject
|
||||
from interpreter import Interpreter
|
||||
|
||||
def test_assign():
|
||||
ast = parse("""
|
||||
object a:
|
||||
b = 5
|
||||
def set(n):
|
||||
self b = n
|
||||
a set(7)
|
||||
i = a b
|
||||
""")
|
||||
w_module = W_NormalObject()
|
||||
interpreter = Interpreter()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("i").value == 7
|
||||
|
||||
|
||||
def test_method_simple():
|
||||
ast = parse("""
|
||||
object a:
|
||||
x = 11
|
||||
def f:
|
||||
self x
|
||||
object b:
|
||||
__parent__ = a
|
||||
x = 22
|
||||
af = a f # a is the receiver, therefore self is a in the method
|
||||
bf = b f # b is the receiver, therefore self is b in the method
|
||||
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("af").value == 11
|
||||
assert w_module.getvalue("bf").value == 22
|
||||
|
||||
|
||||
def test_method_complex():
|
||||
ast = parse("""
|
||||
k = 10
|
||||
object a:
|
||||
x = 11
|
||||
y = 22
|
||||
def f(a, b):
|
||||
if a:
|
||||
if b:
|
||||
a
|
||||
else:
|
||||
k
|
||||
else:
|
||||
if b:
|
||||
self x
|
||||
else:
|
||||
self y
|
||||
object b:
|
||||
__parent__ = a
|
||||
y = 55
|
||||
af11 = a f(1, 1)
|
||||
af10 = a f(1, 0)
|
||||
af01 = a f(0, 1)
|
||||
af00 = a f(0, 0)
|
||||
k = 908
|
||||
bf11 = b f(1, 1)
|
||||
bf10 = b f(1, 0)
|
||||
bf01 = b f(0, 1)
|
||||
bf00 = b f(0, 0)
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("af11").value == 1
|
||||
assert w_module.getvalue("af10").value == 10
|
||||
assert w_module.getvalue("af01").value == 11
|
||||
assert w_module.getvalue("af00").value == 22
|
||||
assert w_module.getvalue("bf11").value == 1
|
||||
assert w_module.getvalue("bf10").value == 908
|
||||
assert w_module.getvalue("bf01").value == 11
|
||||
assert w_module.getvalue("bf00").value == 55
|
38
test/test_objmodel.py
Normal file
38
test/test_objmodel.py
Normal file
@ -0,0 +1,38 @@
|
||||
from objmodel import W_Integer, W_NormalObject
|
||||
|
||||
|
||||
def test_normalobject():
|
||||
w1 = W_NormalObject()
|
||||
# 'setvalue' and 'getvalue' write and read the attributes by name.
|
||||
w1.setvalue('abc', W_Integer(6))
|
||||
w2 = w1.getvalue('abc')
|
||||
assert isinstance(w2, W_Integer)
|
||||
assert w2.value == 6
|
||||
# a missing attribute...
|
||||
assert w1.getvalue('bcd') is None
|
||||
|
||||
|
||||
def test_integer():
|
||||
w1 = W_Integer(5)
|
||||
assert w1.value == 5
|
||||
# W_Integer objects cannot have custom attributes,
|
||||
# so getvalue() returns None.
|
||||
assert w1.getvalue('abc') is None
|
||||
|
||||
|
||||
def test_istrue():
|
||||
assert W_Integer(5).istrue() is True
|
||||
assert W_Integer(0).istrue() is False
|
||||
assert W_Integer(-1).istrue() is True
|
||||
# for now, only W_Integer(0) is false; all the other objects are true.
|
||||
assert W_NormalObject().istrue() is True
|
||||
|
||||
|
||||
def test_clone():
|
||||
w1 = W_NormalObject()
|
||||
w1.setvalue('abc', W_Integer(6))
|
||||
w2 = w1.clone()
|
||||
assert w2.getvalue('abc').value == 6
|
||||
w2.setvalue('abc', W_Integer(99))
|
||||
assert w2.getvalue('abc').value == 99
|
||||
assert w1.getvalue('abc').value == 6 # still the old value
|
205
test/test_parent.py
Normal file
205
test/test_parent.py
Normal file
@ -0,0 +1,205 @@
|
||||
import py
|
||||
|
||||
from simpleparser import parse
|
||||
from objmodel import W_NormalObject
|
||||
from interpreter import Interpreter
|
||||
|
||||
|
||||
def test_implicit_parent():
|
||||
ast = parse("""
|
||||
k = 10
|
||||
object a:
|
||||
z = k
|
||||
az = a z
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
# make_module creates a new empty W_NormalObject for now
|
||||
# this will change later
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("a").getvalue('__parent__') is w_module
|
||||
assert w_module.getvalue("a").getparents() == [w_module]
|
||||
assert w_module.getvalue("az").value == 10
|
||||
|
||||
|
||||
def test_implicit_parent_method():
|
||||
ast = parse("""
|
||||
k = 10
|
||||
def f(x):
|
||||
if x:
|
||||
k
|
||||
else:
|
||||
1
|
||||
f1 = f(1)
|
||||
f0 = f(0)
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("f1").value == 10
|
||||
assert w_module.getvalue("f0").value == 1
|
||||
|
||||
|
||||
def test_shadow_parent_attribute():
|
||||
ast = parse("""
|
||||
k = 10
|
||||
def f(x):
|
||||
if x:
|
||||
k = 41
|
||||
k
|
||||
f1 = f(1)
|
||||
f0 = f(0)
|
||||
|
||||
object a:
|
||||
k = 11
|
||||
|
||||
ak = a k
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("f1").value == 41
|
||||
assert w_module.getvalue("f0").value == 10
|
||||
assert w_module.getvalue("ak").value == 11
|
||||
assert w_module.getvalue("k").value == 10
|
||||
|
||||
|
||||
def test_capture():
|
||||
ast = parse("""
|
||||
k = 10
|
||||
object a:
|
||||
j = k
|
||||
k = 11
|
||||
aj = a j
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("aj").value == 10
|
||||
|
||||
|
||||
def test_override__parent__():
|
||||
ast = parse("""
|
||||
k = 10
|
||||
object a:
|
||||
x = 1
|
||||
y = 2
|
||||
z = k
|
||||
object b:
|
||||
__parent__ = a
|
||||
y = 5
|
||||
z = y
|
||||
|
||||
ax = a x
|
||||
ay = a y
|
||||
az = a z
|
||||
bx = b x
|
||||
by = b y
|
||||
bz = b z
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
a = w_module.getvalue("a")
|
||||
assert a.getvalue('__parent__') is w_module
|
||||
assert w_module.getvalue("b").getvalue('__parent__') is a
|
||||
assert w_module.getvalue("b").getparents() == [a]
|
||||
assert w_module.getvalue("ax").value == 1
|
||||
assert w_module.getvalue("ay").value == 2
|
||||
assert w_module.getvalue("az").value == 10
|
||||
assert w_module.getvalue("bx").value == 1
|
||||
assert w_module.getvalue("by").value == 5
|
||||
assert w_module.getvalue("bz").value == 5
|
||||
|
||||
|
||||
def test_parent_syntax():
|
||||
ast = parse("""
|
||||
object a:
|
||||
x = 11
|
||||
object b(parent=a):
|
||||
x = 22
|
||||
af = a x
|
||||
bf = b x
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
a = w_module.getvalue("a")
|
||||
b = w_module.getvalue("b")
|
||||
assert a.getvalue('__parent__') is w_module
|
||||
assert b.getvalue('__parent__') is w_module
|
||||
assert b.getvalue('parent') is a
|
||||
assert a.getparents() == [w_module]
|
||||
assert b.getparents() == [a, w_module]
|
||||
assert w_module.getvalue("af").value == 11
|
||||
assert w_module.getvalue("bf").value == 22
|
||||
|
||||
|
||||
def test_parent_syntax_multiple():
|
||||
ast = parse("""
|
||||
a = 1
|
||||
b = 2
|
||||
c = 3
|
||||
d = 4
|
||||
object x:
|
||||
b = 5
|
||||
c = 6
|
||||
d = 7
|
||||
object y:
|
||||
c = 8
|
||||
d = 9
|
||||
object z(p1=y, p2=x):
|
||||
d = 10
|
||||
za = z a
|
||||
zb = z b
|
||||
zc = z c
|
||||
zd = z d
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
x = w_module.getvalue("x")
|
||||
y = w_module.getvalue("y")
|
||||
z = w_module.getvalue("z")
|
||||
assert x.getvalue('__parent__') is w_module
|
||||
assert y.getvalue('__parent__') is w_module
|
||||
assert z.getvalue('__parent__') is w_module
|
||||
assert z.getvalue('p1') is y
|
||||
assert z.getvalue('p2') is x
|
||||
assert x.getparents() == [w_module]
|
||||
assert y.getparents() == [w_module]
|
||||
assert z.getparents() == [y, x, w_module]
|
||||
assert w_module.getvalue("za").value == 1
|
||||
assert w_module.getvalue("zb").value == 5
|
||||
assert w_module.getvalue("zc").value == 8
|
||||
assert w_module.getvalue("zd").value == 10
|
||||
|
||||
|
||||
def test_wrong_hierarchy_error():
|
||||
ast = parse("""
|
||||
object base:
|
||||
x = 1
|
||||
object sub(p1=base):
|
||||
x = 2
|
||||
def mayhem:
|
||||
object bad(p1=base, p2=sub):
|
||||
x = 3
|
||||
bad x
|
||||
result = mayhem
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
py.test.raises(TypeError, interpreter.eval, ast, w_module)
|
||||
|
||||
|
||||
def test_duplicate_base_error():
|
||||
ast = parse("""
|
||||
object base:
|
||||
x = 1
|
||||
object sub(p1=base, p2=base):
|
||||
x = 2
|
||||
y = sub x
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
py.test.raises(TypeError, interpreter.eval, ast, w_module)
|
42
test/test_primitive.py
Normal file
42
test/test_primitive.py
Normal file
@ -0,0 +1,42 @@
|
||||
import py
|
||||
|
||||
from simpleparser import parse
|
||||
from objmodel import W_NormalObject
|
||||
from interpreter import Interpreter
|
||||
|
||||
|
||||
def test_primitive():
|
||||
ast = parse("""
|
||||
k = 10 $int_add(31)
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("k").value == 41
|
||||
|
||||
|
||||
def test_primitive_error():
|
||||
ast = parse("""
|
||||
k = 10 $int_add(31, 12)
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
with py.test.raises(TypeError):
|
||||
interpreter.eval(ast, w_module)
|
||||
|
||||
|
||||
def test_loop():
|
||||
ast = parse("""
|
||||
def f(x):
|
||||
r = 0
|
||||
while x:
|
||||
r = r $int_add(x)
|
||||
x = x $int_add(-1)
|
||||
r
|
||||
y = f(100)
|
||||
""")
|
||||
interpreter = Interpreter()
|
||||
w_module = interpreter.make_module()
|
||||
interpreter.eval(ast, w_module)
|
||||
assert w_module.getvalue("y").value == 5050
|
||||
|
100
test/test_simplelexer.py
Normal file
100
test/test_simplelexer.py
Normal file
@ -0,0 +1,100 @@
|
||||
from simplelexer import lex
|
||||
|
||||
# Every insturction ends with an newline
|
||||
def test_single_quoted_string():
|
||||
for s in ["""'abc'""",
|
||||
"""'ab"c'""",
|
||||
"""'ab\\'c'""",
|
||||
]:
|
||||
tokens = lex(s)
|
||||
token, newline, eof = tokens
|
||||
assert token.name == 'String'
|
||||
assert newline.name == 'Newline'
|
||||
assert eof.name == 'EOF'
|
||||
|
||||
def test_number():
|
||||
for s in ["0",
|
||||
"+1",
|
||||
"-1",
|
||||
"-1123123",
|
||||
]:
|
||||
tokens = lex(s)
|
||||
token, newline, eof = tokens
|
||||
assert tokens[0].name == 'Number'
|
||||
assert token.name == 'Number'
|
||||
assert newline.name == 'Newline'
|
||||
assert eof.name == 'EOF'
|
||||
|
||||
def test_name():
|
||||
for s in ["abc",
|
||||
"_",
|
||||
"a_0",
|
||||
"_0",
|
||||
]:
|
||||
tokens = lex(s)
|
||||
token, newline, eof = tokens
|
||||
assert tokens[0].name == 'Name'
|
||||
assert token.name == 'Name'
|
||||
assert newline.name == 'Newline'
|
||||
assert eof.name == 'EOF'
|
||||
|
||||
def test_primitvename():
|
||||
for s in ["$abc",
|
||||
"$_",
|
||||
"$a_0",
|
||||
"$_0",
|
||||
]:
|
||||
tokens = lex(s)
|
||||
token, newline, eof = tokens
|
||||
assert tokens[0].name == 'PrimitiveName'
|
||||
assert token.name == 'PrimitiveName'
|
||||
assert newline.name == 'Newline'
|
||||
assert eof.name == 'EOF'
|
||||
|
||||
def test_long():
|
||||
for s, numtoken in [
|
||||
("if x:\n print x", 10),
|
||||
("if x:#foo\n x abc = 7", 12),
|
||||
("1 a \\\n 2", 5)
|
||||
]:
|
||||
tokens = lex(s)
|
||||
assert len(tokens) == numtoken
|
||||
|
||||
def test_indentation():
|
||||
s = """a
|
||||
b
|
||||
c
|
||||
d
|
||||
|
||||
#some comment
|
||||
e
|
||||
f
|
||||
"""
|
||||
tokens = lex(s)
|
||||
assert [t.name for t in tokens] == ["Name", "Newline", "Name", "Newline",
|
||||
"Indent", "Name", "Newline", "Indent",
|
||||
"Name", "Newline", "Dedent", "Name",
|
||||
"Newline", "Indent", "Name", "Newline",
|
||||
"Dedent", "Dedent", "EOF"]
|
||||
|
||||
# This is only one line! The \ is used for line continuation
|
||||
def test_linecont():
|
||||
s = "a a \\\n b"
|
||||
tokens = lex(s)
|
||||
assert [t.name for t in tokens] == ["Name", "Name", "Name", "Newline",
|
||||
"EOF"]
|
||||
|
||||
# newline token between brackets are ignored ...
|
||||
def test_parenthesis():
|
||||
s = "(a = \n b)"
|
||||
tokens = lex(s)
|
||||
assert [t.name for t in tokens] == ["OpenBracket", "Name", "Assign", "Name",
|
||||
"CloseBracket", "Newline", "EOF"]
|
||||
|
||||
# ... unless you insert a comment
|
||||
def test_comment():
|
||||
s = "(a = # foo this is a comment \n b)"
|
||||
tokens = lex(s)
|
||||
assert [t.name for t in tokens] == ["OpenBracket", "Name", "Assign", "Name",
|
||||
"CloseBracket", "Newline", "EOF"]
|
||||
|
149
test/test_simpleparser.py
Normal file
149
test/test_simpleparser.py
Normal file
@ -0,0 +1,149 @@
|
||||
import py
|
||||
|
||||
from simpleparser import ParseError, parse
|
||||
from simplelexer import lex
|
||||
from simpleast import *
|
||||
|
||||
def raisesparserror(source):
|
||||
with py.test.raises(ParseError) as excinfo:
|
||||
parse(source)
|
||||
print(excinfo.value.nice_error_message())
|
||||
|
||||
|
||||
def test_expression():
|
||||
ast = parse("a b c")
|
||||
ast1 = MethodCall(MethodCall(MethodCall(ImplicitSelf(), "a"), "b"), "c")
|
||||
assert ast == Program([ExprStatement(ast1)])
|
||||
ast = parse("a f(1, a b c, 3,)")
|
||||
ast2 = Program([ExprStatement(MethodCall(MethodCall(ImplicitSelf(), "a"), "f", [
|
||||
IntLiteral(1), ast1, IntLiteral(3)]))])
|
||||
assert ast == ast2
|
||||
|
||||
|
||||
def test_expression2():
|
||||
ast = parse("$a $b $c")
|
||||
ast1 = PrimitiveMethodCall(PrimitiveMethodCall(
|
||||
PrimitiveMethodCall(ImplicitSelf(), "$a"), "$b"), "$c")
|
||||
assert ast == Program([ExprStatement(ast1)])
|
||||
ast = parse("$a $f(1, $a $b $c, 3,)")
|
||||
assert ast == Program([ExprStatement(PrimitiveMethodCall(
|
||||
PrimitiveMethodCall(ImplicitSelf(), "$a"), "$f", [
|
||||
IntLiteral(1), ast1, IntLiteral(3)]))])
|
||||
|
||||
|
||||
def test_simplestatement():
|
||||
ast = parse("a\n")
|
||||
ast1 = Program([ExprStatement(MethodCall(ImplicitSelf(), "a"))])
|
||||
assert ast == ast1
|
||||
ast = parse("a = 4 b\n")
|
||||
ast1 = Program([Assignment(ImplicitSelf(), "a", MethodCall(IntLiteral(4), "b"))])
|
||||
assert ast == ast1
|
||||
ast = raisesparserror("a(1) = 4 b\n")
|
||||
ast = raisesparserror("1 = 4 b\n")
|
||||
|
||||
def test_error():
|
||||
ast = raisesparserror("a add 2\n")
|
||||
|
||||
|
||||
|
||||
def test_if():
|
||||
ast = parse("""if a and(b):
|
||||
a b
|
||||
""")
|
||||
ast1 = Program([IfStatement(MethodCall(MethodCall(ImplicitSelf(), "a"), "and",
|
||||
[MethodCall(ImplicitSelf(), "b")]),
|
||||
Program([ExprStatement(
|
||||
MethodCall(MethodCall(ImplicitSelf(), "a"),
|
||||
"b"))]))])
|
||||
assert ast1 == ast
|
||||
|
||||
ast = parse("""if a and(b):
|
||||
a b
|
||||
else:
|
||||
b
|
||||
""")
|
||||
ast1 = Program([IfStatement(MethodCall(MethodCall(ImplicitSelf(), "a"), "and",
|
||||
[MethodCall(ImplicitSelf(), "b")]),
|
||||
Program([ExprStatement(
|
||||
MethodCall(MethodCall(ImplicitSelf(), "a"),
|
||||
"b"))]),
|
||||
Program([ExprStatement(
|
||||
MethodCall(ImplicitSelf(), "b"))]))])
|
||||
assert ast1 == ast
|
||||
|
||||
def test_while():
|
||||
ast = parse("""
|
||||
while i:
|
||||
i = i sub(1)
|
||||
""")
|
||||
ast1 = Program([WhileStatement(MethodCall(ImplicitSelf(), "i"),
|
||||
Program([Assignment(ImplicitSelf(), "i",
|
||||
MethodCall(MethodCall(ImplicitSelf(), "i"),
|
||||
"sub",
|
||||
[IntLiteral(1)]))]))])
|
||||
assert ast1 == ast
|
||||
|
||||
def test_object():
|
||||
ast = parse("""
|
||||
object a:
|
||||
i = 1
|
||||
if i:
|
||||
j = 2
|
||||
""")
|
||||
ast1 = Program([ObjectDefinition("a", Program([
|
||||
Assignment(ImplicitSelf(), "i", IntLiteral(1)),
|
||||
IfStatement(MethodCall(ImplicitSelf(), "i"), Program([
|
||||
Assignment(ImplicitSelf(), "j", IntLiteral(2)),
|
||||
]))
|
||||
]))])
|
||||
assert ast1 == ast
|
||||
|
||||
ast = parse("""
|
||||
object a(parent=1):
|
||||
i = 1
|
||||
if i:
|
||||
j = 2
|
||||
""")
|
||||
ast1 = Program([ObjectDefinition("a", Program([
|
||||
Assignment(ImplicitSelf(), "i", IntLiteral(1)),
|
||||
IfStatement(MethodCall(ImplicitSelf(), "i"), Program([
|
||||
Assignment(ImplicitSelf(), "j", IntLiteral(2)),
|
||||
]))
|
||||
]),
|
||||
["parent"],
|
||||
[IntLiteral(1)])])
|
||||
assert ast1 == ast
|
||||
|
||||
|
||||
def test_def():
|
||||
ast = parse("""
|
||||
def f(x, y, z):
|
||||
i = 1
|
||||
if i:
|
||||
j = 2
|
||||
""")
|
||||
ast1 = Program([FunctionDefinition("f", ["x", "y", "z"], Program([
|
||||
Assignment(ImplicitSelf(), "i", IntLiteral(1)),
|
||||
IfStatement(MethodCall(ImplicitSelf(), "i"), Program([
|
||||
Assignment(ImplicitSelf(), "j", IntLiteral(2)),
|
||||
]))
|
||||
]))])
|
||||
assert ast1 == ast
|
||||
|
||||
|
||||
def test_object2():
|
||||
ast = parse("""
|
||||
object None:
|
||||
1
|
||||
""")
|
||||
ast = parse("""
|
||||
def pass:
|
||||
None
|
||||
""")
|
||||
ast = parse("""
|
||||
object None:
|
||||
1
|
||||
|
||||
def pass:
|
||||
None
|
||||
""")
|
Reference in New Issue
Block a user