public void Visit(SubFuncCallNode n) { PrintDOTIDLabel(n); PrintDOTParentChild(n); foreach (var child in n.GetChildren()) { child.Accept(this); } }
public void Visit(SubFuncCallNode n) { var children = n.GetChildren(); foreach (var child in children) { child.SymTable = n.SymTable; child.Accept(this); } }
public void Visit(SubFuncCallNode n) { var children = n.GetChildren(); foreach (var child in children) { child.Accept(this); } var returnValSize = Utils.GetTypeFullSize(_globalSymbolTable, n.ExprType); var table = (FunctionSymbolTableEntry)n.CallerTable; n.TemporaryVariableName = table.MemoryLayout.AddTemporaryVariable(returnValSize); }
public void Visit(SubFuncCallNode n) { var children = n.GetChildren(); foreach (var child in children) { child.Accept(this); } var callerTable = (FunctionSymbolTableEntry)n.CallerTable; var funcTable = (FunctionSymbolTableEntry)n.SecondarySymTable; var funcReturnValSize = Utils.GetTypeFullSize(_globalSymbolTable, (funcTable.ReturnType.Lexeme, new List <int>())); var tag = Utils.GetTag(funcTable); var frameSize = funcTable.MemoryLayout.TotalSize; var oldFSPReg = PopRegister(); var localReturnValVar = n.TemporaryVariableName; var localReturnValOffset = callerTable.MemoryLayout.GetOffset(localReturnValVar); var r0 = Registers.R0; var r12 = Registers.R12; var r13 = Registers.R13; var r15 = Registers.R15; _writer.WriteComment("SUB FUNC CALL"); // Set the new FSP reg and set self addr _writer.WriteComment("- create frame"); _writer.WriteInstruction(Instructions.Add, oldFSPReg, r0, FSPReg); _writer.WriteInstruction(Instructions.Addi, FSPReg, FSPReg, $"{frameSize}"); //TODO(AFL) setSelfAddr var selfAddrOffset = -8; _writer.WriteInstruction(Instructions.Sw, $"{selfAddrOffset}({FSPReg})", r12); // Copy arguments _writer.WriteComment("- copy args"); var givenParamTempVarNames = ((FuncCallParamsNode)children.Last()).ParamTempVarNames; // Params given var funcParamNames = funcTable.Params.Select(x => x.Name).ToList(); // variables used in the function for (int i = 0; i < funcParamNames.Count; ++i) { var givenParamAddrReg = PopRegister(); var funcParamAddrReg = PopRegister(); var paramSizeReg = PopRegister(); var givenParamSize = callerTable.MemoryLayout.GetTypeSize(givenParamTempVarNames[i]); var givenParamOffset = callerTable.MemoryLayout.GetOffset(givenParamTempVarNames[i]); var funcParamOffset = funcTable.MemoryLayout.GetOffset(funcParamNames[i]); _writer.WriteInstruction(Instructions.Addi, paramSizeReg, paramSizeReg, $"{givenParamSize}"); _writer.WriteInstruction(Instructions.Add, givenParamAddrReg, givenParamAddrReg, oldFSPReg); _writer.WriteInstruction(Instructions.Addi, givenParamAddrReg, givenParamAddrReg, $"{givenParamOffset}"); _writer.WriteInstruction(Instructions.Add, funcParamAddrReg, funcParamAddrReg, FSPReg); _writer.WriteInstruction(Instructions.Addi, funcParamAddrReg, funcParamAddrReg, $"{funcParamOffset}"); WriteMultiByteCopy(givenParamAddrReg, funcParamAddrReg, paramSizeReg); PushRegister(paramSizeReg); PushRegister(funcParamAddrReg); PushRegister(givenParamAddrReg); } // JUMP! _writer.WriteComment("- jump to func"); _writer.WriteInstruction(Instructions.Jl, r15, tag); // Ok we're back, unset FSP _writer.WriteComment("- unset FSP"); _writer.WriteInstruction(Instructions.Subi, FSPReg, FSPReg, $"{frameSize}"); // set r12 to absolute address of result _writer.WriteComment("- set r12 (callchain ptr)"); _writer.WriteInstruction(Instructions.Sub, r12, r12, r12); _writer.WriteInstruction(Instructions.Add, r12, r0, FSPReg); _writer.WriteInstruction(Instructions.Addi, r12, r12, $"{localReturnValOffset}"); // Copy result from other frame to this frame var valSizeReg = PopRegister(); _writer.WriteComment("- copy result"); _writer.WriteInstruction(Instructions.Addi, valSizeReg, r0, $"{funcReturnValSize}"); WriteMultiByteCopy(r13, r12, valSizeReg); PushRegister(valSizeReg); PushRegister(oldFSPReg); }
public void Visit(SubFuncCallNode n) { var children = n.GetChildren(); var token = ((IdentifierNode)children[0]).Token; n.FuncName = token.Lexeme; List <FunctionSymbolTableEntry> candidateFuncsInScope; switch (n.SymTable) { case FunctionSymbolTableEntry f: { candidateFuncsInScope = new List <FunctionSymbolTableEntry>(); if (!string.IsNullOrEmpty(f.ScopeSpec)) { ClassSymbolTable s = _globalTable.GetClassSymbolTableByName(f.ScopeSpec); var funcsInClass = s.GetFunctions().Where(x => string.Equals(x.Name, n.FuncName)).ToList(); candidateFuncsInScope = candidateFuncsInScope.Concat(funcsInClass).ToList(); } var candidateFuncsInGlobalScope = _globalTable.FunctionSymbolTable.Entries .Cast <FunctionSymbolTableEntry>() .Where(x => string.Equals(x.Name, n.FuncName) && string.IsNullOrEmpty(x.ScopeSpec)).ToList(); // Same name, in class or free function //candidateFuncsInScope = s.GetFunctions().Where(x => string.Equals(x.Name, n.FuncName)).ToList(); candidateFuncsInScope = candidateFuncsInScope.Concat(candidateFuncsInGlobalScope).ToList(); } break; case ClassSymbolTable s: { // Same name, in class candidateFuncsInScope = s.GetFunctions().Where(x => string.Equals(x.Name, n.FuncName)).ToList(); } break; default: throw new InvalidOperationException("Unknown table entry type found"); } if (candidateFuncsInScope.Count == 0) { _errorStream.WriteLine($"Use of undefined function: \"{n.FuncName}\" ({token.StartLine}:{token.StartColumn})"); Console.WriteLine($"Error: Use of undefined function: \"{n.FuncName}\" ({token.StartLine}:{token.StartColumn})"); } // Visit FuncCallParamsNode to get parameter types used var funcParams = (FuncCallParamsNode)children[1]; funcParams.CallerTable = n.CallerTable; funcParams.Accept(this); var funcParamTypes = funcParams.ParamsTypes; FunctionSymbolTableEntry matchingFunc = null; foreach (var candidateFunc in candidateFuncsInScope) { if (candidateFunc.Params.Count != funcParamTypes.Count) { continue; } bool matches = true; for (int i = 0; i < candidateFunc.Params.Count; ++i) { (string type, List <int> dims)unpacked = funcParamTypes[i]; if (!string.Equals(candidateFunc.Params[i].Type.type, unpacked.type)) { matches = false; break; } if (candidateFunc.Params[i].Type.dims.Count == unpacked.dims.Count && candidateFunc.Params[i].Type.dims.All(x => x == 0)) { matches = true; break; } if (!candidateFunc.Params[i].Type.dims.SequenceEqual(unpacked.dims)) { matches = false; break; } } if (matches) { matchingFunc = candidateFunc; break; } } if (matchingFunc == null) { _errorStream.WriteLine($"Use of function: \"{n.FuncName}\" ({token.StartLine}:{token.StartColumn}) with invalid parameters (no matching overload was found)"); Console.WriteLine($"Error: Use of function: \"{n.FuncName}\" ({token.StartLine}:{token.StartColumn}) with invalid parameters (no matching overload was found)"); } else { n.CallerTable = n.SecondarySymTable; n.SecondarySymTable = matchingFunc; n.ScopeSpec = matchingFunc.ReturnType.Lexeme; n.ExprType = (matchingFunc.ReturnType.Lexeme, new List <int>()); } }