private void CalculateClassSize(ClassSymbolTable classTable) { var varsInScope = classTable.GetVariablesInScope(); foreach (var varInScope in varsInScope) { var type = varInScope.Value; var multiplier = 1; foreach (var dim in type.dims) { multiplier *= dim; } if (string.Equals(type.type, TypeConstants.IntType)) { classTable.MemoryLayout.AddEntry(type, varInScope.Key, TypeConstants.IntTypeSize, TypeConstants.IntTypeSize * multiplier); } else if (string.Equals(type.type, TypeConstants.FloatType)) { classTable.MemoryLayout.AddEntry(type, varInScope.Key, TypeConstants.FloatTypeSize, TypeConstants.FloatTypeSize * multiplier); } else { var varClassTable = _globalSymbolTable.GetClassSymbolTableByName(type.type); if (varClassTable.MemoryLayout.TotalSize == 0) { CalculateClassSize(varClassTable); } classTable.MemoryLayout.AddEntry(type, varInScope.Key, varClassTable.MemoryLayout.TotalSize, varClassTable.MemoryLayout.TotalSize * multiplier); } } }
private int GetSize(Token token) { int size; switch (token.TokenType) { case TokenType.Integer: size = TypeConstants.IntTypeSize; break; case TokenType.Float: size = TypeConstants.FloatTypeSize; break; case TokenType.Identifier: var table = _globalSymbolTable.GetClassSymbolTableByName(token.Lexeme); size = table.MemoryLayout.TotalSize; break; default: throw new InvalidOperationException("Unknown type."); } return(size); }
public void Visit(FuncCallNode n) { var children = n.GetChildren(); var first = children.First(); first.SymTable = n.SymTable; first.SecondarySymTable = n.SymTable; first.CallerTable = n.SymTable; first.Accept(this); var currentScopeSpec = first.ScopeSpec; foreach (var node in children.Skip(1)) { if (string.IsNullOrEmpty(currentScopeSpec)) { _errorStream.WriteLine($"ASSERT: Use of variable with no scopespec."); Console.WriteLine($"ASSERT: Use of variable with no scopespec."); break; } var classTable = _globalTable.GetClassSymbolTableByName(currentScopeSpec); if (classTable == null) { _errorStream.WriteLine($"ScopeSpec \"{currentScopeSpec}\" refers to a non existing class."); Console.WriteLine($"Error: ScopeSpec \"{currentScopeSpec}\" refers to a non existing class."); break; } node.SymTable = classTable; node.SecondarySymTable = n.SymTable; node.CallerTable = n.SymTable; node.Accept(this); currentScopeSpec = node.ScopeSpec; } }
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); }