added tests
This commit is contained in:
parent
73188b5200
commit
6da93ed87f
1 changed files with 74 additions and 14 deletions
88
chapter7.py
88
chapter7.py
|
|
@ -715,8 +715,8 @@ class LLVMCodeGenerator(object):
|
|||
# curvar = load var
|
||||
# nextvariable = curvar + step
|
||||
# store nextvar -> var
|
||||
# br endcond, loop, endloop
|
||||
# outloop:
|
||||
# br endcond, loop, afterloop
|
||||
# afterloop:
|
||||
|
||||
# Create an alloca for the induction var. Save and restore location of
|
||||
# our builder because _create_entry_block_alloca may modify it (llvmlite
|
||||
|
|
@ -776,6 +776,42 @@ class LLVMCodeGenerator(object):
|
|||
# The 'for' expression always returns 0
|
||||
return self.builder.constant(ir.DoubleType(), 0.0)
|
||||
|
||||
def _codegen_VarExprAST(self, node):
|
||||
old_bindings = []
|
||||
|
||||
for name, init in node.vars:
|
||||
# Emit the initializer before adding the variable to scope. This
|
||||
# prefents the initializer from referencing the variable itself.
|
||||
if init is not None:
|
||||
init_val = self._codegen(init)
|
||||
else:
|
||||
init_val = self.builder.constant(ir.DoubleType(), 0.0)
|
||||
|
||||
# Create an alloca for the induction var and store the init value to
|
||||
# it. Save and restore location of our builder because
|
||||
# _create_entry_block_alloca may modify it (llvmlite issue #44).
|
||||
saved_block = self.builder.block
|
||||
var_addr = self._create_entry_block_alloca(name)
|
||||
self.builder.position_at_end(saved_block)
|
||||
self.builder.store(init_val, var_addr)
|
||||
|
||||
# We're going to shadow this name in the symbol table now; remember
|
||||
# what to restore.
|
||||
old_bindings.append(self.func_symtab.get(name))
|
||||
self.func_symtab[name] = var_addr
|
||||
|
||||
# Now all the vars are in scope. Codegen the body.
|
||||
body_val = self._codegen(node.body)
|
||||
|
||||
# Restore the old bindings.
|
||||
for i, (name, _) in enumerate(node.vars):
|
||||
if old_bindings[i] is not None:
|
||||
self.func_symtab[name] = old_bindings[i]
|
||||
else:
|
||||
del self.func_symtab[name]
|
||||
|
||||
return body_val
|
||||
|
||||
def _codegen_CallExprAST(self, node):
|
||||
callee_func = self.module.globals.get(node.callee, None)
|
||||
if callee_func is None or not isinstance(callee_func, ir.Function):
|
||||
|
|
@ -978,21 +1014,45 @@ class TestParser(unittest.TestCase):
|
|||
|
||||
|
||||
class TestEvaluator(unittest.TestCase):
|
||||
def test_custom_binop(self):
|
||||
def test_var_expr(self):
|
||||
e = KaleidoscopeEvaluator()
|
||||
e.evaluate('def binary %(a b) a - b')
|
||||
self.assertEqual(e.evaluate('10 % 5'), 5)
|
||||
self.assertEqual(e.evaluate('100 % 5.5'), 94.5)
|
||||
e.evaluate('''
|
||||
def foo(x y z)
|
||||
var s1 = x + y, s2 = z + y in
|
||||
s1 * s2
|
||||
''')
|
||||
self.assertEqual(e.evaluate('foo(1, 2, 3)'), 15)
|
||||
|
||||
e = KaleidoscopeEvaluator()
|
||||
e.evaluate('def binary : 1 (x y) y')
|
||||
e.evaluate('''
|
||||
def foo(step)
|
||||
var accum in
|
||||
(for i = 0, i < 10, step in
|
||||
accum = accum + i) : accum
|
||||
''')
|
||||
# Note that Kaleidoscope's 'for' loop executes the last iteration even
|
||||
# when the condition is no longer fulfilled after the step is done.
|
||||
# 0 + 2 + 4 + 6 + 8 + 10
|
||||
self.assertEqual(e.evaluate('foo(2)'), 30)
|
||||
|
||||
def test_nested_var_exprs(self):
|
||||
e = KaleidoscopeEvaluator()
|
||||
e.evaluate('''
|
||||
def foo(x y z)
|
||||
var s1 = x + y, s2 = z + y in
|
||||
var s3 = s1 * s2 in
|
||||
s3 * 100
|
||||
''')
|
||||
self.assertEqual(e.evaluate('foo(1, 2, 3)'), 1500)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
#p = Parser()
|
||||
#print(p.parse_toplevel('def binary% 77(a b) a + b').dump())
|
||||
#print(p.parse_toplevel('def fra(x t) x % t').dump())
|
||||
kalei = KaleidoscopeEvaluator()
|
||||
#kalei.evaluate('def foo(t) for i = 65, i < t, 1 in putchard(i)')
|
||||
kalei.evaluate('def binary: 1 (x y) y')
|
||||
kalei.evaluate('def test(x) putchard(x) : x = 65 : putchard(x) : x = 66 : putchard(x)')
|
||||
kalei.evaluate('test(77)')
|
||||
#kalei.evaluate('foo(80)', llvmdump=True)
|
||||
#print(kalei.evaluate('5 % 10', optimize=False, llvmdump=True))
|
||||
kalei.evaluate('''
|
||||
def foo(x y z)
|
||||
var s1 = x + y, s2 = z + y in
|
||||
s1 * s2
|
||||
''')
|
||||
print(kalei.evaluate('foo(1, 2, 3)'))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue