Commits

Anonymous committed d5be88d

Save old baseptr. Don't push/return void (size=0) values.

  • Participants
  • Parent commits 3c6d972

Comments (0)

Files changed (3)

File src/castile/backends/stackmac.py

+from castile.types import Void
+
 # Compile to some hypothetical stack-based machine.
 # Not yet in a good way.
 
 # x is at baseptr - 3
 # y is at baseptr - 2
 # z is at baseptr - 1
-# a is at baseptr + 0
-# b is at baseptr + 1
+# old baseptr is saved at baseptr + 0
+# a is at baseptr + 1
+# b is at baseptr + 2
 
 # callee is responsible for popping its locals and the given arguments
 # off the stack, and pushing its return value(S) in the space that the
             save_fun = self.fun_lit
             save_argcount = self.fun_argcount
             self.fun_lit = self.get_label('fun_lit')
-            f = self.fun_lit
-            self.local_pos = 0
-            self.out.write('%s:\n' % f)
+            self.local_pos = 1
+            self.out.write('%s:\n' % self.fun_lit)
+            # also saves the old baseptr right here
             self.out.write('set_baseptr\n')
             self.compile(ast.children[0])
             self.compile(ast.children[1])
             # TODO copy the result value(S) to the first arg position
             # (for now the opcode handles that)
+            # TODO must happen before every return!
+            self.out.write('exeunt_%s:\n' % self.fun_lit)
+            # base this on return type: void = 0, int = 1, union = 2, etc
+            returnsize = 1
+            if ast.aux.return_type == Void():
+                returnsize = 0
+            self.out.write('set_returnsize %d\n' % returnsize)
             self.out.write('clear_baseptr %d\n' % (0 - self.fun_argcount))
+            self.out.write('rts\n')
             self.out.write('%s:\n' % past_fun)
-            self.out.write('push %s\n' % f)
+            self.out.write('push %s\n' % self.fun_lit)
             self.fun_argcount = save_argcount
             self.fun_lit = save_fun
         elif ast.type == 'Args':
             self.out.write('%s:\n' % end_if)
         elif ast.type == 'Return':
             self.compile(ast.children[0])
-            self.out.write('rts\n')
+            self.out.write('jmp exeunt_%s:\n' % self.fun_lit)
         elif ast.type == 'Break':
             self.out.write('jmp %s\n' % self.loop_end)
         elif ast.type == 'Not':
             self.compile(ast.children[0])
             self.out.write('not\n')
         elif ast.type == 'None':
-            self.out.write('push 0\n')
+            pass  # sizeof(void) == 0
         elif ast.type == 'BoolLit':
             if ast.value:
                 self.out.write("push -1\n")

File src/castile/checker.py

             self.return_type = None
             if return_type is None:
                 return_type = Void()
-            return Function(arg_types, return_type)
+            t = Function(arg_types, return_type)
+            ast.aux = t
+            return t
         elif ast.type == 'Args':
             types = []
             for child in ast.children:

File src/castile/stackmac.py

     stack = []
     callstack = []
     baseptr = 0
+    returnsize = 0
     while ip < len(program):
         (op, arg) = program[ip]
         #print ip, op, arg, stack, callstack
             a = stack.pop()
             stack.append(a | b)
         elif op == 'set_baseptr':
-            baseptr = len(stack)
+            stack.append(baseptr)
+            baseptr = len(stack) - 1
+        elif op == 'set_returnsize':
+            returnsize = arg
         elif op == 'clear_baseptr':
-            # TODO assumes only one value returned on stack
-            a = stack.pop()
-            target = baseptr + arg
+            rs = []
+            x = 0
+            while x < returnsize:
+                rs.append(stack.pop())
+                x += 1
+            target = baseptr + arg + 1
+            baseptr = stack[baseptr]
             while len(stack) > target:
                 stack.pop()
-            stack.append(a)
+            x = 0
+            while x < returnsize:
+                stack.append(rs.pop())
+                x += 1
         elif op == 'get_global':
             stack.append(stack[arg])
         elif op == 'get_local':