public void Visit(SubVarCallNode n) { var children = n.GetChildren(); foreach (var child in children) { child.Accept(this); } }
public void Visit(SubVarCallNode n) { PrintDOTIDLabel(n); PrintDOTParentChild(n); foreach (var child in n.GetChildren()) { child.Accept(this); } }
public void Visit(SubVarCallNode n) { var children = n.GetChildren(); foreach (var child in children) { child.Accept(this); } var callChainPointerReg = Registers.R12; var varName = n.VarName; int varOffset; (string type, List <int> dims)varType; int typeSize; FunctionSymbolTableEntry tableForIndexing; switch (n.SymTable) { case FunctionSymbolTableEntry f: { if (f.MemoryLayout.Contains(varName)) { varOffset = f.MemoryLayout.GetOffset(varName); varType = f.MemoryLayout.GetVarType(varName); typeSize = f.MemoryLayout.GetTypeSize(varName); } else { var classTable = _globalSymbolTable.GetClassSymbolTableByName(f.ScopeSpec); varOffset = classTable.MemoryLayout.GetOffset(varName); varType = classTable.MemoryLayout.GetVarType(varName); typeSize = classTable.MemoryLayout.GetTypeSize(varName); _writer.WriteInstruction(Instructions.Lw, callChainPointerReg, $"-8({FSPReg})"); } } tableForIndexing = f; break; case ClassSymbolTable c: varOffset = c.MemoryLayout.GetOffset(varName); varType = c.MemoryLayout.GetVarType(varName); typeSize = c.MemoryLayout.GetTypeSize(varName); tableForIndexing = (FunctionSymbolTableEntry)n.SecondarySymTable; break; default: throw new InvalidOperationException("Unknown table type"); } _writer.WriteComment("SUB VAR CALL"); // Get variable address _writer.WriteComment("Compute absolute address of variable, (we don't have lea...)"); var absoluteAddressReg = PopRegister(); _writer.WriteInstruction(Instructions.Add, absoluteAddressReg, absoluteAddressReg, callChainPointerReg); // grab callchain address _writer.WriteInstruction(Instructions.Addi, absoluteAddressReg, absoluteAddressReg, $"{varOffset}"); // Add offset, we have absolute address now // Get variable address with indexing, if used // x y z // integer a[3][3][3] // a[1][0][2] -> a + 1*sizeof(integer)*3*3 + 0*sizeof(integer)*3 + 2*sizeof(integer) // ^ ^ // typeSize runningMultiplier var indicesNode = (IndicesNode)children[1]; var indices = indicesNode.TemporaryVariableNames; if (indices.Count > 0) { _writer.WriteComment("Computing address from array index"); // Set type size register var typeSizeReg = PopRegister(); _writer.WriteInstruction(Instructions.Addi, typeSizeReg, typeSizeReg, $"{typeSize}"); var runningMultiplierReg = PopRegister(); // 3*3 var indexValueReg = PopRegister(); var indexingElementOffsetReg = PopRegister(); // the 1*sizeof(integer)*3*3 value will be stored here and added to absoluteAddressReg for (int i = 0; i < indices.Count; ++i) { _writer.WriteComment($"Computing for {i}th index"); // Set runningMultiplierReg if (i == 0) // InitialValue { _writer.WriteInstruction(Instructions.Addi, runningMultiplierReg, runningMultiplierReg, "1"); } else { _writer.WriteInstruction(Instructions.Muli, runningMultiplierReg, runningMultiplierReg, $"{varType.dims[i]}"); } // Clear indexingElementOffsetReg _writer.WriteInstruction(Instructions.Sub, indexingElementOffsetReg, indexingElementOffsetReg, indexingElementOffsetReg); _writer.WriteInstruction(Instructions.Addi, indexingElementOffsetReg, indexingElementOffsetReg, "1"); // set initial multiplier value // Load index value var indexOffset = tableForIndexing.MemoryLayout.GetOffset(indices.FastReverse().ToList()[i]); _writer.WriteInstruction(Instructions.Lw, indexValueReg, $"{indexOffset}({FSPReg})"); _writer.WriteInstruction(Instructions.Mul, indexingElementOffsetReg, indexValueReg, typeSizeReg); // 1*sizeof(integer) _writer.WriteInstruction(Instructions.Mul, indexingElementOffsetReg, indexingElementOffsetReg, runningMultiplierReg); // 1*sizeof(integer)*3*3 // Add indexingElementOffsetReg to absoluteAddressReg _writer.WriteInstruction(Instructions.Add, absoluteAddressReg, absoluteAddressReg, indexingElementOffsetReg); } PushRegister(indexingElementOffsetReg); PushRegister(indexValueReg); PushRegister(runningMultiplierReg); PushRegister(typeSizeReg); } //NOTE: R12 has address now // Store absolute address into temp var associated to this SubVarCall //_writer.WriteComment("Storing final address"); //var tempVarOffset = table.MemoryLayout.GetOffset(n.TemporaryVariableName); //_writer.WriteInstruction(Instructions.Sw, $"{tempVarOffset}({FSPReg})", absoluteAddressReg); _writer.WriteInstruction(Instructions.Add, callChainPointerReg, Registers.R0, absoluteAddressReg); PushRegister(absoluteAddressReg); }
public void Visit(SubVarCallNode n) { var children = n.GetChildren(); children[0].SymTable = n.SymTable; children[0].Accept(this); children[1].SymTable = n.SecondarySymTable; children[1].Accept(this); var varNameToken = ((IdentifierNode)children[0]).Token; n.VarName = varNameToken.Lexeme; n.NumDims = ((IndicesNode)children[1]).NumDims; Dictionary <string, (string, List <int>)> varsInScope; switch (n.SymTable) { case FunctionSymbolTableEntry f: { var classTable = _globalTable.GetClassSymbolTableByName(f.ScopeSpec); Dictionary <string, (string, List <int>)> classVars = classTable?.GetVariablesInScope() ?? new Dictionary <string, (string, List <int>)>(); var funcVars = f.GetVariablesInScope(); varsInScope = new Dictionary <string, (string, List <int>)>(); foreach (var v in classVars) { varsInScope.Add(v.Key, v.Value); } foreach (var v in funcVars) { if (!varsInScope.ContainsKey(v.Key)) { varsInScope.Add(v.Key, v.Value); } else { _errorStream.WriteLine($"Variable '{v.Key}' used in {f.ToStringSignature()} is already defined in the class"); Console.WriteLine($"Error: Variable '{v.Key}' used in {f.ToStringSignature()} is already defined in the class"); } } } break; case ClassSymbolTable s: { varsInScope = s.GetVariablesInScope(); } break; default: throw new InvalidOperationException("Unknown table entry type found"); } (string Type, List <int> Dims)typeDims; if (!varsInScope.TryGetValue(n.VarName, out typeDims)) { _errorStream.WriteLine($"Use of undeclared variable \"{n.VarName}\" ({varNameToken.StartLine}:{varNameToken.StartColumn})"); Console.WriteLine($"Error: Use of undeclared variable \"{n.VarName}\" ({varNameToken.StartLine}:{varNameToken.StartColumn})"); } else { n.ScopeSpec = typeDims.Type; n.ExprType = typeDims; if (n.NumDims > typeDims.Dims.Count) { _errorStream.WriteLine($"Data member \"{n.VarName}\" used with more dims than defined! max: {typeDims.Dims.Count}, had: {n.NumDims}"); Console.WriteLine($"Error: Data member \"{n.VarName}\" used with more dims than defined! max: {typeDims.Dims.Count}, had: {n.NumDims}"); } // Say var defined as float a[5][5][5] // and used a[2], the type of the expression is now float[5][5] n.ExprType = (typeDims.Type, typeDims.Dims.Skip(n.NumDims).ToList()); } }