Example #1
0
 public BlockStatement(
     LocalVarDecl[] arLocals, // can be null if we have no locals
     Statement[] arStatements // never null
 )
 {
     // If we have any locals in this block statement, then we
     // also need to have a scope to hold them.
     if (arLocals == null)
     {
         m_arLocals = new LocalVarDecl[0];
     } else {
         m_arLocals = arLocals;
         // @todo - decorate name w/ filerange?
         //m_scopeLocals = new Scope("block_scope", null);
     }
     
     // May have an empty statement block, so arStatements.Length could be 0
     // but at least expect an array.
     Debug.Assert(arStatements != null);
     m_arStatements = arStatements;
     
     // @todo - fix this
     if (arStatements.Length == 0)
         this.m_filerange = new FileRange();
     else 
         this.m_filerange = arStatements[0].Location;
 }
Example #2
0
    // Do the real work
    protected void ParseStatementOrLocal_Helper(out Statement s, out LocalVarDecl v)
    {   
        s = null;
        v = null;
        
        // For each statement, we know which type based off the first token.
        // Expect for an identifier, in which case it could be a few things.
        Token t = m_lexer.PeekNextToken();
        
        #if false
        // Skip past any ';' (as empty statements)
        while(t.TokenType == Token.Type.cSemi)
        {
            ConsumeNextToken();
            t = m_lexer.PeekNextToken();            
        }
        #endif
                       
        if (IsStartOfExp(t))
        {
            FileRange f = BeginRange();
            
            // This could be either an expression or a type
            Exp e = ParseExp();
            t = m_lexer.PeekNextToken();

            
            // Case 1 - Var declaration:
            // If an identifier follows, then we just read a type and this is
            // a var declaration:
            // Type id ';'
            // Type id '=' exp ';'
            if (t.TokenType == Token.Type.cId)
            {
                TypeSig tSig  = this.ConvertExpToType(e);

                Identifier id = ReadExpectedIdentifier();
                
                v = new LocalVarDecl(id, tSig);
                                
                // Check for optional assignment (if there's an '=' after the name)
                Token t3 = m_lexer.PeekNextToken();
                if (t3.TokenType == Token.Type.cAssign)
                {
                    ConsumeNextToken();                     // '='
                    Exp eRHS = ParseExp();                  // exp                
                    ReadExpectedToken(Token.Type.cSemi);    // ';'
                    
                    SimpleObjExp oleft = new SimpleObjExp(id);
                    StatementExp se = new AssignStmtExp(oleft, eRHS);
                    s = new ExpStatement(se);
                    
                    se.SetLocation(EndRange(f));
                } else {                
                    ReadExpectedToken(Token.Type.cSemi);    // ';'
                }


                
                return;
            } // end decl case

            // Case 2 - label declaration
            else if (t.TokenType == Token.Type.cColon)
            {                
                SimpleObjExp o2 = e as SimpleObjExp;
                if (o2 != null)
                {
                    ConsumeNextToken(); // ':'
                    s = new LabelStatement(o2.Name);
                    return; // skip reading a ';'
                } 
                
                ThrowError(new ParserErrorException(Code.cBadLabelDef, t.Location, 
                    "Bad label definition (labels must be a single identifier)"));                                
            } // end case for label decls
                        
            // Expect a StatementExp
            else if (t.TokenType == Token.Type.cSemi) {
                ReadExpectedToken(Token.Type.cSemi);
                
                // Else we must be a StatementExp
                StatementExp se = e as StatementExp;
                if (se == null)
                    //this.ThrowError_ExpectedStatementExp(e.Location);
                    ThrowError(E_ExpectedStatementExp(e.Location));
                
                se.SetLocation(EndRange(f));
                s = new ExpStatement(se);            
                return;
            }
    
            ThrowError(E_UnexpectedToken(t));
        } // end start of expressions
        
        switch(t.TokenType)
        {
        // Empty statement
        case Token.Type.cSemi:
            ConsumeNextToken();
            s = new EmptyStatement();
            break;

        // Return -> 'return' ';'
        //         | 'return' exp ';'
        case Token.Type.cReturn:
            {
                ConsumeNextToken();
                
                t = m_lexer.PeekNextToken();
                Exp e = null;
                if (t.TokenType != Token.Type.cSemi) 
                {
                    e = ParseExp();                    
                }
                ReadExpectedToken(Token.Type.cSemi);
        
                s = new ReturnStatement(e);                
            }        
            break;
            
        // Note that the semi colons are included inthe stmt            
        // IfSmt -> 'if' '(' exp ')' stmt:then 
        // IfSmt -> 'if' '(' exp ')' stmt:then 'else' stmt:else
        case Token.Type.cIf:
        {
            ConsumeNextToken(); // 'if'
            ReadExpectedToken(Token.Type.cLParen);
            Exp exp = ParseExp();            
            ReadExpectedToken(Token.Type.cRParen);
            
            Statement sThen = ParseStatement();
            Statement sElse = null;
            
            Token t2 = m_lexer.PeekNextToken();
            if (t2.TokenType == Token.Type.cElse) 
            {
                ConsumeNextToken(); // 'else'
                sElse = ParseStatement();                
            }
            
            s = new IfStatement(exp, sThen, sElse);        
        }
            break;
            
        case Token.Type.cSwitch:
            s = ParseSwitchStatement();
            break;            
        
        // Throw an expression
        // ThrowStmt -> 'throw' objexp    
        case Token.Type.cThrow:
        {
            ConsumeNextToken(); // 'throw'
            Exp oe = null;
            if (m_lexer.PeekNextToken().TokenType != Token.Type.cSemi)
            {
                oe = ParseExp();            
            }
            ReadExpectedToken(Token.Type.cSemi);
            
            s = new ThrowStatement(oe);
        }
            break;
        
        // try-catch-finally
        case Token.Type.cTry:
            s = ParseTryCatchFinallyStatement();
            break;
        
        // while loop
        // 'while' '(' exp ')' stmt            
        case Token.Type.cWhile:
        {
            ConsumeNextToken(); // 'while'
            ReadExpectedToken(Token.Type.cLParen);

            Exp e = ParseExp();

            ReadExpectedToken(Token.Type.cRParen);

            Statement body = ParseStatement();

            s = new WhileStatement(e, body);


        }
            break;

        // do loop
        // 'do' stmt 'while' '(' exp ')' ';'
        case Token.Type.cDo:
        {
            ConsumeNextToken(); // 'do'
            Statement body = ParseStatement();
            ReadExpectedToken(Token.Type.cWhile);

            ReadExpectedToken(Token.Type.cLParen);
            Exp e = ParseExp();
            ReadExpectedToken(Token.Type.cRParen);

            ReadExpectedToken(Token.Type.cSemi);

            s = new DoStatement(e, body);

        }
            break;

        // goto
        // 'goto' id:label ';'
        case Token.Type.cGoto:
        {
            ConsumeNextToken();                             // 'goto'
            Identifier id = ReadExpectedIdentifier();       // id:label
            ReadExpectedToken(Token.Type.cSemi);            // ';'

            s = new GotoStatement(id);
        }
            break;

        // break
        // 'break' ';'
        case Token.Type.cBreak:
            ConsumeNextToken();
            ReadExpectedToken(Token.Type.cSemi);
            s = new BreakStatement();
            break;

        // Continue
        // 'continue' ';'
        case Token.Type.cContinue:
            ConsumeNextToken();
            ReadExpectedToken(Token.Type.cSemi);
            s = new ContinueStatement();
            break;
            
        // For-loop            
        case Token.Type.cFor:
            s = ParseForStatement();
            break;

        // For-each
        // -> 'foreach' '(' Type id 'in' exp:collection ')' stmt
        case Token.Type.cForEach:
            s = ParseForeachStatement();
            break;
            
        // BlockStatement - can be nested inside each other
        // start with a  '{', no terminating semicolon
        case Token.Type.cLCurly:
            {
                s = ParseStatementBlock();                
            }
            break;
            
        default:
            ThrowError(E_UnexpectedToken(t)); // unrecognized statement
            break;
        
        } // end switch
        
        // Must have come up with something
        Debug.Assert(s != null || v != null);    
    }
Example #3
0
//-----------------------------------------------------------------------------
// Parse a single statement or local var decl (we can't tell which yet)
// Note that may be statement may be a block (which is just fine)
// for a construct like 'int x = 3' (decl & assignment), we'll yeild
// both s & v. Else the out params will be null if we don't have them.
//-----------------------------------------------------------------------------
    protected void ParseStatementOrLocal(out Statement s, out LocalVarDecl v)
    {
        // Wrap the worker to ensure that we have proper line number info
        FileRange f = BeginRange();
        
        // Do the real work
        ParseStatementOrLocal_Helper(out s, out v);
        
        if (s != null)
        {
            s.SetLocation(EndRange(f));
        }
    }
Example #4
0
 protected LocalVarDecl[] LocalVarDeclFromArray(ArrayList alParams)
 {
     LocalVarDecl[] v = new LocalVarDecl[alParams.Count];
     for(int i = 0; i < alParams.Count; i++)            
         v[i] = (LocalVarDecl) alParams[i];
         
     return v;
 }
Example #5
0
 public void ResolveHandler(ISemanticResolver s)
 {           
     // Catch blocks can declare an identifier        
     if (IdVarName != null)
     {
         m_var = new LocalVarDecl(IdVarName, m_type);
         Body.InjectLocalVar(m_var);
     }
     
     this.m_type.ResolveType(s);
     Body.ResolveStatement(s);
     
     // Catch type must be of type System.Exception
     if (m_var != null)
     {
         s.EnsureAssignable(m_var.Symbol.m_type.CLRType, typeof(System.Exception), IdVarName.Location);
     }
     
     // Catch type must be of type System.Exception
     //TypeEntry tSystem_Exception =s.ResolveCLRTypeToBlueType(typeof(System.Exception));
     //s.EnsureDerivedType(tSystem_Exception, m_type.TypeRec, new FileRange());
     
 }
Example #6
0
 public void InjectLocalVar(LocalVarDecl l)
 {
     //m_scopeLocals = new Scope("block_scope", null);
     LocalVarDecl[] ar2 = new LocalVarDecl[Locals.Length + 1];
     ar2[0] = l;
     for(int i = 0; i < Locals.Length; i++)        
         ar2[i + 1] = Locals[i];
     m_arLocals = ar2;
 }
Example #7
0
 public ForeachStatement(
     LocalVarDecl var,
     Exp expCollection,
     Statement body
 )
 {
     Debug.Assert(var != null);
     Debug.Assert(expCollection != null);
     
     m_var = var;
     m_expCollection = expCollection;
     m_stmtBody = body;
 }