Beispiel #1
0
        //--- determine if name is already in scope.
        public bool IsDefined(String name)
        {
            bool defined = symbols.IsDefined(name); // look in current symbol table.

            if (defined || outer == null)
            {
                // either name is found in current symbol table or there is no outer table - so return what we've got.
                return(defined);
            }
            else
            {
                return(outer.IsDefined(name)); // not found so search recursively through outer scope.
            }
        } // end IsDefined method.
        public bool IsDefinedInParent(String name)
        {
            ISymbolTable scopeRef = parent;

            while (scopeRef != null)
            {
                if (scopeRef.IsDefined(name))
                {
                    return(true);
                }

                scopeRef = scopeRef.Parent;
            }

            return(false);
        }
Beispiel #3
0
        public override bool VisitAssignmentExpression(AssignmentExpression assignExp)
        {
            if (assignExp.Target.NodeType == NodeType.VariableRefExpression)
            {
                // Convert to declaration if not found on the scope

                VariableReferenceExpression varRef = (VariableReferenceExpression)assignExp.Target;

                ISymbolTable scope = varRef.SymbolTable;

                System.Diagnostics.Debug.Assert(scope != null);

                String name = varRef.Identifier.Name;

                if (!scope.IsDefined(name))                 // TODO: The rules are slighly more complicated than that.
                {
                    errorReport.Disable();

                    SingleVariableDeclarationStatement varDecl = new SingleVariableDeclarationStatement(varRef.Identifier);

                    IStatement stmt = ASTUtils.GetParentStatement(varRef);

                    System.Diagnostics.Debug.Assert(stmt != null);

                    IStatementContainer stmts = stmt.Parent as IStatementContainer;

                    int index = stmts.Statements.IndexOf(stmt);

                    varDecl.InitExp = assignExp.Value;

                    // stmts.Statements.Insert(index, varDecl);
                    stmts.Statements.Replace(stmt, varDecl);

                    if (!ApplyDeclarationRules(varRef.Identifier, scope, varDecl, stmt))
                    {
                        stmts.Statements.Remove(varDecl);
                    }

                    errorReport.Enable();
                }
            }

            return(base.VisitAssignmentExpression(assignExp));
        }
Beispiel #4
0
        public override bool VisitParameterIdentifier(ParameterIdentifier parameterIdentifier)
        {
            ISymbolTable namescope = parameterIdentifier.Parent.SymbolTable;

            System.Diagnostics.Debug.Assert(namescope != null);
            System.Diagnostics.Debug.Assert(namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Block);

            if (!identifierService.IsValidFormatParameterName(parameterIdentifier.Name))
            {
                errorReport.Error("TODOFILENAME", parameterIdentifier.Position, "'{0}' is an invalid parameter name.", parameterIdentifier.Name);
                return(false);
            }

            System.Diagnostics.Debug.Assert(!namescope.IsDefined(parameterIdentifier.Name));

            namescope.AddVariable(parameterIdentifier);

            return(base.VisitParameterIdentifier(parameterIdentifier));
        }
Beispiel #5
0
        private void EnsureTypeDeclarationsBelongsToThisScope(MultipleVariableDeclarationStatement varDecl, IList stmts)
        {
            ISymbolTable namescope = varDecl.Parent.SymbolTable;

            System.Diagnostics.Debug.Assert(namescope != null);

            foreach (SingleVariableDeclarationStatement typeDecl in stmts)
            {
                Identifier ident = typeDecl.Identifier;

                // Most simple of cases: duplicated declaration
                if (namescope.IsDefined(ident.Name))
                {
                    errorReport.Error("TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined.", ident.Name);
                    continue;
                }

                ApplyDeclarationRules(ident, namescope, typeDecl, varDecl);
            }
        }
Beispiel #6
0
        private bool ApplyDeclarationRules(Identifier ident, ISymbolTable namescope, SingleVariableDeclarationStatement typeDecl, IStatement statem)
        {
            // Second simple case: a local var and we are on the right place to
            // declare it
            if (ident.Type == IdentifierType.Local &&
                (namescope.ScopeType == ScopeType.Method ||
                 namescope.ScopeType == ScopeType.Compound ||
                 namescope.ScopeType == ScopeType.Block))
            {
                namescope.AddVariable(ident);
                return(true);
            }

            // More complex: a block or compound tries to redefine a variable
            if (ident.Type == IdentifierType.Local &&
                (namescope.ScopeType == ScopeType.Compound ||
                 namescope.ScopeType == ScopeType.Block))
            {
                if (namescope.Parent.IsDefined(ident.Name))
                {
                    errorReport.Error("TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined in a parent scope.", ident.Name);
                    return(false);
                }
            }

            // Local variables at class level?
            // We will support that as a type initializer, but not now.
            if (ident.Type == IdentifierType.Local && namescope.ScopeType == ScopeType.Type)
            {
                errorReport.Error("TODOFILENAME", typeDecl.Position, "At type level, just instance or static fields are allowed (yet)");
                return(false);
            }

            // Static or instance in a method/block/compound are moved
            // to the parent class or source unit level
            if (ident.Type == IdentifierType.InstanceField ||
                ident.Type == IdentifierType.StaticField)
            {
                if (namescope.ScopeType == ScopeType.SourceUnit ||
                    namescope.ScopeType == ScopeType.Type)
                {
                    namescope.AddVariable(ident);
                }
                else if (namescope.ScopeType == ScopeType.Method ||
                         namescope.ScopeType == ScopeType.Compound ||
                         namescope.ScopeType == ScopeType.Block)
                {
                    IASTNode node = statem.Parent;

                    while (node != null &&
                           node.NodeType != NodeType.TypeDefinition &&
                           node.NodeType != NodeType.SourceUnit)
                    {
                        node = node.Parent;
                    }

                    if (node == null || node.SymbolTable == null)
                    {
                        errorReport.Error("TODOFILENAME", typeDecl.Position,
                                          "Compiler error: The instance of static declaration '{0}' could not be mapped to a parent type", ident.Name);
                        return(false);
                    }

                    ISymbolTable parentScope = node.SymbolTable;

                    IStatementContainer typeStmtsContainer = node as IStatementContainer;

                    System.Diagnostics.Debug.Assert(parentScope != null);
                    System.Diagnostics.Debug.Assert(typeStmtsContainer != null);

                    if (parentScope.IsDefined(ident.Name))
                    {
                        errorReport.Error("TODOFILENAME", typeDecl.Position,
                                          "Sorry but '{0}' is already defined.", ident.Name);
                        return(false);
                    }
                    else
                    {
                        parentScope.AddVariable(ident);

                        // We can replace the declaration on the method
                        // body with an assignment if and only if this type decl has
                        // an init expression, so CreateAssignmentFromTypeDecl can return null
                        AssignmentExpression assignExp     = CreateAssignmentFromTypeDecl(typeDecl);
                        ExpressionStatement  assignExpStmt = new ExpressionStatement(assignExp);

                        typeDecl.ConvertInitExpressionToDependency();

                        // Replace the declaration with an assignment
                        (statem.Parent as IStatementContainer).Statements.Replace(typeDecl, assignExpStmt);

                        // Add the member/field declaration to the parent
                        typeStmtsContainer.Statements.Add(typeDecl);

                        // TODO: Link assignment expression and typeDecl to help
                        // find out the type of the field later

                        return(true);
                    }
                }
            }

            return(false);
        }