示例#1
0
    protected void ExecuteVarDeclStmt(AstVarDeclStmt stmt)
    {
        if (HadErrorOrReturn())
        {
            return;
        }

        object value = null;

        if (stmt.m_initExpr != null)
        {
            value = EvaluateExpr(stmt.m_initExpr);
        }

        bool success = m_environment.Define(stmt.m_identifier.m_identifier, value);

        if (!success)
        {
            // TODO: Print the line that the first definition was on? To do that we would have to store
            //  line numbers in the environment. Also, it wouldn't really make sense for repl mode so we would
            //  have to have a way to check if we are in repl mode.

            m_runtimeError = true;
            Lox.Error(stmt.m_startLine, "Redefinition of identifier " + stmt.m_identifier.m_identifier);
        }
    }
示例#2
0
    protected void ResolveVarDeclStmt(AstVarDeclStmt stmt)
    {
        var scope = Scope();

        if (scope == null)
        {
            return;                 // TODO: Better global handling
        }
        if (scope.ContainsKey(stmt.m_identifier.m_identifier))
        {
            m_error = true;
            Lox.Error(stmt.m_startLine, "Redefinition of identifier \"" + stmt.m_identifier.m_identifier + "\" in same scope");
            return;
        }

        // Declared but not yet initialized

        scope[stmt.m_identifier.m_identifier] = false;

        if (stmt.m_initExpr != null)
        {
            ResolveExpr(stmt.m_initExpr);
        }

        // Declared and initialized

        scope[stmt.m_identifier.m_identifier] = true;
    }
示例#3
0
 public AstForStmt(int startLine, AstVarDeclStmt pre, AstExpr condition, AstExpr post, AstStmt body)
     : base(STMTK.For, startLine)
 {
     m_preDecl   = pre;
     m_condition = condition;
     m_post      = post;
     m_body      = body;
 }
示例#4
0
    protected AstStmt ParseForStmt()
    {
        PushLoop();
        try
        {
            Token forToken = Previous();
            Debug.Assert(forToken.m_tokenk == TOKENK.For);

            Token openParen;
            Token closeParen;

            AstVarDeclStmt preDecl   = null;
            AstExpr        preExpr   = null;
            AstExpr        condition = null;
            AstExpr        post      = null;

            Token semicolon;

            if ((openParen = TryMatch(TOKENK.OpenParen)) == null)
            {
                return(ErrorStmt(forToken.m_line, "Expected '(' after \"for\""));
            }

            if ((semicolon = TryMatch(TOKENK.Semicolon)) == null)
            {
                Token varToken;
                if ((varToken = TryMatch(TOKENK.Var)) != null)
                {
                    AstStmt stmt = ParseVarDeclStmt();
                    if (stmt == null)
                    {
                        return(EmptyErrorStmt());
                    }

                    Debug.Assert(stmt.m_stmtk == STMTK.VarDecl);
                    preDecl = (AstVarDeclStmt)stmt;
                }
                else
                {
                    AstStmt stmt = ParseExprStmt();
                    if (stmt == null)
                    {
                        return(EmptyErrorStmt());
                    }

                    Debug.Assert(stmt.m_stmtk == STMTK.Expr);
                    preExpr = ((AstExprStmt)stmt).m_expr;
                }
            }

            if ((semicolon = TryMatch(TOKENK.Semicolon)) == null)
            {
                AstStmt stmt = ParseExprStmt();
                if (stmt == null)
                {
                    return(EmptyErrorStmt());
                }

                Debug.Assert(stmt.m_stmtk == STMTK.Expr);
                condition = ((AstExprStmt)stmt).m_expr;
            }

            if ((closeParen = TryMatch(TOKENK.CloseParen)) == null)
            {
                post = ParseExpr();
                if (post == null)
                {
                    return(EmptyErrorStmt());
                }

                if ((closeParen = TryMatch(TOKENK.CloseParen)) == null)
                {
                    return(ErrorStmt(forToken.m_line, "Expected ')' at end of \"for\""));
                }
            }

            AstStmt body = ParseStmt();
            if (body == null)
            {
                return(EmptyErrorStmt());
            }

            if (preDecl != null)
            {
                return(new AstForStmt(forToken.m_line, preDecl, condition, post, body));
            }
            else
            {
                return(new AstForStmt(forToken.m_line, preExpr, condition, post, body));
            }
        }
        finally
        {
            PopLoop();
        }
    }