Example #1
0
        ConditionStatement.VersionStatement VersionStatement(IBlockNode Scope, IStatement Parent)
        {
            Step();
            var s = new ConditionStatement.VersionStatement() { Location = t.Location, Parent = Parent };

            if (laKind == OpenParenthesis)
            {
                Step();
                if (laKind == Identifier || laKind == Literal || laKind == Unittest)
                {
                    Step();
                    if (laKind == Unittest)
                        s.VersionIdentifierOrLiteral = "unittest";
                    else if (laKind == Literal)
                        s.VersionIdentifierOrLiteral = t.LiteralValue;
                    else
                        s.VersionIdentifierOrLiteral = t.Value;
                }
                else
                    SynErr(t.Kind, "Identifier or Literal expected, " + DTokens.GetTokenString(t.Kind) + " found");

                Expect(CloseParenthesis);
            }

            s.ScopedStatement = Statement(Parent: s);

            if (laKind == Else)
            {
                Step();
                s.ElseStatement = Statement(Parent: s);
            }

            s.EndLocation = t.EndLocation;
            return s;
        }
Example #2
0
        IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null)
        {
            IStatement ret = null;

            if (EmptyAllowed && laKind == Semicolon)
            {
                Step();
                return null;
            }

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

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

                ret = (new LabeledStatement() { StartLocation = 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() { StartLocation = t.Location, IsStatic = isStatic, Parent = Parent };
                LastParsedObject = dbs;
                Expect(OpenParenthesis);

                // IfCondition
                IfCondition(dbs);

                Expect(CloseParenthesis);
                // ThenStatement

                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() { StartLocation = 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() { StartLocation = 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 { StartLocation = 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))
            {
                Step();

                var dbs = new ForeachStatement() { StartLocation = t.Location, IsReverse = t.Kind == Foreach_Reverse, Parent=Parent };
                LastParsedObject = dbs;
                Expect(OpenParenthesis);

                var tl = new List<DVariable>();

                bool init = true;
                while (init || laKind == (Comma))
                {
                    if (!init) Step();
                    init = false;

                    var forEachVar = new DVariable();
                    LastParsedObject = forEachVar;
                    forEachVar.StartLocation = la.Location;

                    if (laKind == (Ref))
                    {
                        Step();
                        forEachVar.Attributes.Add(new DAttribute(Ref));
                    }
                    if (laKind == (Identifier) && (Lexer.CurrentPeekToken.Kind == (Semicolon) || Lexer.CurrentPeekToken.Kind == Comma))
                    {
                        Step();
                        forEachVar.Name = t.Value;
                    }
                    else
                    {
                        forEachVar.Type = Type();
                        if (laKind == Identifier)
                        {
                            Expect(Identifier);
                            forEachVar.Name = t.Value;
                        }
                    }
                    forEachVar.EndLocation = t.EndLocation;

                    tl.Add(forEachVar);
                }
                dbs.ForeachTypeList = tl.ToArray();

                Expect(Semicolon);
                dbs.Aggregate = Expression(Scope);

                // ForeachRangeStatement
                if (laKind == DoubleDot)
                {
                    Step();
                    //TODO: Put this in the expression variable
                    Expression();
                }

                Expect(CloseParenthesis);

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

                return dbs;
            }
            #endregion

            #region [Final] SwitchStatement
            else if ((laKind == (Final) && Lexer.CurrentPeekToken.Kind == (Switch)) || laKind == (Switch))
            {
                var dbs = new SwitchStatement { StartLocation = 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() { StartLocation = 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()
                {
                    StartLocation = 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() { StartLocation = 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() { StartLocation = 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() { StartLocation = 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() { StartLocation = 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() { StartLocation = 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() { StartLocation = 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() { StartLocation = 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() { StartLocation = 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() { StartLocation = 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() { StartLocation = 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) && Lexer.CurrentPeekToken.Kind==OpenParenthesis)
            {
                Step();
                var s = new ScopeGuardStatement() { StartLocation = t.Location, Parent = Parent };
                LastParsedObject = s;

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

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

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

            #region AsmStmt
            else if (laKind == (Asm))
            {
                Step();
                var s = new AsmStatement() { StartLocation = t.Location, Parent = Parent };
                LastParsedObject = s;

                Expect(OpenCurlyBrace);

                var l=new List<string>();
                var curInstr = "";
                while (!IsEOF && laKind != (CloseCurlyBrace))
                {
                    if (laKind == Semicolon)
                    {
                        l.Add(curInstr.Trim());
                        curInstr = "";
                    }
                    else
                        curInstr += laKind==Identifier? la.Value: DTokens.GetTokenString(laKind);

                    Step();
                }

                Expect(CloseCurlyBrace);
                s.EndLocation = t.EndLocation;
                return s;
            }
            #endregion

            #region PragmaStatement
            else if (laKind == (Pragma))
            {
                var s=_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))
            {
                // TemplateMixin
                if (Peek(1).Kind != OpenParenthesis)
                    return TemplateMixin();
                else
                {
                    Step();
                    var s = new MixinStatement() { StartLocation = t.Location, Parent = Parent };
                    LastParsedObject = s;

                    Expect(OpenParenthesis);

                    s.MixinExpression = AssignExpression(Scope);

                    Expect(CloseParenthesis);
                    Expect(Semicolon);

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

            #region Conditions
            if (laKind == Debug)
            {
                Step();
                var s = new ConditionStatement.DebugStatement() { StartLocation = t.Location, Parent = Parent };
                LastParsedObject = s;

                if (laKind == OpenParenthesis)
                {
                    Step();
                    if (laKind == Identifier || laKind == Literal)
                    {
                        Step();
                        if (laKind == Literal)
                            s.DebugIdentifierOrLiteral = t.LiteralValue;
                        else
                            s.DebugIdentifierOrLiteral = t.Value;
                    }
                    else
                        SynErr(t.Kind, "Identifier or Literal expected, "+DTokens.GetTokenString(t.Kind)+" found");

                    Expect(CloseParenthesis);
                }

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

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

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

            if (laKind == Version)
            {
                Step();
                var s = new ConditionStatement.VersionStatement() { StartLocation = t.Location, Parent = Parent };

                if (laKind == OpenParenthesis)
                {
                    Step();
                    if (laKind == Identifier || laKind == Literal || laKind==Unittest)
                    {
                        Step();
                        if(laKind==Unittest)
                            s.VersionIdentifierOrLiteral = "unittest";
                        else if(laKind==Literal)
                            s.VersionIdentifierOrLiteral=t.LiteralValue;
                        else
                            s.VersionIdentifierOrLiteral=t.Value;
                    }
                    else
                        SynErr(t.Kind, "Identifier or Literal expected, " + DTokens.GetTokenString(t.Kind) + " found");

                    Expect(CloseParenthesis);
                }

                s.ScopedStatement = Statement(Parent:s);

                if (laKind == Else)
                {
                    Step();
                    s.ElseStatement = Statement(Parent:s);
                }

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

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

                if (s.IsStatic)
                    Step();

                s.AssertExpression = AssignExpression(Scope);
                Expect(Semicolon);
                s.EndLocation = t.EndLocation;

                return s;
            }
            #endregion

            #region D1: VolatileStatement
            else if (laKind == Volatile)
            {
                Step();
                var s = new VolatileStatement() { StartLocation = 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)
                ImportDeclaration();

            else if (!(ClassLike[laKind] || BasicTypes[laKind] || laKind == Enum || Modifiers[laKind] || laKind==PropertyAttribute || laKind == Alias || laKind == Typedef) && IsAssignExpression())
            {
                var s = new ExpressionStatement() { StartLocation = la.Location, Parent = Parent };
                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() { StartLocation = la.Location, Parent = Parent };
                LastParsedObject = s;
                s.Declarations = Declaration(Scope);

                if (Scope != null && s.Declarations != null && s.Declarations.Length > 0)
                    foreach (var decl in s.Declarations)
                        decl.Parent = Scope;

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

            return null;
        }