Exemple #1
0
 def suite(self, node):
     node = L(node)
     node.code = []
     for child in node:
         if DEBUG:
             print(child)
         node.code += pushExpr(child)
     return node
Exemple #2
0
 def keyget_expr(self, node):
     node = L(node)
     node.type = "u"
     leftType = getTypeSignature(node[0])
     if leftType != "u":
         abort("Cannot use non 'u' %s as index to keyget" % leftType, node[0])
     node.code = pushExpr(node[0])
     node.code += ["KEYGET"]
     return node
Exemple #3
0
 def arealen_expr(self, node):
     node = L(node)
     node.type ="u"
     leftType = getTypeSignature(node[0])
     if leftType != "u":
         abort("Cannot use non 'u' %s as index to arealen" % leftType, node[0])
     node.code = pushExpr(node[0])
     node.code += ["AREALEN"]
     return node
Exemple #4
0
        def term(self, node):
            node = L(node)
            node.code = pushExpr(node[0])
            for i in range((len(node) - 1) // 2):
                nextop = node[1 + i * 2 + 1]
                leftType, rightType = ensurePrimitive(node[1].value, node[0], nextop)
                node.code += pushExpr(nextop)
                node.code += ['%s' % {'*':'MUL',  '/':'DIV',  '%':'MOD'}[node[1 + i * 2].value]]

            node.type = leftType
            return node
Exemple #5
0
        def arith_expr(self, node):
            node = L(node)
            node.code = pushExpr(node[0])
            for i in range((len(node) - 1) // 2):
                nextop = node[1 + i * 2 + 1]
                leftType, rightType = ensurePrimitive(node[1].value, node[0], nextop)
                node.code += pushExpr(nextop)
                node.code += ['%s' % {'+':'ADD',  '-':'SUB',  '~':'NOT'}[node[1 + i * 2].value]]

            node.type = leftType
            return node
Exemple #6
0
        def doreturn(self, node):
            node = L(node)
            node.code = []
            retType = getTypeSignature(node[0])
            if compareTypes(retType, func["out"]):
                abort("Return type doesn't match function signature\nExpected %s, got %s" % (func["out"], retType))
            node.type = retType
            node.code += pushExpr(node[0])

            node.code += coda()

            return node
Exemple #7
0
        def funcall(self, node):
            if DEBUG:
                print("()", node)
            node = L(node)
            otherfuncname = node[0].children[0].value
            otherfunc = funcs[otherfuncname]
            node.type = otherfunc["out"]
            node.code = []
            # CANNOT CHANGE STACK FRAME BOUNDARY; THEN pushExpr, because they depend on unmodified AREALEN!
            # Allocate parameter space

            if len(node) > 1:
                intypes = otherfunc["in"]
                for i, param in enumerate(node[1].children):
                    paramsig = getTypeSignature(param)
                    if compareTypes(intypes[i][0], paramsig):
                        abort("Wrong types on function call, expected %s, got %s" % (intypes[i], paramsig))

                    node.code += pushExpr(param)

                node.code += asm("alloc(%i,%i)" % (MEM_STACK, inTypLen(otherfunc["in"])))
                for i, param in enumerate(node[1].children[::-1]):
                    paramsig = getTypeSignature(param)
                    for index in range(types[paramsig]["len"]):
                        # Write args to end of current stack frame
                        node.code += asm("push(%i,sub(arealen(%i),%i))" % (MEM_STACK, MEM_STACK, index+i+1))
                        node.code += ["ROT2"]
                        node.code += ["WRITE"]

            # Push return address
            # TODO do this dynamically with IP
            # XXX this doesn't work anymore anyway

            #label = generator.label()
            #node.code += ["PUSH %s" % label]
            node.code += ["PUSH 4", "HEADER"]
            node.code += ["PUSH 8", "ADD"]
            #XXX must add a few for this to work
            # XXX PUSH FUNC___!"§"otherfuncname (collisions)
            #node.code += ["PUSH %s" % otherfuncname, "JUMP"]
            node.code += asm("keyget(%i)" % nametoint(otherfuncname))
            node.code += ["JUMP"]
            #node.code += [label+":"]
            # TODO now handle returned values!
            # Deallocate return values
            #XXX node.code += asm("dealloc(%i,%i)" % (MEM_STACK, typLen(otherfunc["out"])))
            # Deallocate parameters
            node.code += asm("dealloc(%i,%i)" % (MEM_STACK, inTypLen(otherfunc["in"])))
            return node
Exemple #8
0
        def getitem(self, node):
            node = L(node)
            leftType = getTypeSignature(node[0])
            rightType = getTypeSignature(node[1])
            if not leftType.startswith("*"):
                abort("Cannot index into non-pointer type %s of '%s'" % (leftType, node[0]), node)
            if rightType != "u":
                abort("Cannot index into pointer using non-u type %s of %s" % (rightType, node[1]), node)

            if DEBUG:
                print("[]", leftType, rightType)
            node.code = []
            node.code += ["PUSH 0"] + pushExpr(node[0]) + pushExpr(node[1]) + ["ADD", "READ"]
            node.type = leftType[1:]
            return node
Exemple #9
0
        def string(self, node):
            # TODO allocate on heap
            node = L(node)
            node.type = "vector"
            arr = node[0].value[1:-1]
            new = stringToWords(arr)
            if DEBUG:
                print("String", new)
            node.code = []
            node.code += asm("alloc(%i,%i)" % (MEM_HEAP, len(new)))
            for i, c in enumerate(new):
                node.code += asm("write(%i,sub(arealen(%i),%i),%i)" % (MEM_HEAP, MEM_HEAP, len(new)-i, c))

            node.code += asm("push(sub(arealen(%i),%i),%i)" % (MEM_HEAP, len(new), len(new)))
            return node
Exemple #10
0
 def while_stmt(self, node):
     node = L(node)
     start_label = generator.label()
     end_label = generator.label()
     node.code = [start_label + ':']
     if len(node) == 2:
         node.code += pushExpr(node[0])
         node.code += ['PUSHR %s' % end_label]
         node.code += ['JZR']
         node.code += node[1].code
     else:
         node.code += node[0].code
     node.code += ['PUSHR %s' % start_label]
     node.code += ['JUMPR']
     node.code += [end_label + ':']
     return node
Exemple #11
0
 def attr(self, node):
     if not hasType(node[0].value):
         abort("Name %s has no type" % node[0].value, node[0])
     typ = getTypeSignature(node[0])#XXX
     if not typ in types:
         abort("%s's type is not a struct" % node[0].value, node[0])
     subtype = getSubtype(typ, node[1].value)
     if subtype is None:
         abort("%s.'%s' is not a valid attribute" % (node[0].value, node[1].value), node[1])
     node = L(node)
     node.code = []
     for index in range(subtype["len"]):
         node.code += getAbsoluteOffset(node[0].value, subtype["offset"]+index)
     node.code += ["READ"]
     node.type = subtype["type"]
     return node
Exemple #12
0
 def if_stmt(self, node):
     node = L(node)
     node.code = []
     node.code += pushExpr(node[0])
     end_label = generator.label()
     if len(node) == 3:
         else_label = generator.label()
         node.code += ['PUSHR %s' % else_label]
     else:
         node.code += ['PUSHR %s' % end_label]
     node.code += ['JZR']
     node.code += node[1].code
     if len(node) == 3:
         node.code += ['PUSHR %s' % end_label]
         node.code += ['JUMPR']
         node.code += [else_label + ':']
         node += node[2].code
     node.code += [end_label + ':']
     return node
Exemple #13
0
        def dealloc_stmt(self, node):
            node = L(node)
            node.code = []
            leftType = getTypeSignature(node[0])

            if leftType != "u":
                abort("Cannot use non 'u' %s as index to dealloc" % leftType, node[0])

            if len(node) == 1:
                node.code += ["PUSH 0"]
                node.code += pushExpr(node[0])
            else:
                rightType = getTypeSignature(node[1])
                if rightType != "u":
                    abort("Cannot use non 'u' %s as size to dealloc" % rightType, node[1])
                node.code += pushExpr(node[0])
                node.code += pushExpr(node[1])
            node.code += ["DEALLOC"]
            return node
Exemple #14
0
        def read(self, node):
            node = L(node)
            node.code = []
            leftType = getTypeSignature(node[0])

            if leftType != "u":
                abort("Cannot use non 'u' %s as index" % leftType, node[0])

            if len(node) == 1:
                node.code += ["PUSH 0"]
                node.code += pushExpr(node[0])
            else:
                rightType = getTypeSignature(node[1])
                if rightType != "u":
                    abort("Cannot use non 'u' %s as index" % rightType, node[1])
                node.code += pushExpr(node[0])
                node.code += pushExpr(node[1])
            node.code += ["READ"]
            node.type = "u"
            return node
Exemple #15
0
        def write_stmt(self, node):
            node = L(node)
            node.code = []
            leftType = getTypeSignature(node[0])

            if leftType != "u":
                abort("Cannot use non 'u' %s as index" % leftType, node[0])

            if len(node) == 2:
                abort("disabled write", node)
                node.code += ["PUSH 0"]
                node.code += pushExpr(node[0])
            else:
                middleType = getTypeSignature(node[1])
                if middleType != "u":
                    abort("Cannot use non 'u' %s as index" % middleType, node[1])
                node.code += pushExpr(node[0])
                node.code += pushExpr(node[1])
            node.code += pushExpr(node[-1])
            node.code += ["WRITE"]
            return node
Exemple #16
0
        def tuple(self, node):
            node = L(node)
            node.code = []
            if DEBUG:
                print("TUPLE", node, node.code)
            if isinstance(node, list):
                data = node
                tup = list(getTypeSignature(n) for n in data)
                node.type = tup#flatten(tup)
            else:
                data = node[1]
                tup = list(getTypeSignature(n) for n in data)
                #TODO compare name with actual type
                nametyp = types[node[0].value]
                if nametyp != tup:
                    abort("Invalid type arguments: %s %s" % (nametyp, tup), node[0])
                node.type = nametyp

            for n in data:
                node.code += pushExpr(n)

            return node
Exemple #17
0
        def comparison(self, node):
            node = L(node)
            if DEBUG:
                print("cmp", node)
            leftType, rightType = ensurePrimitive("cmp", node[0], node[2])
            node.code = []

            cmp = node[1].value

            if cmp in ["!=", "=="]:
                node.code += pushExpr(node[0])
                node.code += pushExpr(node[2])
                node.code += ["SUB"]
                if cmp == "==":
                    node.code += ["NOT"]
            elif cmp == "<":
                node.code += pushExpr(node[0])
                node.code += pushExpr(node[2])
                node.code += ["CMP"]
                node.code += ["NOT"]
            elif cmp == ">=":
                node.code += pushExpr(node[2])
                node.code += pushExpr(node[0])
                node.code += ["CMP"]
            elif cmp == ">":
                node.code += pushExpr(node[0])
                node.code += pushExpr(node[2])
                node.code += ["CMP"]
                node.code += ["NOT"]
            elif cmp == "<=":
                node.code += pushExpr(node[2])
                node.code += pushExpr(node[0])
                node.code += ["CMP"]
            else:
                abort("Unknown comparison operator %s" % node[1].value, node[1])
            #print("COMPARISON", cmp, node.code)
            node.type = "u"
            return node
Exemple #18
0
        def assign(self, node):
            if DEBUG:
                print("=", node)
            rightType = getTypeSignature(node[1])
            if DEBUG:
                print("=", rightType)

            if hasType(node[0].value):
                leftType = getTypeSignature(node[0].value)
                if compareTypes(leftType, rightType):
                    abort("Assignment type mismatch %s = %s" % (leftType, rightType), node)
            else:
                #print("New var", node[0].value)
                if isinstance(rightType, list) and len(rightType) > 1:
                    raise NotImplemented("nope")
                elif len(rightType) == 0:
                    abort("Cannot assign from () to something", node[0])

                var[node[0].value] = {"type":rightType}
                #node.code += [["_RESERVE", node[0].value]]
            #print(types,var[node[0].value])

            node = L(node)
            node.code = []
            """
            node.code += getAbsoluteOffset(node[0].value)
            node.code += getAbsoluteOffset(node[1].value)
            node.code += rightType["len"]
            node.code += "MEMCOPY"
            """
            node.code += pushExpr(node[1])
            for index in range(types[rightType]["len"]-1, -1, -1):
                # composite assignment somewhere else!
                node.code += getAbsoluteOffset(node[0].value, index)
                node.code += ["ROT2"]
                node.code += ["WRITE"]

            return node
Exemple #19
0
        def funcbody(self, node):
            node = L(node)
            node.code = []
            # Allocate stack frame
            #print("RET", func["out"])

            # Calculate stack frame size # + return address + stack frame
            framesize = varLen() + 2#XXX retlen +

            # Allocate stack frame
            node.code += asm("alloc(%i,%i)" % (MEM_STACK, framesize))

            # Write current stack frame address to second last item of stack frame
            node.code += asm("write(%i,sub(arealen(%i),2),read(%i,0))" % (MEM_STACK, MEM_STACK, MEM_STACK))

            # Write return address from stack to end of stack frame
            node.code += asm("write(%i,sub(arealen(%i),1),rot2)" % (MEM_STACK, MEM_STACK))

            # Write stack frame address to 0:0
            node.code += asm("write(%i,0,sub(arealen(%i), %i))" % (MEM_STACK, MEM_STACK, framesize))

            # Put last index of area on stack
            #node.code += ["PUSH 0"]
            #node.code += ["PUSH 0", "arealen", "PUSH 1", "SUB"]
            # Save return address in frame
            #node.code += ["ROT2", "WRITE"]
            if DEBUG:
                print(funcname, node[0])

            node.code += node[0].code
            node.code += ecoda()

            code = "\n".join(node.code)

            #XXX check for jump at end of function!
            return code
Exemple #20
0
 def memorylen_expr(self, node):
     node = L(node)
     node.type = "u"
     node.code = ["MEMORYLEN"]
     return node
Exemple #21
0
 def doyield(self,node):
     node = L(node)
     node.code = []
     #node.code += pushExpr(node[0])
     node.code += ["YIELD"]
     return node
Exemple #22
0
 def expr(self, node):
     node = L(node)
     node.code = []
     node.type = getTypeSignature(node[0])
     node.code = pushExpr(node[0])
     return node
Exemple #23
0
 def funcname_expr(self, node):
     node = L(node)
     node.type = "u"
     node.code = ["PUSH %i" % nametoint(node[0].value)]
     return node
Exemple #24
0
 def area_stmt(self, node):
     node = L(node)
     node.code = ["AREA"]
     return node
Exemple #25
0
 def compound_stmt(self, node):
     node = L(node)
     node.code = pushExpr(node[0])
     return node
Exemple #26
0
 def run(self, node):
     node = L(node)
     #node.code = asm("push(99999999999,99999999999)")
     node.code = pushExpr(node[0])
     node.code += ["RUN"]
     return node
Exemple #27
0
 def listmaker(self, node):
     node = L(node)
     node.type = ["u"] * len(node)
     return node
Exemple #28
0
 def number(self, node):
     node = L(node)
     node.type = "u"
     #TODO make sure u is in range
     node.code = ["PUSH %s" % node[0].value]
     return node
Exemple #29
0
 def simple_stmt(self, node):
     node = L(node)
     node.code = pushExpr(node[0])
     return node