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)}")
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
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))
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
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