Exemple #1
0
        public override void PreVisit(FuncDef funcDef)
        {
            // Transfer scopes.
            this.FunctionScopeLink = this.GlobalScope.Get(funcDef.Entry.ID, Classification.Function);

            this.ClassInstanceScope = new SymbolTable();
            if (funcDef.ScopeResolution != null)
            {
                this.ClassInstanceScope = this.GlobalScope.Get(funcDef.ScopeResolution.ID, Classification.Class).Link;
            }

            var newFunctionScope = new SymbolTable();

            // Add the return values.
            newFunctionScope.Add(new TableEntry("retaddr", Classification.SubCalculationStackSpace, 4), (0, 0));
            newFunctionScope.Add(new TableEntry("retval", Classification.SubCalculationStackSpace, funcDef.NodeMemorySize), (0, 0));

            if (funcDef.ScopeResolution != null)
            {
                newFunctionScope.AddRange(this.GlobalScope.Get(funcDef.ScopeResolution.ID, Classification.Class).Link.GetAll(Classification.Variable), (0, 0));
            }

            newFunctionScope.AddRange(this.FunctionScopeLink.Link.GetAll(), (0, 0));

            FunctionScopeLink.Link = newFunctionScope;
        }
Exemple #2
0
        public SymbolTable GetCurrentScope()
        {
            var table = new SymbolTable();

            table.AddRange(this.GlobalScope.GetAll(), (0, 0));
            table.AddRange(this.FunctionScopeLink?.Link?.GetAll(), (0, 0));
            table.AddRange(this.ClassInstanceScope?.GetAll(), (0, 0));
            return(table);
        }
        public void AddRange()
        {
            var symbols = new Symbol[]{
                new Symbol(SymbolType.Private, "id1"),
                new Symbol(SymbolType.Public, "id2")
            };

            SymbolTable table = new SymbolTable();
            Assert.AreEqual(0, table.Count);
            table.AddRange(symbols);

            Assert.AreEqual(symbols.Length, table.Count);
            Assert.AreEqual(symbols, table.ToArray());
        }
Exemple #4
0
        public void AddRange()
        {
            var symbols = new Symbol[] {
                new Symbol(SymbolType.Private, "id1"),
                new Symbol(SymbolType.Public, "id2")
            };

            SymbolTable table = new SymbolTable();

            Assert.AreEqual(0, table.Count);
            table.AddRange(symbols);

            Assert.AreEqual(symbols.Length, table.Count);
            Assert.AreEqual(symbols, table.ToArray());
        }
        public override void Visit(Program node)
        {
            // Determines whether or not a class contains full implementation.
            Dictionary <string, object> Done = new Dictionary <string, object>();

            // This is done after we visited all the classes.
            foreach (var classEntry in classes.Values)
            {
                var visiting       = new Stack <ClassDecl>();
                var visited        = new Dictionary <string, object>();
                var implementation = new SymbolTable();
                var focus          = classEntry;

                implementation.AddRange(classEntry.Table.GetAll(), classEntry.Location);

                do
                {
                    visited.Add(focus.ClassName, null);
                    foreach (var parent in focus.InheritingClasses.IDs)
                    {
                        if (Done.ContainsKey(parent))
                        {
                            implementation.AddRange(classes[parent].Table.GetAll(), classEntry.Location, true);
                        }
                        else
                        {
                            if (visited.ContainsKey(parent))
                            {
                                ErrorManager.Add($"Circular dependancy deteced between {focus.ClassName} and {parent}.", focus.Location);
                                visiting.Clear();
                                break;
                            }
                            else
                            {
                                if (classes.ContainsKey(parent))
                                {
                                    implementation.AddRange(classes[parent].Table.GetAll(), classEntry.Location);
                                    visiting.Push(classes[parent]);
                                }
                                else
                                {
                                    ErrorManager.Add($"The class {parent} cannot be found or is not defined.", focus.Location);
                                }
                            }
                        }
                    }

                    if (visiting.Count > 0)
                    {
                        focus = visiting.Pop();
                    }
                    else
                    {
                        focus = null;
                    }
                } while (focus != null);

                Done.Add(classEntry.ClassName, null);
                classEntry.Table = implementation;
            }

            foreach (var classEntry in GlobalScope.GetAll(Classification.Class))
            {
                classEntry.Link = classes[classEntry.ID].Table;
            }
        }
        public override void Visit(Var var)
        {
            SymbolTable currentScope = new SymbolTable();

            currentScope.AddRange(this._functionScope.GetAll(), var.Location);
            currentScope.AddRange(this._globalScope.GetAll(), var.Location);
            currentScope.AddRange(this._classInstanceScope?.GetAll(), var.Location);

            foreach (var element in var.Elements)
            {
                if (element is AParams aparams)
                {
                    throw new System.Exception();
                }

                if (element is DataMember dataMember)
                {
                    TableEntry entry = null;
                    if (currentScope.Get($"{dataMember.Id}-{Classification.Variable}") is TableEntry vEntry)
                    {
                        entry = vEntry;
                    }
                    else if (currentScope.Get($"{dataMember.Id}-{Classification.Parameter}") is TableEntry pEntry)
                    {
                        entry = pEntry;
                    }
                    else
                    {
                        ErrorManager.Add($"The {Classification.Variable} {dataMember.Id} could not be resolved.", dataMember.Location);
                        break;
                    }

                    int actualNumParams;
                    if (dataMember.Indexes == null)
                    {
                        actualNumParams = 0;
                    }
                    else
                    {
                        actualNumParams = dataMember.Indexes.Expressions.Count;
                    }
                    int expectedNumParams = entry.Type.Count(val => val == '[');
                    int diffIndices       = expectedNumParams - actualNumParams;

                    if (diffIndices < 0)
                    {
                        ErrorManager.Add($"Too many indices for {dataMember.Id}. Got {actualNumParams}, expected {expectedNumParams}", dataMember.Location);
                        break;
                    }

                    for (int i = 0; i < actualNumParams && i < expectedNumParams; i++)
                    {
                        var exp = dataMember.Indexes.Expressions[i] as Node;
                        if (exp.SemanticalType != "int")
                        {
                            ErrorManager.Add($"Index must be of type int and not {exp.SemanticalType}.", exp.Location);
                        }
                    }

                    dataMember.SemanticalType = entry.Type.Replace("[]", string.Empty) + "[]".Repeat(diffIndices);
                    var.SemanticalType        = dataMember.SemanticalType;

                    currentScope = new SymbolTable();
                    currentScope.AddRange(_globalScope.Get($"{var.SemanticalType}-{Classification.Class}")?.Link?.GetAll(), var.Location);
                }

                if (element is FCall fcall)
                {
                    TableEntry entry = currentScope.Get($"{fcall.Id}-{Classification.Function}");

                    if (entry != null)
                    {
                        var    types      = entry.Type.Split('-');
                        string returnType = types[0];
                        var    parameters = types[1] == "" ? new string[0] : types[1].Split(',');

                        if (parameters.Length == fcall.Parameters.Expressions.Count)
                        {
                            for (int i = 0; i < parameters.Length; i++)
                            {
                                string expectedType = parameters[i];

                                var expression = fcall.Parameters.Expressions[i] as Node;
                                if (expression != null)
                                {
                                    string actualType = expression.SemanticalType;

                                    if (actualType != expectedType)
                                    {
                                        ErrorManager.Add($"Invalid parameter type: Expected {expectedType}, got {actualType}", expression.Location);
                                        break;
                                    }
                                }
                                else
                                {
                                    throw new System.Exception();
                                }
                            }

                            fcall.SemanticalType = returnType;
                            var.SemanticalType   = returnType;

                            if (entry.Link == null)
                            {
                                ErrorManager.Add($"The function {fcall.Id} is not linked.", fcall.Location);
                                //break;
                            }

                            currentScope = new SymbolTable();
                            currentScope.AddRange(_globalScope.Get($"{var.SemanticalType}-{Classification.Class}")?.Link?.GetAll(), var.Location);
                        }
                        else
                        {
                            ErrorManager.Add($"The function {fcall.Id} takes in {parameters.Length} arguments.", fcall.Location);
                            var.SemanticalType = returnType;
                            break;
                        }
                    }
                    else
                    {
                        ErrorManager.Add($"The function {fcall.Id} could not be found or does not exist.", fcall.Location);
                        break;
                    }
                }
            }
        }
Exemple #7
0
 protected virtual void CloneFrom(MetaTableImpl metaTable)
 {
     _table = _createInternalStorage(metaTable.Count);
     _table.AddRange(metaTable._table);
     _filter = metaTable._filter;
 }