Exemplo n.º 1
0
    def generateFunctionStackFrame(self, fn):
        if fn.isImported:
            return ""
        outside = []
        inside = []
        inside += [(labelname.getReturnAddressLabel(fn.name), 2)]
        outside += [(None, 2)]

        inside += [(labelname.getArgumentName(fn.name, i, False),
                    fn.args[i].getReserveSize()) for i in range(len(fn.args))]
        outside += [(labelname.getArgumentName(fn.name, i, True),
                     fn.args[i].getReserveSize()) for i in range(len(fn.args))]

        inside += [(labelname.getReturnName(fn.name, False),
                    fn.retType.getReserveSize())]
        outside += [(labelname.getReturnName(fn.name, True),
                     fn.retType.getReserveSize())]

        inside += [(labelname.getLocalName(fn.name, v),
                    fn.localVars[v].getReserveSize()) for v in fn.localVars]

        inside += [(labelname.getTempName(i,
                                          fn.name), self.backend.MAX_INT_SIZE)
                   for i in range(fn.maxTempVarIndex + 1)]
        try:
            return self.backend.reserveStackFrames(inside, outside)
        except ValueError as e:
            raise ValueError(f"{fn.name}: {str(e)}")
Exemplo n.º 2
0
 def generateFunctionCall(self, position, name, args, curFn):
     if name not in self.nameInfo.functions:
         raise SemanticError(position,
                             "Undefined function: {}".format(name))
     f = self.nameInfo.functions[name]
     if len(args) != len(f.args):
         raise SemanticError(position,
                             "Incorrect argument count for {}".format(name))
     result = ""
     isRecursive = self.callgraph.isRecursive(curFn, name)
     if not self.useStack:
         if isRecursive:
             sys.stderr.write("Warning: {}: recursion\n".format(
                 position))  # TODO warning function in a different module
         if isRecursive:
             result += self.backend.genPushLocals(curFn)
     for n, expr in enumerate(args):
         result += self.generateAssignment(
             Value.variable(Position.fromAny(expr),
                            labelname.getArgumentName(name, n, True),
                            f.args[n]), expr, curFn)
     result += self.backend.genCall(name)
     if not self.useStack:
         if isRecursive:
             result += self.backend.genPopLocals(curFn)
     return result
Exemplo n.º 3
0
 def resolveName(self, fn, localVars, globalVars, paramVars):
     if self._src.isNumber():
         return self
     else:
         if self._src in localVars:
             t = localVars[self._src]
             newType = self._type.removeUnknown(t)
             return Value(self._position, newType,
                          self._level + t.getIndirectionOffset(),
                          labelname.getLocalName(fn, self._src),
                          newType.isAlignedByDefault())
         elif self._src in paramVars:
             t, n = paramVars[self._src]
             newType = self._type.removeUnknown(t)
             return Value(self._position, newType,
                          self._level + t.getIndirectionOffset(),
                          labelname.getArgumentName(fn, n, False),
                          newType.isAlignedByDefault())
         elif self._src in globalVars:
             t, _ = globalVars[self._src]
             newType = self._type.removeUnknown(t)
             return Value(self._position, newType,
                          self._level + t.getIndirectionOffset(), self._src,
                          newType.isAlignedByDefault())
         else:
             raise SemanticError(self._position,
                                 "Undeclared variable {}".format(self._src))
Exemplo n.º 4
0
 def getExports(self):
     for name in self.nameInfo.functions:
         f = self.nameInfo.functions[name]
         if f.isExported:
             yield name
             yield labelname.getReturnName(name, True)
             for n in range(len(f.args)):
                 yield labelname.getArgumentName(name, n, True)
     for name in self.nameInfo.varExports:
         yield name
Exemplo n.º 5
0
 def generateFunctionReserve(self, fn):
     if fn.isImported:
         return ""
     result = self.backend.reserveBlock(
         labelname.getReserveBeginLabel(fn.name),
         [(labelname.getReturnAddressLabel(fn.name), 2)] +
         [([
             labelname.getArgumentName(fn.name, i, True),
             labelname.getArgumentName(fn.name, i, False),
         ], fn.args[i].getReserveSize())
          for i in range(len(fn.args))] + [(labelname.getLocalName(
              fn.name, v), fn.localVars[v].getReserveSize())
                                           for v in fn.localVars],
         self.uniqueId, f"{fn.name}_frame", self.createSubsections)
     result += self.backend.genLabel(labelname.getReserveEndLabel(fn.name))
     result += self.backend.reserve([
         labelname.getReturnName(fn.name, True),
         labelname.getReturnName(fn.name, False)
     ], fn.retType.getReserveSize(), "bss", self.uniqueId,
                                    self.createSubsections)
     return result