コード例 #1
0
        public override void EnterLocalVariableDeclaration([NotNull] NovaParser.LocalVariableDeclarationContext context)
        {
            VariableDeclaratorContext declarator = context.variableDeclarator();

            string type = context.typeType().GetChild(0).GetText();
            string name = declarator.variableDeclaratorId().GetText();

            DeclarationStatement statement = new DeclarationStatement(Parent, context);

            Variable variable = new Variable(name, type, context.variableDeclarator());

            ExpressionNode value = new ExpressionNode(statement);

            VariableInitializerContext initializer = declarator.variableInitializer();

            if (initializer != null)
            {
                ExpressionContext  expressionContext = initializer.expression();
                ExpressionListener listener          = new ExpressionListener(statement);

                expressionContext.EnterRule(listener);

                value = listener.GetResult();
            }

            statement.Variable = variable;
            statement.Value    = value;

            Result.Add(statement);
        }
コード例 #2
0
 public void VisitDeclarationStatement(DeclarationStatement node)
 {
     foreach (var declaration in node.Declarations)
     {
         declaration.Accept(this);
     }
 }
コード例 #3
0
 public void Visit(DeclarationStatement expressionNode)
 {
     foreach (var decl in expressionNode.Declarations)
     {
         decl.Accept(this);
     }
 }
コード例 #4
0
        public override void Switch(IAstTransformer transformer, out Node resultingNode)
        {
            DeclarationStatement thisNode           = (DeclarationStatement)this;
            Statement            resultingTypedNode = thisNode;

            transformer.OnDeclarationStatement(thisNode, ref resultingTypedNode);
            resultingNode = resultingTypedNode;
        }
コード例 #5
0
ファイル: Statement.cs プロジェクト: weshaggard/Testura.Code
 static Statement()
 {
     Declaration = new DeclarationStatement();
     Jump        = new JumpStatement();
     Selection   = new SelectionStatement();
     Iteration   = new IterationStatement();
     Expression  = new ExpressionStatement();
 }
コード例 #6
0
 public void Visit(DeclarationStatement expressionNode)
 {
     foreach (var d in expressionNode.Declarations)
     {
         CurrentSymbolTable.AnnotateTypedSymbol(d.Reference, expressionNode.Type);
         d.Initialization?.Accept(this);
     }
 }
コード例 #7
0
ファイル: BasicRecompiler.cs プロジェクト: npvb/CAsGen
        private void GenerateDeclaration(DeclarationStatement declaration, StringBuilder programBuilder)
        {
            var declarationType = declaration.GetType();

            if (declaration is FunctionDeclaration)
            {
                GenerateFunction(declaration as FunctionDeclaration, programBuilder);
            }
        }
コード例 #8
0
        //if(st is AliasStatement) {
        //        Console.WriteLine("is AliasStatement");
        //        return;
        //    }  else if(st is BreakStatement) {
        //        Console.WriteLine("is BreakStatement");
        //        return;
        //    } else if(st is ContinueStatement) {
        //        Console.WriteLine("is ContinueStatement");
        //        return;
        //    } else if(st is ExternStatement) {
        //        Console.WriteLine("is ExternStatement");
        //        return;
        //    } else if(st is GotoStatement) {
        //        Console.WriteLine("is GotoStatement");
        //        return;
        //    } else if(st is ImportStatement) {
        //        Console.WriteLine("is ImportStatement");
        //        return;
        //    } else if(st is LabelStatement) {
        //        Console.WriteLine("is LabelStatement");
        //        return;
        //    } else if(st is ThrowStatement) {
        //        Console.WriteLine("is VariableDeclaration");
        //        return;
        //    } else {
        //        if(!st.GetType().IsSubclassOf(typeof(Statement))) {
        //            VisitOtherStmt(st);
        //        }
        //        return;
        //    }


        /// <summary>
        /// Stores the local defined variable's info and updates if it has been initialized
        /// </summary>
        /// <param name="dst"></param>
        private void AnalyzeDeclarationStatement(DeclarationStatement dst)
        {
            //from child in dst.GetDescendantsAndSelf()
            var allDeclarations = from expression in dst.FindExpressions <VariableDeclaration>(true)
                                  select expression;

            foreach (var vd in allDeclarations)
            {
                UpdateByExpression(vd);
            }
        }
コード例 #9
0
 public override void OnDeclarationStatement(DeclarationStatement node)
 {
     Write(Indent());
     Visit(node.Declaration);
     if (node.Initializer != null)
     {
         Write(" = ");
         Visit(node.Initializer);
     }
     WriteLine(";");
 }
コード例 #10
0
ファイル: BooPrinterVisitor.cs プロジェクト: codehaus/boo
 override public void OnDeclarationStatement(DeclarationStatement d)
 {
     WriteIndented();
     Visit(d.Declaration);
     if (null != d.Initializer)
     {
         WriteOperator(" = ");
         Visit(d.Initializer);
     }
     WriteLine();
 }
コード例 #11
0
 public override void OnDeclarationStatement(DeclarationStatement node)
 {
     if (node.Declaration.Type != null && !SearchField(node.Declaration.Name))
     {
         TypeReference initializerType = GetInferredType(node.Initializer);
         if (node.Declaration.Type.Matches(initializerType))
         {
             node.Declaration.Type = null;
         }
     }
     base.OnDeclarationStatement(node);
 }
コード例 #12
0
        public override void OnDeclarationStatement(DeclarationStatement node)
        {
            CodeVariableDeclarationStatement var = new CodeVariableDeclarationStatement(ConvTypeRef(node.Declaration.Type),
                                                                                        node.Declaration.Name);

            if (node.Initializer != null)
            {
                _expression = null;
                node.Initializer.Accept(this);
                var.InitExpression = _expression;
            }
            _statements.Add(var);
        }
コード例 #13
0
        public override void LeaveDeclarationStatement(DeclarationStatement node)
        {
            if (node.Declaration.Type != null)
            {
                Expression initializer = node.Initializer;
                if (initializer is TryCastExpression)
                {
                    TryCastExpression tryCastExpression = (TryCastExpression)initializer;

                    Expression    target = tryCastExpression.Target;
                    TypeReference type   = tryCastExpression.Type;
                    node.Initializer = target;
                }
            }
        }
コード例 #14
0
 static void ReplaceWithInitializer(DeclarationStatement decl)
 {
     if (decl.Initializer == null)
     {
         decl.ReplaceBy(null);
     }
     else
     {
         ExpressionStatement statement = new ExpressionStatement(decl.LexicalInfo);
         statement.Expression = new BinaryExpression(decl.LexicalInfo, BinaryOperatorType.Assign,
                                                     new ReferenceExpression(decl.Declaration.LexicalInfo, decl.Declaration.Name),
                                                     decl.Initializer);
         decl.ReplaceBy(statement);
     }
 }
コード例 #15
0
ファイル: ParserStatements.cs プロジェクト: tmakij/MiniPascal
        private IStatement DeclarationStatement()
        {
            DeclarationStatement varDecl = VariableDeclaration();

            if (varDecl != null)
            {
                return(varDecl);
            }
            Procedure procDecl = ProcedureStatement();

            if (procDecl != null)
            {
                return(procDecl);
            }
            return(ReadFunction());
        }
コード例 #16
0
        public static void RenameLocals(Block block, StringComparer nameComparer)
        {
            FindVariableDeclarationsVisitor fvdv = new FindVariableDeclarationsVisitor();

            block.Accept(fvdv);
            List <DeclarationStatement> list = new List <DeclarationStatement>();

            foreach (DeclarationStatement decl in fvdv.Declarations)
            {
                DeclarationStatement conflict = null;
                int conflictIndex             = -1;
                for (int i = 0; i < list.Count; i++)
                {
                    if (nameComparer.Equals(list[i].Declaration.Name, decl.Declaration.Name))
                    {
                        conflict      = list[i];
                        conflictIndex = i;
                        break;
                    }
                }
                if (conflict == null)
                {
                    list.Add(decl);
                }
                else
                {
                    // Handle conflict: try if "moveup" would be sufficient
                    if (IsSameType(decl.Declaration.Type, conflict.Declaration.Type, nameComparer))
                    {
                        // create declaration at beginning of class and
                        // replace decl & conflict by assignment
                        DeclarationStatement newDecl = new DeclarationStatement(conflict.LexicalInfo);
                        newDecl.Declaration = new Declaration(conflict.Declaration.LexicalInfo, conflict.Declaration.Name, conflict.Declaration.Type);
                        block.Insert(0, newDecl);
                        ReplaceWithInitializer(decl);
                        ReplaceWithInitializer(conflict);
                        list[conflictIndex] = newDecl;
                    }
                    else
                    {
                        string newName = FindFreeName(decl.Declaration.Name, list, fvdv.Declarations, nameComparer);
                        decl.ParentNode.Accept(new RenameLocalsVisitor(decl.Declaration.Name, newName, nameComparer));
                        decl.Declaration.Name = newName;
                    }
                }
            }
        }
コード例 #17
0
 public override void OnDeclarationStatement(DeclarationStatement node)
 {
     if (!node.ContainsAnnotation("PrivateScope"))
     {
         Field         field;
         Field         field1      = field = new Field(LexicalInfo.Empty);
         int           num1        = (int)(field.Modifiers = TypeMemberModifiers.Public);
         string        text1       = field.Name = "$";
         TypeReference reference1  = field.Type = TypeReference.Lift(node.Declaration.Type);
         Expression    expression1 = field.Initializer = Expression.Lift(node.Initializer);
         int           num2        = (int)(field.IsVolatile = false);
         string        text2       = field.Name = CodeSerializer.LiftName(node.Declaration.Name);
         Field         item        = field;
         item.LexicalInfo = node.LexicalInfo;
         this._class.Members.Add(item);
         this.RemoveCurrentNode();
     }
 }
コード例 #18
0
        public override void OnBlock(Block node)
        {
            try
            {
                if (node.Statements.Count == 0 || node.Statements[0].NodeType != NodeType.Block)
                {
                    return;
                }

                var innerBlock = (Block)node.Statements[0];
                ExpressionStatement firstStatement;
                if (!IsSwitchStatementWithOnlyDefault(innerBlock, out firstStatement))
                {
                    return;
                }

                var binaryExp = (BinaryExpression)firstStatement.Expression;
                if (binaryExp.Operator != BinaryOperatorType.Assign || binaryExp.Left.NodeType != NodeType.ReferenceExpression || !binaryExp.Left.ToCodeString().Contains("$switch$"))
                {
                    return;
                }

                var originalLocal = ((InternalLocal)binaryExp.Left.Entity).Local;
                var varName       = originalLocal.Name.Replace("$", "_");
                var local         = new Local(varName, true);
                var internalLocal = new InternalLocal(local, binaryExp.ExpressionType);
                local.Entity = internalLocal;

                internalLocal.OriginalDeclaration = new Declaration(varName, CodeBuilder.CreateTypeReference(internalLocal.Type));

                // we need a DeclarationStatment as the parent of the "OriginalDeclaration"
                var ds = new DeclarationStatement(internalLocal.OriginalDeclaration, binaryExp.Right);

                innerBlock.Statements.RemoveAt(0);

                var parentMethod = node.GetAncestor <Method>();
                parentMethod.Locals.Replace(originalLocal, internalLocal.Local);
            }
            finally
            {
                base.OnBlock(node);
            }
        }
コード例 #19
0
        private IType GetTypeFromDeclarationContext()
        {
            TypeReference        tr = null;
            DeclarationStatement ds = _parent as DeclarationStatement;

            if (ds != null)
            {
                tr = ds.Declaration.Type;
            }

            Field fd = _parent as Field;

            if (fd != null)
            {
                tr = fd.Type;
            }

            if (tr != null)
            {
                return(tr.Entity as IType);
            }
            return(null);
        }
コード例 #20
0
ファイル: FlowAnalyzer.cs プロジェクト: smx-smx/ValaSharp
        public override void visit_declaration_statement(DeclarationStatement stmt)
        {
            stmt.accept_children(this);

            if (unreachable(stmt))
            {
                stmt.declaration.unreachable = true;
                return;
            }

            if (!stmt.declaration.used)
            {
                Report.warning(stmt.declaration.source_reference, "local variable `%s' declared but never used".printf(stmt.declaration.name));
            }

            current_block.add_node(stmt);

            var local = stmt.declaration as LocalVariable;

            if (local != null && local.initializer != null)
            {
                handle_errors(local.initializer);
            }
        }
コード例 #21
0
ファイル: Parser_Impl.cs プロジェクト: gavin-norman/Mono-D
        IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null)
        {
            if (EmptyAllowed && laKind == Semicolon)
            {
                LastParsedObject = null;
                Step();
                return null;
            }

            if (BlocksAllowed && laKind == OpenCurlyBrace)
                return BlockStatement(Scope,Parent);

            #region LabeledStatement (loc:... goto loc;)
            if (laKind == Identifier && Lexer.CurrentPeekToken.Kind == Colon)
            {
                Step();

                var ret = new LabeledStatement() { Location = t.Location, Identifier = t.Value, Parent = Parent };
                LastParsedObject = ret;
                Step();
                ret.EndLocation = t.EndLocation;

                return ret;
            }
            #endregion

            #region IfStatement
            else if (laKind == (If) || (laKind == Static && Lexer.CurrentPeekToken.Kind == If))
            {
                bool isStatic = laKind == Static;
                if (isStatic)
                    Step();

                Step();

                var dbs = new IfStatement() { Location = t.Location, IsStatic = isStatic, Parent = Parent };
                LastParsedObject = dbs;
                Expect(OpenParenthesis);

                // IfCondition
                IfCondition(dbs);

                // ThenStatement
                if(Expect(CloseParenthesis))
                    dbs.ThenStatement = Statement(Scope: Scope, Parent: dbs);

                // ElseStatement
                if (laKind == (Else))
                {
                    Step();
                    dbs.ElseStatement = Statement(Scope: Scope, Parent: dbs);
                }

                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region WhileStatement
            else if (laKind == While)
            {
                Step();

                var dbs = new WhileStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = dbs;
                Expect(OpenParenthesis);
                dbs.Condition = Expression(Scope);
                Expect(CloseParenthesis);

                dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);
                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region DoStatement
            else if (laKind == (Do))
            {
                Step();

                var dbs = new WhileStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = dbs;
                dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);

                Expect(While);
                Expect(OpenParenthesis);
                dbs.Condition = Expression(Scope);
                Expect(CloseParenthesis);

                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region ForStatement
            else if (laKind == (For))
            {
                Step();

                var dbs = new ForStatement { Location = t.Location, Parent = Parent };
                LastParsedObject = dbs;
                Expect(OpenParenthesis);

                // Initialize
                if (laKind != Semicolon)
                    dbs.Initialize = Statement(false, Scope: Scope, Parent: dbs); // Against the D language theory, blocks aren't allowed here!
                else
                    Step();
                // Enforce a trailing semi-colon only if there hasn't been an expression (the ; gets already skipped in there)
                //	Expect(Semicolon);

                // Test
                if (laKind != (Semicolon))
                    dbs.Test = Expression(Scope);

                Expect(Semicolon);

                // Increment
                if (laKind != (CloseParenthesis))
                    dbs.Increment = Expression(Scope);

                Expect(CloseParenthesis);

                dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);
                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region ForeachStatement
            else if (laKind == Foreach || laKind == Foreach_Reverse)
                return ForeachStatement(Scope, Parent);
            #endregion

            #region [Final] SwitchStatement
            else if ((laKind == (Final) && Lexer.CurrentPeekToken.Kind == (Switch)) || laKind == (Switch))
            {
                var dbs = new SwitchStatement { Location = la.Location, Parent = Parent };
                LastParsedObject = dbs;
                if (laKind == (Final))
                {
                    dbs.IsFinal = true;
                    Step();
                }
                Step();
                Expect(OpenParenthesis);
                dbs.SwitchExpression = Expression(Scope);
                Expect(CloseParenthesis);

                dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);
                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region CaseStatement
            else if (laKind == (Case))
            {
                Step();

                var dbs = new SwitchStatement.CaseStatement() { Location = la.Location, Parent = Parent };
                LastParsedObject = dbs;
                dbs.ArgumentList = Expression(Scope);

                Expect(Colon);

                // CaseRangeStatement
                if (laKind == DoubleDot)
                {
                    Step();
                    Expect(Case);
                    dbs.LastExpression = AssignExpression();
                    Expect(Colon);
                }

                var sl = new List<IStatement>();

                while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF)
                {
                    var stmt = Statement(Scope: Scope, Parent: dbs);

                    if (stmt != null)
                    {
                        stmt.Parent = dbs;
                        sl.Add(stmt);
                    }
                }

                dbs.ScopeStatementList = sl.ToArray();
                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region Default
            else if (laKind == (Default))
            {
                Step();

                var dbs = new SwitchStatement.DefaultStatement()
                {
                    Location = la.Location,
                    Parent = Parent
                };
                LastParsedObject = dbs;

                Expect(Colon);

                var sl = new List<IStatement>();

                while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF)
                {
                    var stmt = Statement(Scope: Scope, Parent: dbs);

                    if (stmt != null)
                    {
                        stmt.Parent = dbs;
                        sl.Add(stmt);
                    }
                }

                dbs.ScopeStatementList = sl.ToArray();
                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region Continue | Break
            else if (laKind == (Continue))
            {
                Step();
                var s = new ContinueStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;
                if (laKind == (Identifier))
                {
                    Step();
                    s.Identifier = t.Value;
                }
                Expect(Semicolon);
                s.EndLocation = t.EndLocation;

                return s;
            }

            else if (laKind == (Break))
            {
                Step();
                var s = new BreakStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;
                if (laKind == (Identifier))
                {
                    Step();
                    s.Identifier = t.Value;
                }
                Expect(Semicolon);
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region Return
            else if (laKind == (Return))
            {
                Step();
                var s = new ReturnStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;
                if (laKind != (Semicolon))
                    s.ReturnExpression = Expression(Scope);

                Expect(Semicolon);
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region Goto
            else if (laKind == (Goto))
            {
                Step();
                var s = new GotoStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;

                if (laKind == (Identifier))
                {
                    Step();
                    s.StmtType = GotoStatement.GotoStmtType.Identifier;
                    s.LabelIdentifier = t.Value;
                }
                else if (laKind == Default)
                {
                    Step();
                    s.StmtType = GotoStatement.GotoStmtType.Default;
                }
                else if (laKind == (Case))
                {
                    Step();
                    s.StmtType = GotoStatement.GotoStmtType.Case;

                    if (laKind != (Semicolon))
                        s.CaseExpression = Expression(Scope);
                }

                Expect(Semicolon);
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region WithStatement
            else if (laKind == (With))
            {
                Step();

                var dbs = new WithStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = dbs;
                Expect(OpenParenthesis);

                // Symbol
                dbs.WithExpression = Expression(Scope);

                Expect(CloseParenthesis);

                dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);

                dbs.EndLocation = t.EndLocation;
                return dbs;
            }
            #endregion

            #region SynchronizedStatement
            else if (laKind == (Synchronized))
            {
                Step();
                var dbs = new SynchronizedStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = dbs;

                if (laKind == (OpenParenthesis))
                {
                    Step();
                    dbs.SyncExpression = Expression(Scope);
                    Expect(CloseParenthesis);
                }

                dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);

                dbs.EndLocation = t.EndLocation;
                return dbs;
            }
            #endregion

            #region TryStatement
            else if (laKind == (Try))
            {
                Step();

                var s = new TryStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;

                s.ScopedStatement = Statement(Scope: Scope, Parent: s);

                if (!(laKind == (Catch) || laKind == (Finally)))
                    SemErr(Catch, "At least one catch or a finally block expected!");

                var catches = new List<TryStatement.CatchStatement>();
                // Catches
                while (laKind == (Catch))
                {
                    Step();

                    var c = new TryStatement.CatchStatement() { Location = t.Location, Parent = s };
                    LastParsedObject = c;

                    // CatchParameter
                    if (laKind == (OpenParenthesis))
                    {
                        Step();

                        if (laKind == CloseParenthesis)
                        {
                            SemErr(CloseParenthesis, "Catch parameter expected, not ')'");
                            Step();
                        }
                        else
                        {
                            var catchVar = new DVariable();
                            LastParsedObject = catchVar;
                            var tt = la; //TODO?
                            catchVar.Type = BasicType();
                            if (laKind != Identifier)
                            {
                                la = tt;
                                catchVar.Type = new IdentifierDeclaration("Exception");
                            }
                            Expect(Identifier);
                            catchVar.Name = t.Value;
                            Expect(CloseParenthesis);

                            c.CatchParameter = catchVar;
                        }
                    }

                    c.ScopedStatement = Statement(Scope: Scope, Parent: c);
                    c.EndLocation = t.EndLocation;

                    catches.Add(c);
                }

                if (catches.Count > 0)
                    s.Catches = catches.ToArray();

                if (laKind == (Finally))
                {
                    Step();

                    var f = new TryStatement.FinallyStatement() { Location = t.Location, Parent = Parent };
                    LastParsedObject = f;

                    f.ScopedStatement = Statement();
                    f.EndLocation = t.EndLocation;

                    s.FinallyStmt = f;
                }

                s.EndLocation = t.EndLocation;
                return s;
            }
            #endregion

            #region ThrowStatement
            else if (laKind == (Throw))
            {
                Step();
                var s = new ThrowStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;

                s.ThrowExpression = Expression(Scope);
                Expect(Semicolon);
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region ScopeGuardStatement
            else if (laKind == DTokens.Scope)
            {
                Step();

                if (laKind == OpenParenthesis)
                {
                    var s = new ScopeGuardStatement() { Location = t.Location, Parent = Parent };
                    LastParsedObject = s;

                    Step();

                    if (Expect(Identifier) && t.Value != null) // exit, failure, success
                        s.GuardedScope = t.Value.ToLower();

                    if (Expect(CloseParenthesis))
                        TrackerVariables.ExpectingIdentifier = false;

                    if (!IsEOF)
                        s.ScopedStatement = Statement(Scope: Scope, Parent: s);

                    s.EndLocation = t.EndLocation;
                    return s;
                }
                else
                    PushAttribute(new DAttribute(DTokens.Scope), false);
            }
            #endregion

            #region AsmStmt
            else if (laKind == Asm)
                return AsmStatement(Parent);
            #endregion

            #region PragmaStatement
            else if (laKind == (Pragma))
            {
                var s = new PragmaStatement { Location = la.Location };

                s.Pragma = _Pragma();
                s.Parent = Parent;

                s.ScopedStatement = Statement(Scope: Scope, Parent: s);
                s.EndLocation = t.EndLocation;
                return s;
            }
            #endregion

            #region MixinStatement
            //TODO: Handle this one in terms of adding it to the node structure
            else if (laKind == (Mixin))
            {
                if (Peek(1).Kind == OpenParenthesis)
                    return MixinDeclaration();
                else
                    return TemplateMixin();
            }
            #endregion

            #region Conditions
            if (laKind == Debug)
                return DebugStatement(Scope, Parent);

            if (laKind == Version)
                return VersionStatement(Scope, Parent);
            #endregion

            #region (Static) AssertExpression
            else if (laKind == Assert || (laKind == Static && PK(Assert)))
            {
                var s = new AssertStatement() { Location = la.Location, IsStatic = laKind == Static, Parent = Parent };
                LastParsedObject = s;

                if (s.IsStatic)
                    Step();

                Step();

                if (Expect(OpenParenthesis))
                {
                    s.AssertedExpression = Expression(Scope);
                    Expect(CloseParenthesis);
                    Expect(Semicolon);
                }
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region D1: VolatileStatement
            else if (laKind == Volatile)
            {
                Step();
                var s = new VolatileStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;
                s.ScopedStatement = Statement(Scope: Scope, Parent: s);
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            // ImportDeclaration
            else if (laKind == Import)
                return ImportDeclaration();

            else if (!(ClassLike[laKind] || BasicTypes[laKind] || laKind == Enum || Modifiers[laKind] || laKind == PropertyAttribute || laKind == Alias || laKind == Typedef) && IsAssignExpression())
            {
                var s = new ExpressionStatement() { Location = la.Location, Parent = Parent };

                if (!IsEOF)
                    LastParsedObject = s;
                // a==b, a=9; is possible -> Expressions can be there, not only single AssignExpressions!
                s.Expression = Expression(Scope);

                if (Expect(Semicolon))
                    LastParsedObject = null;

                s.EndLocation = t.EndLocation;
                return s;
            }
            else
            {
                var s = new DeclarationStatement() { Location = la.Location, Parent = Parent };
                LastParsedObject = s;
                s.Declarations = Declaration(Scope);

                s.EndLocation = t.EndLocation;
                return s;
            }
        }
コード例 #22
0
		public override void Visit(DeclarationStatement s)
		{
			base.Visit(s);
			//FixStatementIndentation(s.Location);
			FixSemicolon(s.EndLocation);
			
			
		}
コード例 #23
0
ファイル: ShaderWriter.cs プロジェクト: Aggror/Stride
 /// <inheritdoc />
 public override void Visit(DeclarationStatement declarationStatement)
 {
     WriteLinkLine(declarationStatement);
     VisitDynamic(declarationStatement.Content);
 }
コード例 #24
0
ファイル: Parser_Impl.cs プロジェクト: rainers/D_Parser
        public IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null)
        {
            switch (laKind)
            {
                case Semicolon:
                    if (!EmptyAllowed)
                        goto default;
                    Step();
                    return null;
                case OpenCurlyBrace:
                    if (!BlocksAllowed)
                        goto default;
                    return BlockStatement(Scope,Parent);
                // LabeledStatement (loc:... goto loc;)
                case Identifier:
                    if (Lexer.CurrentPeekToken.Kind != Colon)
                        goto default;
                    Step();

                    var ls = new LabeledStatement() { Location = t.Location, Identifier = t.Value, Parent = Parent };
                    Step();
                    ls.EndLocation = t.EndLocation;

                    return ls;
                // IfStatement
                case If:
                    Step();

                    var iS = new IfStatement{	Location = t.Location, Parent = Parent	};

                    Expect(OpenParenthesis);
                    // IfCondition
                    IfCondition(iS);

                    // ThenStatement
                    if(Expect(CloseParenthesis))
                        iS.ThenStatement = Statement(Scope: Scope, Parent: iS);

                    // ElseStatement
                    if (laKind == (Else))
                    {
                        Step();
                        iS.ElseStatement = Statement(Scope: Scope, Parent: iS);
                    }

                    if(t != null)
                        iS.EndLocation = t.EndLocation;

                    return iS;
                // Conditions
                case Version:
                case Debug:
                    return StmtCondition(Parent, Scope);
                case Static:
                    if (Lexer.CurrentPeekToken.Kind == If)
                        return StmtCondition(Parent, Scope);
                    else if (Lexer.CurrentPeekToken.Kind == Assert)
                        goto case Assert;
                    else if (Lexer.CurrentPeekToken.Kind == Import)
                        goto case Import;
                    goto default;
                case For:
                    return ForStatement(Scope, Parent);
                case Foreach:
                case Foreach_Reverse:
                    return ForeachStatement(Scope, Parent);
                case While:
                    Step();

                    var ws = new WhileStatement() { Location = t.Location, Parent = Parent };

                    Expect(OpenParenthesis);
                    ws.Condition = Expression(Scope);
                    Expect(CloseParenthesis);

                    if(!IsEOF)
                    {
                        ws.ScopedStatement = Statement(Scope: Scope, Parent: ws);
                        ws.EndLocation = t.EndLocation;
                    }

                    return ws;
                case Do:
                    Step();

                    var dws = new WhileStatement() { Location = t.Location, Parent = Parent };
                    if(!IsEOF)
                        dws.ScopedStatement = Statement(true, false, Scope, dws);

                    if(Expect(While) && Expect(OpenParenthesis))
                    {
                        dws.Condition = Expression(Scope);
                        Expect(CloseParenthesis);
                        Expect(Semicolon);

                        dws.EndLocation = t.EndLocation;
                    }

                    return dws;
                // [Final] SwitchStatement
                case Final:
                    if (Lexer.CurrentPeekToken.Kind != Switch)
                        goto default;
                    goto case Switch;
                case Switch:
                    var ss = new SwitchStatement { Location = la.Location, Parent = Parent };
                    if (laKind == (Final))
                    {
                        ss.IsFinal = true;
                        Step();
                    }
                    Step();
                    Expect(OpenParenthesis);
                    ss.SwitchExpression = Expression(Scope);
                    Expect(CloseParenthesis);

                    if(!IsEOF)
                        ss.ScopedStatement = Statement(Scope: Scope, Parent: ss);
                    ss.EndLocation = t.EndLocation;

                    return ss;
                case Case:
                    Step();

                    var sscs = new SwitchStatement.CaseStatement() { Location = la.Location, Parent = Parent };
                    sscs.ArgumentList = Expression(Scope);

                    Expect(Colon);

                    // CaseRangeStatement
                    if (laKind == DoubleDot)
                    {
                        Step();
                        Expect(Case);
                        sscs.LastExpression = AssignExpression();
                        Expect(Colon);
                    }

                    var sscssl = new List<IStatement>();

                    while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF)
                    {
                        var stmt = Statement(Scope: Scope, Parent: sscs);

                        if (stmt != null)
                        {
                            stmt.Parent = sscs;
                            sscssl.Add(stmt);
                        }
                    }

                    sscs.ScopeStatementList = sscssl.ToArray();
                    sscs.EndLocation = t.EndLocation;

                    return sscs;
                case Default:
                    Step();

                    var ssds = new SwitchStatement.DefaultStatement()
                    {
                        Location = la.Location,
                        Parent = Parent
                    };

                    Expect(Colon);

                    var ssdssl = new List<IStatement>();

                    while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF)
                    {
                        var stmt = Statement(Scope: Scope, Parent: ssds);

                        if (stmt != null)
                        {
                            stmt.Parent = ssds;
                            ssdssl.Add(stmt);
                        }
                    }

                    ssds.ScopeStatementList = ssdssl.ToArray();
                    ssds.EndLocation = t.EndLocation;

                    return ssds;
                case Continue:
                    Step();
                    var cs = new ContinueStatement() { Location = t.Location, Parent = Parent };
                    if (laKind == (Identifier))
                    {
                        Step();
                        cs.Identifier = t.Value;
                    }
                    else if(IsEOF)
                        cs.IdentifierHash = DTokens.IncompleteIdHash;

                    Expect(Semicolon);
                    cs.EndLocation = t.EndLocation;

                    return cs;
                case Break:
                    Step();
                    var bs = new BreakStatement() { Location = t.Location, Parent = Parent };

                    if (laKind == (Identifier))
                    {
                        Step();
                        bs.Identifier = t.Value;
                    }
                    else if(IsEOF)
                        bs.IdentifierHash = DTokens.IncompleteIdHash;

                    Expect(Semicolon);

                    bs.EndLocation = t.EndLocation;

                    return bs;
                case Return:
                    Step();
                    var rs = new ReturnStatement() { Location = t.Location, Parent = Parent };

                    if (laKind != (Semicolon))
                        rs.ReturnExpression = Expression(Scope);

                    Expect(Semicolon);
                    rs.EndLocation = t.EndLocation;

                    return rs;
                case Goto:
                    Step();
                    var gs = new GotoStatement() { Location = t.Location, Parent = Parent };

                    switch(laKind)
                    {
                        case Identifier:
                            Step();
                            gs.StmtType = GotoStatement.GotoStmtType.Identifier;
                            gs.LabelIdentifier = t.Value;
                            break;
                        case Default:
                            Step();
                            gs.StmtType = GotoStatement.GotoStmtType.Default;
                            break;
                        case Case:
                            Step();
                            gs.StmtType = GotoStatement.GotoStmtType.Case;

                            if (laKind != (Semicolon))
                                gs.CaseExpression = Expression(Scope);
                            break;
                        default:
                            if (IsEOF)
                                gs.LabelIdentifierHash = DTokens.IncompleteIdHash;
                            break;
                    }
                    Expect(Semicolon);
                    gs.EndLocation = t.EndLocation;

                    return gs;
                case With:
                    Step();

                    var wS = new WithStatement() { Location = t.Location, Parent = Parent };

                    if(Expect(OpenParenthesis))
                    {
                        // Symbol
                        wS.WithExpression = Expression(Scope);

                        Expect(CloseParenthesis);

                        if(!IsEOF)
                            wS.ScopedStatement = Statement(Scope: Scope, Parent: wS);
                    }
                    wS.EndLocation = t.EndLocation;
                    return wS;
                case Synchronized:
                    Step();
                    var syncS = new SynchronizedStatement() { Location = t.Location, Parent = Parent };

                    if (laKind == (OpenParenthesis))
                    {
                        Step();
                        syncS.SyncExpression = Expression(Scope);
                        Expect(CloseParenthesis);
                    }

                    if(!IsEOF)
                        syncS.ScopedStatement = Statement(Scope: Scope, Parent: syncS);
                    syncS.EndLocation = t.EndLocation;

                    return syncS;
                case Try:
                    Step();

                    var ts = new TryStatement() { Location = t.Location, Parent = Parent };

                    ts.ScopedStatement = Statement(Scope: Scope, Parent: ts);

                    if (!(laKind == (Catch) || laKind == (Finally)))
                        SemErr(Catch, "At least one catch or a finally block expected!");

                    var catches = new List<TryStatement.CatchStatement>();
                    // Catches
                    while (laKind == (Catch))
                    {
                        Step();

                        var c = new TryStatement.CatchStatement() { Location = t.Location, Parent = ts };

                        // CatchParameter
                        if (laKind == (OpenParenthesis))
                        {
                            Step();

                            if (laKind == CloseParenthesis || IsEOF)
                            {
                                SemErr(CloseParenthesis, "Catch parameter expected, not ')'");
                                Step();
                            }
                            else
                            {
                                var catchVar = new DVariable { Parent = Scope, Location = t.Location };

                                Lexer.PushLookAheadBackup();
                                catchVar.Type = BasicType();
                                if (laKind == CloseParenthesis)
                                {
                                    Lexer.RestoreLookAheadBackup();
                                    catchVar.Type = new IdentifierDeclaration("Exception");
                                }
                                else
                                    Lexer.PopLookAheadBackup();

                                if (Expect(Identifier))
                                {
                                    catchVar.Name = t.Value;
                                    catchVar.NameLocation = t.Location;
                                    Expect(CloseParenthesis);
                                }
                                else if(IsEOF)
                                    catchVar.NameHash = DTokens.IncompleteIdHash;

                                catchVar.EndLocation = t.EndLocation;
                                c.CatchParameter = catchVar;
                            }
                        }

                        if(!IsEOF)
                            c.ScopedStatement = Statement(Scope: Scope, Parent: c);
                        c.EndLocation = t.EndLocation;

                        catches.Add(c);
                    }

                    if (catches.Count > 0)
                        ts.Catches = catches.ToArray();

                    if (laKind == (Finally))
                    {
                        Step();

                        var f = new TryStatement.FinallyStatement() { Location = t.Location, Parent = Parent };

                        f.ScopedStatement = Statement();
                        f.EndLocation = t.EndLocation;

                        ts.FinallyStmt = f;
                    }

                    ts.EndLocation = t.EndLocation;
                    return ts;
                case Throw:
                    Step();
                    var ths = new ThrowStatement() { Location = t.Location, Parent = Parent };

                    ths.ThrowExpression = Expression(Scope);
                    Expect(Semicolon);
                    ths.EndLocation = t.EndLocation;

                    return ths;
                case DTokens.Scope:
                    Step();

                    if (laKind == OpenParenthesis)
                    {
                        var s = new ScopeGuardStatement() {
                            Location = t.Location,
                            Parent = Parent
                        };

                        Step();

                        if (Expect(Identifier) && t.Value != null) // exit, failure, success
                            s.GuardedScope = t.Value.ToLower();
                        else if (IsEOF)
                            s.GuardedScope = DTokens.IncompleteId;

                        Expect(CloseParenthesis);

                        s.ScopedStatement = Statement(Scope: Scope, Parent: s);

                        s.EndLocation = t.EndLocation;
                        return s;
                    }
                    else
                        PushAttribute(new Modifier(DTokens.Scope), false);
                    goto default;
                case Asm:
                    return ParseAsmStatement(Scope, Parent);
                case Pragma:
                    var ps = new PragmaStatement { Location = la.Location };

                    ps.Pragma = _Pragma();
                    ps.Parent = Parent;

                    ps.ScopedStatement = Statement(Scope: Scope, Parent: ps);
                    ps.EndLocation = t.EndLocation;
                    return ps;
                case Mixin:
                    if (Peek(1).Kind == OpenParenthesis)
                    {
                        OverPeekBrackets(OpenParenthesis);
                        if (Lexer.CurrentPeekToken.Kind != Semicolon)
                            return ExpressionStatement(Scope, Parent);
                        return MixinDeclaration(Scope, Parent);
                    }
                    else
                    {
                        var tmx = TemplateMixin(Scope, Parent);
                        if (tmx.MixinId == null)
                            return tmx;
                        else
                            return new DeclarationStatement { Declarations = new[] { new NamedTemplateMixinNode(tmx) }, Parent = Parent };
                    }
                case Assert:
                    var isStatic = laKind == Static;
                    AssertStatement asS;
                    if (isStatic)
                    {
                        Step();
                        asS = new StaticAssertStatement { Location = la.Location, Parent = Parent };
                    }
                    else
                        asS = new AssertStatement() { Location = la.Location, Parent = Parent };

                    Step();

                    if (Expect(OpenParenthesis))
                    {
                        asS.AssertedExpression = Expression(Scope);
                        Expect(CloseParenthesis);
                        Expect(Semicolon);
                    }
                    asS.EndLocation = t.EndLocation;

                    return asS;
                case Volatile:
                    Step();
                    var vs = new VolatileStatement() { Location = t.Location, Parent = Parent };

                    vs.ScopedStatement = Statement(Scope: Scope, Parent: vs);
                    vs.EndLocation = t.EndLocation;

                    return vs;
                case Import:
                    if(laKind == Static)
                        Step(); // Will be handled in ImportDeclaration

                    return ImportDeclaration(Scope);
                case Enum:
                case Alias:
                case Typedef:
                    var ds = new DeclarationStatement() { Location = la.Location, Parent = Parent, ParentNode = Scope };
                    ds.Declarations = Declaration(Scope);

                    ds.EndLocation = t.EndLocation;
                    return ds;
                default:
                    if (IsClassLike(laKind) || (IsBasicType(laKind) && Lexer.CurrentPeekToken.Kind != Dot) || IsModifier(laKind))
                        goto case Typedef;
                    if (IsAssignExpression())
                        return ExpressionStatement(Scope, Parent);
                    goto case Typedef;

            }
        }
コード例 #25
0
ファイル: MethodCall.cs プロジェクト: smx-smx/ValaSharp
        public override bool check(CodeContext context)
        {
            if (is_checked)
            {
                return(!error);
            }

            is_checked = true;

            if (!call.check(context))
            {
                /* if method resolving didn't succeed, skip this check */
                error = true;
                return(false);
            }

            // type of target object
            DataType target_object_type = null;

            List <DataType> method_type_args = null;

            if (call.value_type is DelegateType)
            {
                // delegate invocation, resolve generic types relative to delegate
                target_object_type = call.value_type;
            }
            else if (call is MemberAccess)
            {
                var ma = (MemberAccess)call;
                if (ma.prototype_access)
                {
                    error = true;
                    Report.error(source_reference, "Access to instance member `%s' denied".printf(call.symbol_reference.get_full_name()));
                    return(false);
                }

                method_type_args = ma.get_type_arguments();

                if (ma.inner != null)
                {
                    target_object_type = ma.inner.value_type;

                    // foo is relevant instance in foo.bar.connect (on_bar)
                    if (ma.inner.symbol_reference is Signal)
                    {
                        var sig = ma.inner as MemberAccess;
                        if (sig != null)
                        {
                            target_object_type = sig.inner.value_type;
                        }
                    }

                    // foo is relevant instance in foo.bar.begin (bar_ready) and foo.bar.end (result)
                    var m = ma.symbol_reference as Method;
                    if (m != null && m.coroutine)
                    {
                        // begin or end call of async method
                        if (ma.member_name == "begin" || ma.member_name == "end")
                        {
                            var method_access = ma.inner as MemberAccess;
                            if (method_access != null && method_access.inner != null)
                            {
                                target_object_type = method_access.inner.value_type;
                            }
                            else
                            {
                                // static method
                                target_object_type = null;
                            }
                        }
                    }
                }

                if (ma.symbol_reference != null && ma.symbol_reference.get_attribute("Assert") != null)
                {
                    this.is_assert = true;

                    var _args = get_argument_list();
                    if (_args.Count == 1)
                    {
                        this.source_reference = _args[0].source_reference;
                    }
                }
            }

            var mtype           = call.value_type;
            var gobject_chainup = call.symbol_reference == context.analyzer.object_type;

            is_chainup = gobject_chainup;

            if (!gobject_chainup)
            {
                var expr = call;
                var ma   = expr as MemberAccess;
                if (ma != null && ma.symbol_reference is CreationMethod)
                {
                    expr = ma.inner;
                    ma   = expr as MemberAccess;
                }
                if (ma != null && ma.member_name == "this")
                {
                    // this[.with_foo] ()
                    is_chainup = true;
                }
                else if (expr is BaseAccess)
                {
                    // base[.with_foo] ()
                    is_chainup = true;
                }
            }

            CreationMethod base_cm = null;

            if (is_chainup)
            {
                var cm = context.analyzer.find_current_method() as CreationMethod;
                if (cm == null)
                {
                    error = true;
                    Report.error(source_reference, "invocation not supported in this context");
                    return(false);
                }
                else if (cm.chain_up)
                {
                    error = true;
                    Report.error(source_reference, "Multiple constructor calls in the same constructor are not permitted");
                    return(false);
                }
                cm.chain_up = true;

                if (mtype is ObjectType)
                {
                    var otype = (ObjectType)mtype;
                    var cl    = (Class)otype.type_symbol;
                    base_cm = cl.default_construction_method;
                    if (base_cm == null)
                    {
                        error = true;
                        Report.error(source_reference, "chain up to `%s' not supported".printf(cl.get_full_name()));
                        return(false);
                    }
                    else if (!base_cm.has_construct_function)
                    {
                        error = true;
                        Report.error(source_reference, "chain up to `%s' not supported".printf(base_cm.get_full_name()));
                        return(false);
                    }
                }
                else if (call.symbol_reference is CreationMethod && call.symbol_reference.parent_symbol is Class)
                {
                    base_cm = (CreationMethod)call.symbol_reference;
                    if (!base_cm.has_construct_function)
                    {
                        error = true;
                        Report.error(source_reference, "chain up to `%s' not supported".printf(base_cm.get_full_name()));
                        return(false);
                    }
                }
                else if (gobject_chainup)
                {
                    var cl = cm.parent_symbol as Class;
                    if (cl == null || !cl.is_subtype_of(context.analyzer.object_type))
                    {
                        error = true;
                        Report.error(source_reference, "chain up to `GLib.Object' not supported");
                        return(false);
                    }
                    call.value_type = new ObjectType(context.analyzer.object_type);
                    mtype           = call.value_type;
                }
            }

            // check for struct construction
            if (call is MemberAccess &&
                ((call.symbol_reference is CreationMethod &&
                  call.symbol_reference.parent_symbol is Struct) ||
                 call.symbol_reference is Struct))
            {
                var st = call.symbol_reference as Struct;
                if (st != null && st.default_construction_method == null && (st.is_boolean_type() || st.is_integer_type() || st.is_floating_type()))
                {
                    error = true;
                    Report.error(source_reference, "invocation not supported in this context");
                    return(false);
                }

                var struct_creation_expression = new ObjectCreationExpression((MemberAccess)call, source_reference);
                struct_creation_expression.struct_creation = true;
                foreach (Expression arg in get_argument_list())
                {
                    struct_creation_expression.add_argument(arg);
                }
                struct_creation_expression.target_type = target_type;
                context.analyzer.replaced_nodes.Add(this);
                parent_node.replace_expression(this, struct_creation_expression);
                struct_creation_expression.check(context);
                return(true);
            }
            else if (!is_chainup && call is MemberAccess && call.symbol_reference is CreationMethod)
            {
                error = true;
                Report.error(source_reference, "use `new' operator to create new objects");
                return(false);
            }

            if (!is_chainup && mtype is ObjectType)
            {
                // prevent funny stuff like (new Object ()) ()
                error = true;
                Report.error(source_reference, "invocation not supported in this context");
                return(false);
            }
            else if (mtype != null && mtype.is_invokable())
            {
                // call ok, expression is invokable
            }
            else if (call.symbol_reference is Class)
            {
                error = true;
                Report.error(source_reference, "use `new' operator to create new objects");
                return(false);
            }
            else
            {
                error = true;
                Report.error(source_reference, "invocation not supported in this context");
                return(false);
            }

            var ret_type = mtype.get_return_type();
            var _params  = mtype.get_parameters();

            if (mtype is MethodType)
            {
                var m = ((MethodType)mtype).method_symbol;
                if (m != null && m.coroutine)
                {
                    var ma = (MemberAccess)call;
                    if (!is_yield_expression)
                    {
                        // begin or end call of async method
                        if (ma.member_name != "end")
                        {
                            // begin (possibly implicit)
                            if (ma.member_name != "begin")
                            {
                                Report.deprecated(ma.source_reference, "implicit .begin is deprecated");
                            }
                            _params  = m.get_async_begin_parameters();
                            ret_type = new VoidType();
                        }
                        else
                        {
                            // end
                            _params = m.get_async_end_parameters();
                        }
                    }
                    else if (ma.member_name == "begin" || ma.member_name == "end")
                    {
                        error = true;
                        Report.error(ma.source_reference, "use of `%s' not allowed in yield statement".printf(ma.member_name));
                    }
                }

                if (m != null)
                {
                    var ma            = (MemberAccess)call;
                    int n_type_params = m.get_type_parameters().Count;
                    int n_type_args   = ma.get_type_arguments().Count;
                    if (n_type_args > 0 && n_type_args < n_type_params)
                    {
                        error = true;
                        Report.error(ma.source_reference, "too few type arguments");
                        return(false);
                    }
                    else if (n_type_args > 0 && n_type_args > n_type_params)
                    {
                        error = true;
                        Report.error(ma.source_reference, "too many type arguments");
                        return(false);
                    }
                }
            }

            // FIXME partial code duplication in ObjectCreationExpression.check

            Expression last_arg = null;

            var args = get_argument_list();
            IEnumerator <Expression> arg_it = args.GetEnumerator();

            foreach (Parameter param in _params)
            {
                if (param.ellipsis)
                {
                    break;
                }

                if (param.params_array)
                {
                    var array_type = (ArrayType)param.variable_type;
                    while (arg_it.MoveNext())
                    {
                        Expression arg = arg_it.Current;

                        /* store expected type for callback parameters */
                        arg.target_type             = array_type.element_type;
                        arg.target_type.value_owned = array_type.value_owned;
                    }
                    break;
                }

                if (arg_it.MoveNext())
                {
                    Expression arg = arg_it.Current;

                    /* store expected type for callback parameters */
                    arg.formal_target_type = param.variable_type;
                    arg.target_type        = arg.formal_target_type.get_actual_type(target_object_type, method_type_args, this);

                    last_arg = arg;
                }
            }

            // concatenate stringified arguments for methods with attribute [Print]
            if (mtype is MethodType && ((MethodType)mtype).method_symbol.get_attribute("Print") != null)
            {
                var template = new Template(source_reference);
                foreach (Expression arg in argument_list)
                {
                    arg.parent_node = null;
                    template.add_expression(arg);
                }
                argument_list.Clear();
                add_argument(template);
            }

            // printf arguments
            if (mtype is MethodType && ((MethodType)mtype).method_symbol.printf_format)
            {
                StringLiteral format_literal = null;
                if (last_arg != null)
                {
                    // use last argument as format string
                    format_literal = StringLiteral.get_format_literal(last_arg);
                    if (format_literal == null && args.Count == _params.Count - 1)
                    {
                        // insert "%s" to avoid issues with embedded %
                        format_literal             = new StringLiteral("\"%s\"");
                        format_literal.target_type = context.analyzer.string_type.copy();
                        argument_list.Insert(args.Count - 1, format_literal);

                        // recreate iterator and skip to right position
                        arg_it = argument_list.GetEnumerator();
                        foreach (Parameter param in _params)
                        {
                            if (param.ellipsis)
                            {
                                break;
                            }
                            arg_it.MoveNext();
                        }
                    }
                }
                else
                {
                    // use instance as format string for string.printf (...)
                    var ma = call as MemberAccess;
                    if (ma != null)
                    {
                        format_literal = StringLiteral.get_format_literal(ma.inner);
                    }
                }
                if (format_literal != null)
                {
                    string format = format_literal.eval();
                    if (!context.analyzer.check_print_format(format, arg_it, source_reference))
                    {
                        return(false);
                    }
                }
            }

            foreach (Expression arg in get_argument_list().ToList())
            {
                arg.check(context);
            }

            if (ret_type is VoidType)
            {
                // void return type
                if (!(parent_node is ExpressionStatement) &&
                    !(parent_node is ForStatement) &&
                    !(parent_node is YieldStatement))
                {
                    // A void method invocation can be in the initializer or
                    // iterator of a for statement
                    error = true;
                    Report.error(source_reference, "invocation of void method not allowed as expression");
                    return(false);
                }
            }

            formal_value_type = ret_type.copy();
            value_type        = formal_value_type.get_actual_type(target_object_type, method_type_args, this);

            bool may_throw = false;

            if (mtype is MethodType)
            {
                var m = ((MethodType)mtype).method_symbol;
                if (is_yield_expression)
                {
                    if (!m.coroutine)
                    {
                        error = true;
                        Report.error(source_reference, "yield expression requires async method");
                    }
                    if (context.analyzer.current_method == null || !context.analyzer.current_method.coroutine)
                    {
                        error = true;
                        Report.error(source_reference, "yield expression not available outside async method");
                    }
                }
                if (m != null && m.coroutine && !is_yield_expression && ((MemberAccess)call).member_name != "end")
                {
                    // .begin call of async method, no error can happen here
                }
                else
                {
                    foreach (DataType error_type in m.get_error_types())
                    {
                        may_throw = true;

                        // ensure we can trace back which expression may throw errors of this type
                        var call_error_type = error_type.copy();
                        call_error_type.source_reference = source_reference;

                        add_error_type(call_error_type);
                    }
                }
                if (m.returns_floating_reference)
                {
                    value_type.floating_reference = true;
                }
                if (m.returns_modified_pointer)
                {
                    ((MemberAccess)call).inner.lvalue = true;
                }

                var dynamic_sig = m.parent_symbol as DynamicSignal;
                if (dynamic_sig != null && dynamic_sig.handler != null)
                {
                    dynamic_sig.return_type = dynamic_sig.handler.value_type.get_return_type().copy();
                    bool first = true;
                    foreach (Parameter param in dynamic_sig.handler.value_type.get_parameters())
                    {
                        if (first)
                        {
                            // skip sender parameter
                            first = false;
                        }
                        else
                        {
                            dynamic_sig.add_parameter(param.copy());
                        }
                    }
                    dynamic_sig.handler.target_type = new DelegateType(dynamic_sig.get_delegate(new ObjectType((ObjectTypeSymbol)dynamic_sig.parent_symbol), this));
                }

                if (m != null && m.get_type_parameters().Count > 0)
                {
                    var ma = (MemberAccess)call;
                    if (ma.get_type_arguments().Count == 0)
                    {
                        // infer type arguments
                        foreach (var type_param in m.get_type_parameters())
                        {
                            DataType type_arg = null;

                            // infer type arguments from arguments
                            arg_it = args.GetEnumerator();
                            foreach (Parameter param in _params)
                            {
                                if (param.ellipsis || param.params_array)
                                {
                                    break;
                                }

                                if (arg_it.MoveNext())
                                {
                                    Expression arg = arg_it.Current;

                                    type_arg = param.variable_type.infer_type_argument(type_param, arg.value_type);
                                    if (type_arg != null)
                                    {
                                        break;
                                    }

                                    arg.target_type = arg.formal_target_type.get_actual_type(target_object_type, method_type_args, this);
                                }
                            }

                            // infer type arguments from expected return type
                            if (type_arg == null && target_type != null)
                            {
                                type_arg = m.return_type.infer_type_argument(type_param, target_type);
                            }

                            if (type_arg == null)
                            {
                                error = true;
                                Report.error(ma.source_reference, "cannot infer generic type argument for type parameter `%s'".printf(type_param.get_full_name()));
                                return(false);
                            }

                            ma.add_type_argument(type_arg);
                        }

                        // recalculate argument target types with new information
                        arg_it = args.GetEnumerator();
                        foreach (Parameter param in _params)
                        {
                            if (param.ellipsis || param.params_array)
                            {
                                break;
                            }

                            if (arg_it.MoveNext())
                            {
                                Expression arg = arg_it.Current;

                                arg.target_type = arg.formal_target_type.get_actual_type(target_object_type, method_type_args, this);
                            }
                        }

                        // recalculate return value type with new information
                        value_type = formal_value_type.get_actual_type(target_object_type, method_type_args, this);
                    }
                }
                // replace method-type if needed for proper argument-check in semantic-analyser
                if (m != null && m.coroutine)
                {
                    var ma = (MemberAccess)call;
                    if (ma.member_name == "end")
                    {
                        mtype = new MethodType(m.get_end_method());
                    }
                }
            }
            else if (mtype is ObjectType)
            {
                // constructor
                var cl = (Class)((ObjectType)mtype).type_symbol;
                var m  = cl.default_construction_method;
                foreach (DataType error_type in m.get_error_types())
                {
                    may_throw = true;

                    // ensure we can trace back which expression may throw errors of this type
                    var call_error_type = error_type.copy();
                    call_error_type.source_reference = source_reference;

                    add_error_type(call_error_type);
                }
            }
            else if (mtype is DelegateType)
            {
                var d = ((DelegateType)mtype).delegate_symbol;
                foreach (DataType error_type in d.get_error_types())
                {
                    may_throw = true;

                    // ensure we can trace back which expression may throw errors of this type
                    var call_error_type = error_type.copy();
                    call_error_type.source_reference = source_reference;

                    add_error_type(call_error_type);
                }
            }

            if (!context.analyzer.check_arguments(this, mtype, _params, get_argument_list()))
            {
                error = true;
                return(false);
            }

            /* Check for constructv chain up */
            if (base_cm != null && base_cm.is_variadic() && args.Count == base_cm.get_parameters().Count)
            {
                var this_last_arg = args[args.Count - 1];
                if (this_last_arg.value_type is StructValueType && this_last_arg.value_type.data_type == context.analyzer.va_list_type.data_type)
                {
                    is_constructv_chainup = true;
                }
            }

            if (may_throw)
            {
                if (parent_node is LocalVariable || parent_node is ExpressionStatement)
                {
                    // simple statements, no side effects after method call
                }
                else if (!(context.analyzer.current_symbol is Block))
                {
                    // can't handle errors in field initializers
                    Report.error(source_reference, "Field initializers must not throw errors");
                }
                else
                {
                    // store parent_node as we need to replace the expression in the old parent node later on
                    var old_parent_node = parent_node;

                    var local = new LocalVariable(value_type.copy(), get_temp_name(), null, source_reference);
                    var decl  = new DeclarationStatement(local, source_reference);

                    insert_statement(context.analyzer.insert_block, decl);

                    var temp_access = SemanticAnalyzer.create_temp_access(local, target_type);

                    // don't set initializer earlier as this changes parent_node and parent_statement
                    local.initializer = this;
                    decl.check(context);


                    // move temp variable to insert block to ensure the
                    // variable is in the same block as the declaration
                    // otherwise there will be scoping issues in the generated code
                    var block = (Block)context.analyzer.current_symbol;
                    block.remove_local_variable(local);
                    context.analyzer.insert_block.add_local_variable(local);

                    old_parent_node.replace_expression(this, temp_access);
                    temp_access.check(context);
                }
            }

            return(!error);
        }
コード例 #26
0
 public override void OnDeclarationStatement(DeclarationStatement node)
 {
     DeclarationFound(node.Declaration.Name, node.Declaration.Type, node.Initializer, node.LexicalInfo);
 }
コード例 #27
0
 public override bool EnterDeclarationStatement(DeclarationStatement node)
 {
     WriteIndented();
     return(true);
 }
コード例 #28
0
 public override void OnDeclarationStatement(DeclarationStatement node)
 {
     declarations.Add(node);
     base.OnDeclarationStatement(node);
 }
コード例 #29
0
 public void Visit(DeclarationStatement declarationStatement)
 {
 }
コード例 #30
0
        public override bool check(CodeContext context)
        {
            if (is_checked)
            {
                return(!error);
            }

            is_checked = true;

            if (member_name != null)
            {
                if (!member_name.check(context))
                {
                    error = true;
                    return(false);
                }
            }

            TypeSymbol type = null;

            if (type_reference == null)
            {
                if (member_name == null)
                {
                    error = true;
                    Report.error(source_reference, "Incomplete object creation expression");
                    return(false);
                }

                if (member_name.symbol_reference == null)
                {
                    error = true;
                    return(false);
                }

                var constructor_sym = member_name.symbol_reference;
                var type_sym        = member_name.symbol_reference;

                var type_args = member_name.get_type_arguments();

                if (constructor_sym is Method)
                {
                    type_sym = constructor_sym.parent_symbol;

                    var constructor = (Method)constructor_sym;
                    if (!(constructor_sym is CreationMethod))
                    {
                        error = true;
                        Report.error(source_reference, "`%s' is not a creation method".printf(constructor.get_full_name()));
                        return(false);
                    }

                    symbol_reference = constructor;

                    // inner expression can also be base access when chaining constructors
                    var ma = member_name.inner as MemberAccess;
                    if (ma != null)
                    {
                        type_args = ma.get_type_arguments();
                    }
                }

                if (type_sym is Class)
                {
                    type = (TypeSymbol)type_sym;
                    if (((Class)type).is_error_base)
                    {
                        type_reference = new ErrorType(null, null, source_reference);
                    }
                    else
                    {
                        type_reference = new ObjectType((Class)type);
                    }
                }
                else if (type_sym is Struct)
                {
                    type           = (TypeSymbol)type_sym;
                    type_reference = new StructValueType((Struct)type);
                }
                else if (type_sym is ErrorCode)
                {
                    type_reference   = new ErrorType((ErrorDomain)type_sym.parent_symbol, (ErrorCode)type_sym, source_reference);
                    symbol_reference = type_sym;
                }
                else
                {
                    error = true;
                    Report.error(source_reference, "`%s' is not a class, struct, or error code".printf(type_sym.get_full_name()));
                    return(false);
                }

                foreach (DataType type_arg in type_args)
                {
                    type_reference.add_type_argument(type_arg);
                }
            }
            else
            {
                type = type_reference.data_type;
            }

            value_type             = type_reference.copy();
            value_type.value_owned = true;

            bool may_throw = false;

            int given_num_type_args    = type_reference.get_type_arguments().Count;
            int expected_num_type_args = 0;

            if (type is Class)
            {
                var cl = (Class)type;

                expected_num_type_args = cl.get_type_parameters().Count;

                if (struct_creation)
                {
                    error = true;
                    Report.error(source_reference, "syntax error, use `new' to create new objects");
                    return(false);
                }

                if (cl.is_abstract)
                {
                    value_type = null;
                    error      = true;
                    Report.error(source_reference, "Can't create instance of abstract class `%s'".printf(cl.get_full_name()));
                    return(false);
                }

                if (symbol_reference == null)
                {
                    symbol_reference = cl.default_construction_method;

                    if (symbol_reference == null)
                    {
                        error = true;
                        Report.error(source_reference, "`%s' does not have a default constructor".printf(cl.get_full_name()));
                        return(false);
                    }

                    // track usage for flow analyzer
                    symbol_reference.used = true;
                    symbol_reference.version.check(source_reference);
                }

                if (symbol_reference != null &&
                    (symbol_reference.access == SymbolAccessibility.PRIVATE || symbol_reference.access == SymbolAccessibility.PROTECTED))
                {
                    bool in_target_type = false;
                    for (Symbol this_symbol = context.analyzer.current_symbol; this_symbol != null; this_symbol = this_symbol.parent_symbol)
                    {
                        if (this_symbol == cl)
                        {
                            in_target_type = true;
                            break;
                        }
                    }

                    if (!in_target_type)
                    {
                        error = true;
                        Report.error(source_reference, "Access to non-public constructor `%s' denied".printf(symbol_reference.get_full_name()));
                        return(false);
                    }
                }

                while (cl != null)
                {
                    // FIXME: use target values in the codegen
                    if (cl.get_attribute_string("CCode", "ref_sink_function") != null)
                    {
                        value_type.floating_reference = true;
                        break;
                    }

                    cl = cl.base_class;
                }
            }
            else if (type is Struct)
            {
                var st = (Struct)type;

                expected_num_type_args = st.get_type_parameters().Count;

                if (!struct_creation && !context.deprecated)
                {
                    Report.warning(source_reference, "deprecated syntax, don't use `new' to initialize structs");
                }

                if (symbol_reference == null)
                {
                    symbol_reference = st.default_construction_method;
                }

                if (st.is_simple_type() && symbol_reference == null && object_initializer.Count == 0)
                {
                    error = true;
                    Report.error(source_reference, "`%s' does not have a default constructor".printf(st.get_full_name()));
                    return(false);
                }
            }

            if (expected_num_type_args > given_num_type_args)
            {
                error = true;
                Report.error(source_reference, "too few type arguments");
                return(false);
            }
            else if (expected_num_type_args < given_num_type_args)
            {
                error = true;
                Report.error(source_reference, "too many type arguments");
                return(false);
            }

            if (symbol_reference == null && get_argument_list().Count != 0)
            {
                value_type = null;
                error      = true;
                Report.error(source_reference, "No arguments allowed when constructing type `%s'".printf(type.get_full_name()));
                return(false);
            }

            if (symbol_reference is Method)
            {
                var m = (Method)symbol_reference;

                if (is_yield_expression)
                {
                    if (!m.coroutine)
                    {
                        error = true;
                        Report.error(source_reference, "yield expression requires async method");
                    }
                    if (context.analyzer.current_method == null || !context.analyzer.current_method.coroutine)
                    {
                        error = true;
                        Report.error(source_reference, "yield expression not available outside async method");
                    }
                }

                // FIXME partial code duplication of MethodCall.check

                Expression last_arg = null;

                var args = get_argument_list();
                IEnumerator <Expression> arg_it = args.GetEnumerator();
                foreach (Parameter param in m.get_parameters())
                {
                    if (param.ellipsis)
                    {
                        break;
                    }

                    if (arg_it.MoveNext())
                    {
                        Expression arg = arg_it.Current;

                        /* store expected type for callback parameters */
                        arg.formal_target_type = param.variable_type;
                        arg.target_type        = arg.formal_target_type.get_actual_type(value_type, null, this);

                        last_arg = arg;
                    }
                }

                // printf arguments
                if (m.printf_format)
                {
                    StringLiteral format_literal = null;
                    if (last_arg != null)
                    {
                        // use last argument as format string
                        format_literal = StringLiteral.get_format_literal(last_arg);
                        if (format_literal == null && args.Count == m.get_parameters().Count - 1)
                        {
                            // insert "%s" to avoid issues with embedded %
                            format_literal             = new StringLiteral("\"%s\"");
                            format_literal.target_type = context.analyzer.string_type.copy();
                            argument_list.Insert(args.Count - 1, format_literal);

                            // recreate iterator and skip to right position
                            arg_it = argument_list.GetEnumerator();
                            foreach (Parameter param in m.get_parameters())
                            {
                                if (param.ellipsis)
                                {
                                    break;
                                }
                                arg_it.MoveNext();
                            }
                        }
                    }
                    if (format_literal != null)
                    {
                        string format = format_literal.eval();
                        if (!context.analyzer.check_print_format(format, arg_it, source_reference))
                        {
                            return(false);
                        }
                    }
                }

                foreach (Expression arg in args.ToList())
                {
                    arg.check(context);
                }

                context.analyzer.check_arguments(this, new MethodType(m), m.get_parameters(), args);

                foreach (DataType error_type in m.get_error_types())
                {
                    may_throw = true;

                    // ensure we can trace back which expression may throw errors of this type
                    var call_error_type = error_type.copy();
                    call_error_type.source_reference = source_reference;

                    add_error_type(call_error_type);
                }
            }
            else if (type_reference is ErrorType)
            {
                if (type_reference != null)
                {
                    type_reference.check(context);
                }

                if (member_name != null)
                {
                    member_name.check(context);
                }

                foreach (Expression arg in argument_list)
                {
                    arg.check(context);
                }

                foreach (MemberInitializer init in object_initializer)
                {
                    init.check(context);
                }

                if (get_argument_list().Count == 0)
                {
                    error = true;
                    Report.error(source_reference, "Too few arguments, errors need at least 1 argument");
                }
                else
                {
                    IEnumerator <Expression> arg_it = get_argument_list().GetEnumerator();
                    arg_it.MoveNext();
                    var ex = arg_it.Current;
                    if (ex.value_type == null || !ex.value_type.compatible(context.analyzer.string_type))
                    {
                        error = true;
                        Report.error(source_reference, "Invalid type for argument 1");
                    }

                    var format_literal = StringLiteral.get_format_literal(ex);
                    if (format_literal != null)
                    {
                        var format = format_literal.eval();
                        if (!context.analyzer.check_print_format(format, arg_it, source_reference))
                        {
                            error = true;
                            return(false);
                        }
                    }

                    arg_it = get_argument_list().GetEnumerator();
                    arg_it.MoveNext();
                    if (!context.analyzer.check_variadic_arguments(arg_it, 1, source_reference))
                    {
                        error = true;
                        return(false);
                    }
                }
            }

            foreach (MemberInitializer init in get_object_initializer())
            {
                context.analyzer.visit_member_initializer(init, type_reference);
            }

            if (may_throw)
            {
                if (parent_node is LocalVariable || parent_node is ExpressionStatement)
                {
                    // simple statements, no side effects after method call
                }
                else if (!(context.analyzer.current_symbol is Block))
                {
                    // can't handle errors in field initializers
                    Report.error(source_reference, "Field initializers must not throw errors");
                }
                else
                {
                    // store parent_node as we need to replace the expression in the old parent node later on
                    var old_parent_node = parent_node;

                    var local = new LocalVariable(value_type.copy(), get_temp_name(), null, source_reference);
                    var decl  = new DeclarationStatement(local, source_reference);

                    insert_statement(context.analyzer.insert_block, decl);

                    var temp_access = SemanticAnalyzer.create_temp_access(local, target_type);
                    // don't set initializer earlier as this changes parent_node and parent_statement
                    local.initializer = this;
                    decl.check(context);


                    // move temp variable to insert block to ensure the
                    // variable is in the same block as the declaration
                    // otherwise there will be scoping issues in the generated code
                    var block = (Block)context.analyzer.current_symbol;
                    block.remove_local_variable(local);
                    context.analyzer.insert_block.add_local_variable(local);

                    old_parent_node.replace_expression(this, temp_access);
                    temp_access.check(context);
                }
            }

            return(!error);
        }
コード例 #31
0
ファイル: Parser_Impl.cs プロジェクト: EnergonV/D_Parser
        public IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null)
        {
            if (EmptyAllowed && laKind == Semicolon)
            {
                LastParsedObject = null;
                Step();
                return null;
            }

            if (BlocksAllowed && laKind == OpenCurlyBrace)
                return BlockStatement(Scope,Parent);

            #region LabeledStatement (loc:... goto loc;)
            if (laKind == Identifier && Lexer.CurrentPeekToken.Kind == Colon)
            {
                Step();

                var ret = new LabeledStatement() { Location = t.Location, Identifier = t.Value, Parent = Parent };
                LastParsedObject = null;
                Step();
                ret.EndLocation = t.EndLocation;

                return ret;
            }
            #endregion

            #region IfStatement
            else if (laKind == (If))
            {
                Step();

                var dbs = new IfStatement{	Location = t.Location, Parent = Parent	};

                LastParsedObject = dbs;
                Expect(OpenParenthesis);

                // IfCondition
                IfCondition(dbs);

                // ThenStatement
                if(Expect(CloseParenthesis))
                    dbs.ThenStatement = Statement(Scope: Scope, Parent: dbs);

                // ElseStatement
                if (laKind == (Else))
                {
                    Step();
                    dbs.ElseStatement = Statement(Scope: Scope, Parent: dbs);
                }

                if(t != null)
                    dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region Conditions
            else if ((laKind == Static && Lexer.CurrentPeekToken.Kind == If) || laKind == Version || laKind == Debug)
                return StmtCondition(Parent, Scope);
            #endregion

            #region WhileStatement
            else if (laKind == While)
            {
                Step();

                var dbs = new WhileStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = dbs;
                Expect(OpenParenthesis);
                dbs.Condition = Expression(Scope);
                Expect(CloseParenthesis);

                if(!IsEOF)
                {
                    dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);
                    dbs.EndLocation = t.EndLocation;
                }

                return dbs;
            }
            #endregion

            #region DoStatement
            else if (laKind == (Do))
            {
                Step();

                var dbs = new WhileStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = dbs;
                if(!IsEOF)
                    dbs.ScopedStatement = Statement(true, false, Scope, dbs);

                if(Expect(While) && Expect(OpenParenthesis))
                {
                    dbs.Condition = Expression(Scope);
                    Expect(CloseParenthesis);
                    if (Expect(Semicolon))
                        LastParsedObject = null;

                    dbs.EndLocation = t.EndLocation;
                }

                return dbs;
            }
            #endregion

            #region ForStatement
            else if (laKind == (For))
                return ForStatement(Scope, Parent);
            #endregion

            #region ForeachStatement
            else if (laKind == Foreach || laKind == Foreach_Reverse)
                return ForeachStatement(Scope, Parent);
            #endregion

            #region [Final] SwitchStatement
            else if ((laKind == (Final) && Lexer.CurrentPeekToken.Kind == (Switch)) || laKind == (Switch))
            {
                var dbs = new SwitchStatement { Location = la.Location, Parent = Parent };
                LastParsedObject = dbs;
                if (laKind == (Final))
                {
                    dbs.IsFinal = true;
                    Step();
                }
                Step();
                Expect(OpenParenthesis);
                dbs.SwitchExpression = Expression(Scope);
                Expect(CloseParenthesis);

                if(!IsEOF)
                    dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);
                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region CaseStatement
            else if (laKind == (Case))
            {
                Step();

                var dbs = new SwitchStatement.CaseStatement() { Location = la.Location, Parent = Parent };
                LastParsedObject = dbs;
                dbs.ArgumentList = Expression(Scope);

                if (Expect(Colon))
                    LastParsedObject = null;

                // CaseRangeStatement
                if (laKind == DoubleDot)
                {
                    Step();
                    Expect(Case);
                    dbs.LastExpression = AssignExpression();
                    if (Expect(Colon))
                        LastParsedObject = null;
                }

                var sl = new List<IStatement>();

                while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF)
                {
                    var stmt = Statement(Scope: Scope, Parent: dbs);

                    if (stmt != null)
                    {
                        stmt.Parent = dbs;
                        sl.Add(stmt);
                    }
                }

                dbs.ScopeStatementList = sl.ToArray();
                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region Default
            else if (laKind == (Default))
            {
                Step();

                var dbs = new SwitchStatement.DefaultStatement()
                {
                    Location = la.Location,
                    Parent = Parent
                };
                LastParsedObject = dbs;

                Expect(Colon);

                var sl = new List<IStatement>();

                while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF)
                {
                    var stmt = Statement(Scope: Scope, Parent: dbs);

                    if (stmt != null)
                    {
                        stmt.Parent = dbs;
                        sl.Add(stmt);
                    }
                }

                dbs.ScopeStatementList = sl.ToArray();
                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region Continue | Break
            else if (laKind == (Continue))
            {
                Step();
                var s = new ContinueStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;
                if (laKind == (Identifier))
                {
                    Step();
                    s.Identifier = t.Value;
                }
                if (Expect(Semicolon))
                    LastParsedObject = null;
                s.EndLocation = t.EndLocation;

                return s;
            }

            else if (laKind == (Break))
            {
                Step();
                var s = new BreakStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;
                if (laKind == (Identifier))
                {
                    Step();
                    s.Identifier = t.Value;
                }
                if (Expect(Semicolon))
                    LastParsedObject = null;
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region Return
            else if (laKind == (Return))
            {
                Step();
                var s = new ReturnStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;
                if (laKind != (Semicolon))
                    s.ReturnExpression = Expression(Scope);

                if (Expect(Semicolon))
                    LastParsedObject = null;
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region Goto
            else if (laKind == (Goto))
            {
                Step();
                var s = new GotoStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;

                if (laKind == (Identifier))
                {
                    Step();
                    s.StmtType = GotoStatement.GotoStmtType.Identifier;
                    s.LabelIdentifier = t.Value;
                }
                else if (laKind == Default)
                {
                    Step();
                    s.StmtType = GotoStatement.GotoStmtType.Default;
                }
                else if (laKind == (Case))
                {
                    Step();
                    s.StmtType = GotoStatement.GotoStmtType.Case;

                    if (laKind != (Semicolon))
                        s.CaseExpression = Expression(Scope);
                }

                if (Expect(Semicolon))
                    LastParsedObject = null;
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region WithStatement
            else if (laKind == (With))
            {
                Step();

                var dbs = new WithStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = dbs;
                if(Expect(OpenParenthesis))
                {
                    // Symbol
                    dbs.WithExpression = Expression(Scope);

                    Expect(CloseParenthesis);

                    if(!IsEOF)
                        dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);
                }
                dbs.EndLocation = t.EndLocation;
                return dbs;
            }
            #endregion

            #region SynchronizedStatement
            else if (laKind == (Synchronized))
            {
                Step();
                var dbs = new SynchronizedStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = dbs;

                if (laKind == (OpenParenthesis))
                {
                    Step();
                    dbs.SyncExpression = Expression(Scope);
                    Expect(CloseParenthesis);
                }

                if(!IsEOF)
                    dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs);
                dbs.EndLocation = t.EndLocation;

                return dbs;
            }
            #endregion

            #region TryStatement
            else if (laKind == (Try))
            {
                Step();

                var s = new TryStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;

                s.ScopedStatement = Statement(Scope: Scope, Parent: s);

                if (!(laKind == (Catch) || laKind == (Finally)))
                    SemErr(Catch, "At least one catch or a finally block expected!");

                var catches = new List<TryStatement.CatchStatement>();
                // Catches
                while (laKind == (Catch))
                {
                    Step();

                    var c = new TryStatement.CatchStatement() { Location = t.Location, Parent = s };
                    LastParsedObject = c;

                    // CatchParameter
                    if (laKind == (OpenParenthesis))
                    {
                        Step();

                        if (laKind == CloseParenthesis || IsEOF)
                        {
                            SemErr(CloseParenthesis, "Catch parameter expected, not ')'");
                            Step();
                        }
                        else
                        {
                            var catchVar = new DVariable { Parent = Scope, Location = t.Location };
                            LastParsedObject = catchVar;
                            Lexer.PushLookAheadBackup();
                            catchVar.Type = BasicType();
                            if (laKind == CloseParenthesis)
                            {
                                Lexer.RestoreLookAheadBackup();
                                catchVar.Type = new IdentifierDeclaration("Exception");
                            }
                            else
                                Lexer.PopLookAheadBackup();

                            if (Expect(Identifier))
                            {
                                catchVar.Name = t.Value;
                                catchVar.NameLocation = t.Location;
                                Expect(CloseParenthesis);
                            }
                            else if(IsEOF)
                                ExpectingNodeName = true;

                            catchVar.EndLocation = t.EndLocation;
                            c.CatchParameter = catchVar;
                        }
                    }

                    if(!IsEOF)
                        c.ScopedStatement = Statement(Scope: Scope, Parent: c);
                    c.EndLocation = t.EndLocation;

                    catches.Add(c);
                }

                if (catches.Count > 0)
                    s.Catches = catches.ToArray();

                if (laKind == (Finally))
                {
                    Step();

                    var f = new TryStatement.FinallyStatement() { Location = t.Location, Parent = Parent };
                    LastParsedObject = f;

                    f.ScopedStatement = Statement();
                    f.EndLocation = t.EndLocation;

                    s.FinallyStmt = f;
                }

                s.EndLocation = t.EndLocation;
                return s;
            }
            #endregion

            #region ThrowStatement
            else if (laKind == (Throw))
            {
                Step();
                var s = new ThrowStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;

                s.ThrowExpression = Expression(Scope);
                Expect(Semicolon);
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region ScopeGuardStatement
            else if (laKind == DTokens.Scope)
            {
                Step();

                if (laKind == OpenParenthesis)
                {
                    var s = new ScopeGuardStatement() { Location = t.Location, Parent = Parent };
                    LastParsedObject = s;

                    Step();

                    if (Expect(Identifier) && t.Value != null) // exit, failure, success
                        s.GuardedScope = t.Value.ToLower();

                    if (Expect(CloseParenthesis))
                        TrackerVariables.ExpectingIdentifier = false;

                    if (!IsEOF)
                        s.ScopedStatement = Statement(Scope: Scope, Parent: s);

                    s.EndLocation = t.EndLocation;
                    return s;
                }
                else
                    PushAttribute(new Modifier(DTokens.Scope), false);
            }
            #endregion

            #region AsmStmt
            else if (laKind == Asm)
                return AsmStatement(Parent);
            #endregion

            #region PragmaStatement
            else if (laKind == (Pragma))
            {
                var s = new PragmaStatement { Location = la.Location };

                s.Pragma = _Pragma();
                s.Parent = Parent;

                s.ScopedStatement = Statement(Scope: Scope, Parent: s);
                s.EndLocation = t.EndLocation;
                return s;
            }
            #endregion

            #region MixinStatement
            else if (laKind == (Mixin))
            {
                if (Peek(1).Kind == OpenParenthesis)
                {
                    OverPeekBrackets(OpenParenthesis);
                    if (Lexer.CurrentPeekToken.Kind != Semicolon)
                        return ExpressionStatement(Scope, Parent);
                    return MixinDeclaration(Scope, Parent);
                }
                else
                {
                    var tmx = TemplateMixin(Scope, Parent);
                    if (tmx.MixinId == null)
                        return tmx;
                    else
                        return new DeclarationStatement { Declarations = new[] { new NamedTemplateMixinNode(tmx) }, Parent = Parent };
                }
            }
            #endregion

            #region (Static) AssertExpression
            else if (laKind == Assert || (laKind == Static && Lexer.CurrentPeekToken.Kind == Assert))
            {
                var isStatic = laKind == Static;
                AssertStatement s;
                if (isStatic)
                {
                    Step();
                    s = new StaticAssertStatement { Location = la.Location, Parent = Parent };
                }
                else
                    s = new AssertStatement() { Location = la.Location, Parent = Parent };
                LastParsedObject = s;

                Step();

                if (Expect(OpenParenthesis))
                {
                    s.AssertedExpression = Expression(Scope);
                    if(Expect(CloseParenthesis) && Expect(Semicolon))
                        LastParsedObject = null;
                }
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region D1: VolatileStatement
            else if (laKind == Volatile)
            {
                Step();
                var s = new VolatileStatement() { Location = t.Location, Parent = Parent };
                LastParsedObject = s;
                s.ScopedStatement = Statement(Scope: Scope, Parent: s);
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            // ImportDeclaration
            else if (laKind == Import || (laKind == Static && Lexer.CurrentPeekToken.Kind == Import))
            {
                if(laKind == Static)
                    Step(); // Will be handled in ImportDeclaration

                return ImportDeclaration(Scope);
            }

            else if (!(ClassLike[laKind] || BasicTypes[laKind] || laKind == Enum || Modifiers[laKind] || IsAtAttribute || laKind == Alias || laKind == Typedef) && IsAssignExpression())
                return ExpressionStatement(Scope, Parent);

            var ds = new DeclarationStatement() { Location = la.Location, Parent = Parent, ParentNode = Scope };
            LastParsedObject = ds;
            ds.Declarations = Declaration(Scope);

            ds.EndLocation = t.EndLocation;
            return ds;
        }
コード例 #32
0
 public override void OnDeclarationStatement(DeclarationStatement node)
 {
     throw new NotImplementedException();
 }
コード例 #33
0
 public void Visit(DeclarationStatement declarationStatement)
 {
 }
コード例 #34
0
 public override void LeaveDeclarationStatement(DeclarationStatement node)
 {
     WriteLine();
 }
コード例 #35
0
        public override bool check(CodeContext context)
        {
            if (is_checked)
            {
                return(!error);
            }

            is_checked = true;

            if (left is ValaTuple && Operator == AssignmentOperator.SIMPLE && parent_node is ExpressionStatement)
            {
                var tuple = (ValaTuple)left;

                var local = new LocalVariable(null, get_temp_name(), right, right.source_reference);
                var decl  = new DeclarationStatement(local, source_reference);
                decl.check(context);
                insert_statement(context.analyzer.insert_block, decl);

                int i = 0;
                ExpressionStatement stmt = null;
                foreach (var expr in tuple.get_expressions())
                {
                    if (stmt != null)
                    {
                        stmt.check(context);
                        insert_statement(context.analyzer.insert_block, stmt);
                    }

                    var temp_access = MemberAccess.simple(local.name, right.source_reference);
                    var ea          = new ElementAccess(temp_access, expr.source_reference);
                    ea.append_index(new IntegerLiteral(i.ToString(), expr.source_reference));
                    var assign = new Assignment(expr, ea, Operator, expr.source_reference);
                    stmt = new ExpressionStatement(assign, expr.source_reference);

                    i++;
                }

                context.analyzer.replaced_nodes.Add(this);
                parent_node.replace_expression(this, stmt.expression);
                return(stmt.expression.check(context));
            }

            left.lvalue = true;

            if (!left.check(context))
            {
                // skip on error in inner expression
                error = true;
                return(false);
            }

            if (left is MemberAccess)
            {
                var ma = (MemberAccess)left;

                if (ma.symbol_reference is Constant)
                {
                    error = true;
                    Report.error(source_reference, "Assignment to constant after initialization");
                    return(false);
                }

                if ((!(ma.symbol_reference is Signal || ma.symbol_reference is DynamicProperty) && ma.value_type == null) ||
                    (ma.inner == null && ma.member_name == "this" && context.analyzer.is_in_instance_method()))
                {
                    error = true;
                    Report.error(source_reference, "unsupported lvalue in assignment");
                    return(false);
                }
                if (ma.prototype_access)
                {
                    error = true;
                    Report.error(source_reference, "Access to instance member `%s' denied".printf(ma.symbol_reference.get_full_name()));
                    return(false);
                }

                if (ma.error || ma.symbol_reference == null)
                {
                    error = true;
                    /* if no symbol found, skip this check */
                    return(false);
                }

                if (ma.symbol_reference is DynamicSignal)
                {
                    // target_type not available for dynamic signals
                    if (!context.deprecated)
                    {
                        Report.warning(source_reference, "deprecated syntax, use `connect' method instead");
                    }
                }
                else if (ma.symbol_reference is Signal)
                {
                    if (!context.deprecated)
                    {
                        Report.warning(source_reference, "deprecated syntax, use `connect' method instead");
                    }
                    var sig = (Signal)ma.symbol_reference;
                    right.target_type = new DelegateType(sig.get_delegate(ma.inner.value_type, this));
                }
                else if (ma.symbol_reference is DynamicProperty)
                {
                    // target_type not available for dynamic properties
                }
                else
                {
                    right.formal_target_type = ma.formal_value_type.copy();
                    right.target_type        = ma.value_type.copy();
                }
            }
            else if (left is ElementAccess)
            {
                var ea = (ElementAccess)left;

                if (ea.container.value_type.data_type == context.analyzer.string_type.data_type)
                {
                    error = true;
                    Report.error(ea.source_reference, "strings are immutable");
                    return(false);
                }
                else if (ea.container is MemberAccess && ea.container.symbol_reference is Signal)
                {
                    var ma  = (MemberAccess)ea.container;
                    var sig = (Signal)ea.container.symbol_reference;
                    right.target_type = new DelegateType(sig.get_delegate(ma.inner.value_type, this));
                }
                else if (ea.container.value_type.get_member("set") is Method)
                {
                    var set_call = new MethodCall(new MemberAccess(ea.container, "set", source_reference), source_reference);
                    foreach (Expression e in ea.get_indices())
                    {
                        set_call.add_argument(e);
                    }
                    set_call.add_argument(right);
                    parent_node.replace_expression(this, set_call);
                    return(set_call.check(context));
                }
                else
                {
                    right.target_type = left.value_type;
                }
            }
            else if (left is PointerIndirection)
            {
                right.target_type = left.value_type;
            }
            else
            {
                error = true;
                Report.error(source_reference, "unsupported lvalue in assignment");
                return(false);
            }

            if (!right.check(context))
            {
                // skip on error in inner expression
                error = true;
                return(false);
            }

            if (Operator != AssignmentOperator.SIMPLE && left is MemberAccess)
            {
                // transform into simple assignment
                // FIXME: only do this if the backend doesn't support
                // the assignment natively

                var ma = (MemberAccess)left;

                if (!(ma.symbol_reference is Signal))
                {
                    var old_value = new MemberAccess(ma.inner, ma.member_name);

                    var bin = new BinaryExpression(BinaryOperator.PLUS, old_value, right, source_reference);
                    bin.target_type               = right.target_type;
                    right.target_type             = right.target_type.copy();
                    right.target_type.value_owned = false;

                    if (Operator == AssignmentOperator.BITWISE_OR)
                    {
                        bin.Operator = BinaryOperator.BITWISE_OR;
                    }
                    else if (Operator == AssignmentOperator.BITWISE_AND)
                    {
                        bin.Operator = BinaryOperator.BITWISE_AND;
                    }
                    else if (Operator == AssignmentOperator.BITWISE_XOR)
                    {
                        bin.Operator = BinaryOperator.BITWISE_XOR;
                    }
                    else if (Operator == AssignmentOperator.ADD)
                    {
                        bin.Operator = BinaryOperator.PLUS;
                    }
                    else if (Operator == AssignmentOperator.SUB)
                    {
                        bin.Operator = BinaryOperator.MINUS;
                    }
                    else if (Operator == AssignmentOperator.MUL)
                    {
                        bin.Operator = BinaryOperator.MUL;
                    }
                    else if (Operator == AssignmentOperator.DIV)
                    {
                        bin.Operator = BinaryOperator.DIV;
                    }
                    else if (Operator == AssignmentOperator.PERCENT)
                    {
                        bin.Operator = BinaryOperator.MOD;
                    }
                    else if (Operator == AssignmentOperator.SHIFT_LEFT)
                    {
                        bin.Operator = BinaryOperator.SHIFT_LEFT;
                    }
                    else if (Operator == AssignmentOperator.SHIFT_RIGHT)
                    {
                        bin.Operator = BinaryOperator.SHIFT_RIGHT;
                    }

                    right = bin;
                    right.check(context);

                    Operator = AssignmentOperator.SIMPLE;
                }
            }

            if (left.symbol_reference is Signal)
            {
                var sig = (Signal)left.symbol_reference;

                var m = right.symbol_reference as Method;

                if (m == null)
                {
                    error = true;
                    Report.error(right.source_reference, "unsupported expression for signal handler");
                    return(false);
                }

                var dynamic_sig = sig as DynamicSignal;
                var right_ma    = right as MemberAccess;
                if (dynamic_sig != null)
                {
                    bool first = true;
                    foreach (Parameter param in dynamic_sig.handler.value_type.get_parameters())
                    {
                        if (first)
                        {
                            // skip sender parameter
                            first = false;
                        }
                        else
                        {
                            dynamic_sig.add_parameter(param.copy());
                        }
                    }
                    right.target_type = new DelegateType(sig.get_delegate(new ObjectType((ObjectTypeSymbol)sig.parent_symbol), this));
                }
                else if (!right.value_type.compatible(right.target_type))
                {
                    var delegate_type = (DelegateType)right.target_type;

                    error = true;
                    Report.error(right.source_reference, "method `%s' is incompatible with signal `%s', expected `%s'".printf(right.value_type.ToString(), right.target_type.ToString(), delegate_type.delegate_symbol.get_prototype_string(m.name)));
                    return(false);
                }
                else if (right_ma != null && right_ma.prototype_access)
                {
                    error = true;
                    Report.error(right.source_reference, "Access to instance member `%s' denied".printf(m.get_full_name()));
                    return(false);
                }
            }
            else if (left is MemberAccess)
            {
                var ma = (MemberAccess)left;

                if (ma.symbol_reference is Property)
                {
                    var prop = (Property)ma.symbol_reference;

                    var dynamic_prop = prop as DynamicProperty;
                    if (dynamic_prop != null)
                    {
                        dynamic_prop.property_type = right.value_type.copy();
                        left.value_type            = dynamic_prop.property_type.copy();
                    }

                    if (prop.set_accessor == null ||
                        (!prop.set_accessor.writable && !(context.analyzer.find_current_method() is CreationMethod || context.analyzer.is_in_constructor())))
                    {
                        ma.error = true;
                        Report.error(ma.source_reference, "Property `%s' is read-only".printf(prop.get_full_name()));
                        return(false);
                    }
                    else if (!context.deprecated &&
                             !prop.set_accessor.writable &&
                             context.analyzer.find_current_method() is CreationMethod)
                    {
                        if (ma.inner.symbol_reference != context.analyzer.find_current_method().this_parameter)
                        {
                            // trying to set construct-only property in creation method for foreign instance
                            Report.error(ma.source_reference, "Property `%s' is read-only".printf(prop.get_full_name()));
                            return(false);
                        }
                        else
                        {
                            Report.error(ma.source_reference, "Cannot assign to construct-only properties, use Object (property: value) constructor chain up");
                            return(false);
                        }
                    }
                }
                else if (ma.symbol_reference is Variable && right.value_type == null)
                {
                    var variable = (Variable)ma.symbol_reference;

                    if (right.symbol_reference is Method &&
                        variable.variable_type is DelegateType)
                    {
                        var m  = (Method)right.symbol_reference;
                        var dt = (DelegateType)variable.variable_type;
                        var cb = dt.delegate_symbol;

                        /* check whether method matches callback type */
                        if (!cb.matches_method(m, dt))
                        {
                            error = true;
                            Report.error(source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf(m.get_full_name(), cb.get_full_name()));
                            return(false);
                        }

                        right.value_type = variable.variable_type;
                    }
                    else
                    {
                        error = true;
                        Report.error(source_reference, "Assignment: Invalid assignment attempt");
                        return(false);
                    }
                }

                if (left.value_type != null && right.value_type != null)
                {
                    /* if there was an error on either side,
                     * i.e. {left|right}.value_type == null, skip type check */

                    if (!right.value_type.compatible(left.value_type))
                    {
                        error = true;
                        Report.error(source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf(right.value_type.ToString(), left.value_type.ToString()));
                        return(false);
                    }

                    if (!(ma.symbol_reference is Property))
                    {
                        if (right.value_type.is_disposable())
                        {
                            /* rhs transfers ownership of the expression */
                            if (!(left.value_type is PointerType) && !left.value_type.value_owned)
                            {
                                /* lhs doesn't own the value */
                                error = true;
                                Report.error(source_reference, "Invalid assignment from owned expression to unowned variable");
                            }
                        }
                        else if (left.value_type.value_owned)
                        {
                            /* lhs wants to own the value
                             * rhs doesn't transfer the ownership
                             * code generator needs to add reference
                             * increment calls */
                        }
                    }
                }

                var right_ma = right as MemberAccess;
                if (right_ma != null && ma.symbol_reference == right_ma.symbol_reference)
                {
                    if (ma.symbol_reference is LocalVariable || ma.symbol_reference is Parameter)
                    {
                        Report.warning(source_reference, "Assignment to same variable");
                    }
                    else if (ma.symbol_reference is Field)
                    {
                        var f = (Field)ma.symbol_reference;
                        if (f.binding == MemberBinding.STATIC)
                        {
                            Report.warning(source_reference, "Assignment to same variable");
                        }
                        else
                        {
                            var ma_inner       = ma.inner as MemberAccess;
                            var right_ma_inner = right_ma.inner as MemberAccess;
                            if (ma_inner != null && ma_inner.member_name == "this" && ma_inner.inner == null &&
                                right_ma_inner != null && right_ma_inner.member_name == "this" && right_ma_inner.inner == null)
                            {
                                Report.warning(source_reference, "Assignment to same variable");
                            }
                        }
                    }
                }
            }
            else if (left is ElementAccess)
            {
                var ea = (ElementAccess)left;

                if (!right.value_type.compatible(left.value_type))
                {
                    error = true;
                    Report.error(source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf(right.value_type.ToString(), left.value_type.ToString()));
                    return(false);
                }

                if (right.value_type.is_disposable())
                {
                    /* rhs transfers ownership of the expression */

                    DataType element_type;

                    if (ea.container.value_type is ArrayType)
                    {
                        var array_type = (ArrayType)ea.container.value_type;
                        element_type = array_type.element_type;
                    }
                    else
                    {
                        var args = ea.container.value_type.get_type_arguments();
                        Debug.Assert(args.Count == 1);
                        element_type = args[0];
                    }

                    if (!(element_type is PointerType) && !element_type.value_owned)
                    {
                        /* lhs doesn't own the value */
                        error = true;
                        Report.error(source_reference, "Invalid assignment from owned expression to unowned variable");
                        return(false);
                    }
                }
                else if (left.value_type.value_owned)
                {
                    /* lhs wants to own the value
                     * rhs doesn't transfer the ownership
                     * code generator needs to add reference
                     * increment calls */
                }
            }
            else
            {
                return(true);
            }

            if (left.value_type != null)
            {
                value_type             = left.value_type.copy();
                value_type.value_owned = false;
            }
            else
            {
                value_type = null;
            }

            add_error_types(left.get_error_types());
            add_error_types(right.get_error_types());

            return(!error);
        }