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); } } }
public ContextClass(ContextFile fileContext) { FileContext = fileContext; PropertyContext = new PropertyContextCollection(); PropertyContext.ClassContext = this; ProcManagerContext = new ProcContextCollection(); ProcManagerContext.ClassContext = this; EmitContext = new ClassEmitContext(); MemberDictionary = new NameDictionary <SymbolDefMember>(); CurrentTable = new ClassSymbolTable("Class"); }
public void AddClassSymbolTable(ClassSymbolTable table) { table.Parent = this; ClassSymbolTables.Add(table); }
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>()); } }