예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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");
        }
예제 #3
0
 public void AddClassSymbolTable(ClassSymbolTable table)
 {
     table.Parent = this;
     ClassSymbolTables.Add(table);
 }
예제 #4
0
        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>());
            }
        }