Example #1
0
    def FuncCallNode(self, node, scope, emit, tlevel):
        #there are two cases here.  one is calling a function
        #that is the result of an expression (e.g. member lookup),
        #the other is calling a named function, which pushes
        #the value itself.

        func = node.type
        if len(node[1]) != len(func.children[0]):
            typespace.error("Wrong number of function arguments", node)

        for i, a in enumerate(func[0]):
            a2 = node[1][i]
            nt = a2.type
            if type(a2) == FuncCallNode:
                nt = a2.type.type
                if type(nt) == IdentNode:
                    nt = TypeRefNode(nt.val)

            if not types_match(a.type, nt, typespace):
                typespace.error("Wrong type for argument %i." % (i + 1), node)

        #XXX REMEMBER TO RELINK THIS!
        self.opcode("LOAD_OPCODE_PTR", -2, "return address")
        jmpcode = len(self.codes) - 1

        for a in node[1]:
            self.opcode("PUSH")
            emit(a, scope)

        if type(node[0]) == IdentNode:
            self.opcode("LOAD_REG_SYMBOL_PTR", [node[0].val, 0])
        else:
            self.opcode("PUSH")
            emit(node[0], scope)
            self.opcode("LOAD_REG_PTR", 0)
            self.opcode("POP")

        if func.is_native:
            self.opcode("NATIVE_CALL", func.name)
        else:
            self.opcode("LONGJMP", 0, "call %s" % func.name)

        self.codes[jmpcode].arg = len(self.codes)

        #decrement locals offset.
        #we do this here since the
        #called function, not the caller,
        #pops the arguments.

        self.stacklevels[-1] -= len(func[0])
Example #2
0
 def FuncCallNode(self, node, scope, emit, tlevel):
   #there are two cases here.  one is calling a function
   #that is the result of an expression (e.g. member lookup),
   #the other is calling a named function, which pushes 
   #the value itself.
   
   func = node.type
   if len(node[1]) != len(func.children[0]):
     typespace.error("Wrong number of function arguments", node);
   
   for i, a in enumerate(func[0]):
     a2 = node[1][i]
     nt = a2.type
     if type(a2) == FuncCallNode:
       nt = a2.type.type
       if type(nt) == IdentNode:
         nt = TypeRefNode(nt.val)
         
     if not types_match(a.type, nt, typespace):
       typespace.error("Wrong type for argument %i."%(i+1), node);
   
   #XXX REMEMBER TO RELINK THIS!
   self.opcode("LOAD_OPCODE_PTR", -2, "return address")
   jmpcode = len(self.codes)-1
   
   for a in node[1]:
     self.opcode("PUSH")
     emit(a, scope)
   
   if type(node[0]) == IdentNode:
     self.opcode("LOAD_REG_SYMBOL_PTR", [node[0].val, 0]); 
   else:
     self.opcode("PUSH")
     emit(node[0], scope)
     self.opcode("LOAD_REG_PTR", 0);
     self.opcode("POP")
   
   if func.is_native:
     self.opcode("NATIVE_CALL", func.name)
   else:
     self.opcode("LONGJMP", 0, "call %s"%func.name);
   
   self.codes[jmpcode].arg = len(self.codes)
   
   #decrement locals offset.
   #we do this here since the 
   #called function, not the caller,
   #pops the arguments.
   
   self.stacklevels[-1] -= len(func[0])
Example #3
0
 def VarDeclNode(self, node, scope, emit, tlevel):
   if node.local:
     if len(self.stacklevels) == 0:
       typespace.error("Global variable has local flag", node)
   
     node.stack_off = self.stacklevels[-1]
     self.opcode("PUSH", comment="declare %s"%node.val)
   if node.val in scope and types_match(node.type, scope[node.val].type, typespace):
     node.stack_off = scope[node.val].stack_off
     if len(self.stacklevels) > 1:
       node.local = True
     else:
       node.local = scope[node.val].local
       
   scope[node.val] = node
   if type(node[0]) != ExprNode or len(node[0]) > 0:
     n = AssignNode(IdentNode(node.val), node[0], "=")
     n.type = node.type
     self.AssignNode(n, scope, emit, tlevel)
Example #4
0
    def VarDeclNode(self, node, scope, emit, tlevel):
        if node.local:
            if len(self.stacklevels) == 0:
                typespace.error("Global variable has local flag", node)

            node.stack_off = self.stacklevels[-1]
            self.opcode("PUSH", comment="declare %s" % node.val)
        if node.val in scope and types_match(node.type, scope[node.val].type,
                                             typespace):
            node.stack_off = scope[node.val].stack_off
            if len(self.stacklevels) > 1:
                node.local = True
            else:
                node.local = scope[node.val].local

        scope[node.val] = node
        if type(node[0]) != ExprNode or len(node[0]) > 0:
            n = AssignNode(IdentNode(node.val), node[0], "=")
            n.type = node.type
            self.AssignNode(n, scope, emit, tlevel)