Anonymous avatar Anonymous committed 2be42ed Draft

Stackmac backend now passes some tests.

Comments (0)

Files changed (5)

eg/simple.castile

 fun main() {
-  if 4 > 5 {
+  if 4 < 5 {
     return 2 * 3 + 4
   } else {
     return 0

src/castile/backends/stackmac.py

                 self.compile(child)
             self.out.write("""\
 ; call main
-push main
+; pick main_index
 call
 """)
         elif ast.type == 'Defn':
-            self.out.write('%s:\n' % ast.value)
+            self.out.write('; define %s_index <count>\n' % ast.value)
             self.compile(ast.children[0])
         elif ast.type in ('StructDefn', 'Forward'):
             pass
             self.current_loop_end = end
             self.out.write('%s:\n' % start)
             self.compile(ast.children[0])
-            self.out.write('beq %s\n' % end)
+            self.out.write('bzero %s\n' % end)
             self.compile(ast.children[1])
             self.out.write('jmp %s\n' % start)
             self.out.write('%s:\n' % end)
             else_part = self.get_label('else_part')
             end_if = self.get_label('end_if')
             self.compile(ast.children[0])
-            self.out.write('beq %s\n' % else_part)
+            self.out.write('bzero %s\n' % else_part)
             self.compile(ast.children[1])
             self.out.write('jmp %s\n' % end_if)
             self.out.write('%s:\n' % else_part)

src/castile/parser.py

     def body(self):
         # block for a function body -- automatically promotes the
         # last expression to a 'return' if it's not a statement
+        # (and inserts a 'return' if the block is empty
         self.expect('{')
         stmts = []
         last = None
             last = self.stmt()
             stmts.append(last)
             self.consume(';')
-        if last is not None and last.type not in self.STMT_TYPES:
+        if len(stmts) == 0:
+            stmts = [AST('Return', [AST('None')])]
+        elif last is not None and last.type not in self.STMT_TYPES:
             stmts[-1] = AST('Return', [stmts[-1]])
         self.expect('}')
         return AST('Block', stmts)

src/castile/stackmac.py

 from castile.builtins import BUILTINS
 
 
+def boo(b):
+    if b:
+        return -1
+    else:
+        return 0
+
+
 def run(program):
     ip = 0
+    iter = 0
     stack = []
     callstack = []
-    while ip <= len(program):
+    while ip < len(program):
         (op, arg) = program[ip]
-        print ip, op, arg
+        # print ip, op, arg, stack, callstack
         if op == 'push':
             stack.append(arg)
         elif op == 'jmp':
             ip = stack.pop() - 1
         elif op == 'rts':
             ip = callstack.pop()
+        elif op == 'mul':
+            b = stack.pop()
+            a = stack.pop()
+            stack.append(a * b)
+        elif op == 'add':
+            b = stack.pop()
+            a = stack.pop()
+            stack.append(a + b)
+        elif op == 'gt':
+            b = stack.pop()
+            a = stack.pop()
+            stack.append(boo(a > b))
+        elif op == 'lt':
+            b = stack.pop()
+            a = stack.pop()
+            stack.append(boo(a < b))
+        elif op == 'bzero':
+            a = stack.pop()
+            if a == 0:
+                ip = arg - 1
         else:
             raise NotImplementedError((op, arg))
         ip += 1
+        iter += 1
+        if iter > 10000:
+            raise ValueError("infinite loop?")
+    print repr(stack.pop())
 
 
 def main(args):
         if arg in labels:
             p.append((op, labels[arg]))
         else:
+            if arg is not None:
+                arg = int(arg)
             p.append((op, arg))
 
     run(p)
 #!/bin/sh
 
-cat >test_config <<EOF
+echo -n '' > test_config
+
+if [ "x$1" = "xeval" -o "x$1" = "xall" ]; then
+  cat >>test_config <<EOF
     -> Functionality "Run Castile Program" is implemented by shell command
     -> "bin/castile %(test-file)"
 
+EOF
+fi
+
+if [ "x$1" = "xjs" -o "x$1" = "xall" ]; then
+  cat >>test_config <<EOF
     -> Functionality "Run Castile Program" is implemented by shell command
     -> "bin/castile -c javascript %(test-file) > foo.js && node foo.js"
 
+EOF
+fi
+
+if [ "x$1" = "xruby" -o "x$1" = "xall" ]; then
+  cat >>test_config <<EOF
     -> Functionality "Run Castile Program" is implemented by shell command
     -> "bin/castile -c ruby %(test-file) > foo.rb && ruby foo.rb"
+
 EOF
+fi
 
-cat >test_config <<EOF
+if [ "x$1" = "xstackmac" -o "x$1" = "xall" ]; then
+  cat >>test_config <<EOF
     -> Functionality "Run Castile Program" is implemented by shell command
     -> "bin/castile -c stackmac %(test-file) > foo.stack && bin/stackmac foo.stack"
+
 EOF
+fi
 
 falderal -b test_config README.markdown
 rm -f test_config foo.*
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.