Ejemplo n.º 1
0
        Stmt *new_stmt_goto(SrcPos pos, char *label)
        {
            Stmt *s = new_stmt(STMT_GOTO, pos);

            s->label = label;
            return(s);
        }
Ejemplo n.º 2
0
        Stmt *parse_stmt_for(SrcPos pos)
        {
            Stmt *init = null;
            Expr *cond = null;
            Stmt *next = null;

            if (!is_token(TOKEN_LBRACE))
            {
                expect_token(TOKEN_LPAREN);
                if (!is_token(TOKEN_SEMICOLON))
                {
                    init = parse_simple_stmt();
                }
                if (match_token(TOKEN_SEMICOLON))
                {
                    if (!is_token(TOKEN_SEMICOLON))
                    {
                        cond = parse_expr();
                    }
                    if (match_token(TOKEN_SEMICOLON))
                    {
                        if (!is_token(TOKEN_RPAREN))
                        {
                            next = parse_simple_stmt();
                            if (next->kind == STMT_INIT)
                            {
                                error_here("Init statements not allowed in for-statement's next clause");
                            }
                        }
                    }
                }
            }
            expect_token(TOKEN_RPAREN);
            return(new_stmt_for(pos, init, cond, next, parse_stmt_block()));
        }
Ejemplo n.º 3
0
        Stmt *new_stmt_label(SrcPos pos, char *label)
        {
            Stmt *s = new_stmt(STMT_LABEL, pos);

            s->label = label;
            return(s);
        }
Ejemplo n.º 4
0
        Stmt *new_stmt_note(SrcPos pos, Note note)
        {
            Stmt *s = new_stmt(STMT_NOTE, pos);

            s->note = note;
            return(s);
        }
Ejemplo n.º 5
0
        Stmt *new_stmt_for(SrcPos pos, Stmt *init, Expr *cond, Stmt *next, StmtList block)
        {
            var s = new_stmt(STMT_FOR, pos);

            s->for_stmt.init  = init;
            s->for_stmt.cond  = cond;
            s->for_stmt.next  = next;
            s->for_stmt.block = block;
            return(s);
        }
Ejemplo n.º 6
0
 Note *get_stmt_note(Stmt *stmt, char *name)
 {
     for (var i = 0; i < stmt->notes.num_notes; i++)
     {
         Note *note = stmt->notes.notes + i;
         if (note->name == name)
         {
             return(note);
         }
     }
     return(null);
 }
Ejemplo n.º 7
0
        Stmt *new_stmt_if(SrcPos pos, Stmt *init, Expr *cond, StmtList then_block, ElseIf **elseifs, int num_elseifs,
                          StmtList else_block)
        {
            var s = new_stmt(STMT_IF, pos);

            s->if_stmt.cond        = cond;
            s->if_stmt.init        = init;
            s->if_stmt.then_block  = then_block;
            s->if_stmt.elseifs     = elseifs;
            s->if_stmt.num_elseifs = num_elseifs;
            s->if_stmt.else_block  = else_block;
            return(s);
        }
Ejemplo n.º 8
0
        Stmt *parse_stmt_if(SrcPos pos)
        {
            expect_token(TOKEN_LPAREN);
            Expr *cond = parse_expr();
            Stmt *init = parse_init_stmt(cond);

            if (init != null)
            {
                if (match_token(TOKEN_SEMICOLON))
                {
                    cond = parse_expr();
                }
                else
                {
                    cond = null;
                }
            }
            expect_token(TOKEN_RPAREN);
            var then_block = parse_stmt_block();
            var else_block = default(StmtList);

            var buf = PtrBuffer.Create();

            while (match_keyword(else_keyword))
            {
                if (!match_keyword(if_keyword))
                {
                    else_block = parse_stmt_block();
                    break;
                }

                var elseif_cond  = parse_paren_expr();
                var elseif_block = parse_stmt_block();
                var elif         = (ElseIf *)xmalloc(sizeof(ElseIf));
                elif->cond  = elseif_cond;
                elif->block = elseif_block;
                buf->Add(elif);
            }

            return(new_stmt_if(pos, init, cond, then_block, (ElseIf **)buf->_begin, buf->count, else_block));
        }
Ejemplo n.º 9
0
        Stmt *parse_simple_stmt()
        {
            SrcPos pos  = token.pos;
            Expr * expr = parse_expr();
            Stmt * stmt = parse_init_stmt(expr);

            if (stmt == null)
            {
                if (is_assign_op())
                {
                    TokenKind op = token.kind;
                    next_token();
                    stmt = new_stmt_assign(pos, op, expr, parse_expr());
                }
                else
                {
                    stmt = new_stmt_expr(pos, expr);
                }
            }
            return(stmt);
        }
Ejemplo n.º 10
0
        Stmt *parse_init_stmt(Expr *left)
        {
            var   pos  = token.pos;
            Stmt *stmt = null;

            if (match_token(TOKEN_COLON_ASSIGN))
            {
                if (left->kind != EXPR_NAME)
                {
                    fatal_error_here(":= must be preceded by a name");
                    return(null);
                }

                return(new_stmt_init(left->pos, left->name, null, parse_expr(), false));
            }
            else if (match_token(TOKEN_COLON))
            {
                if (left->kind != EXPR_NAME)
                {
                    fatal_error_here(": must be preceded by a name");
                    return(null);
                }
                char *    name     = left->name;
                Typespec *type     = parse_type();
                Expr *    expr     = null;
                bool      is_undef = false;
                if (match_token(TOKEN_ASSIGN))
                {
                    is_undef = match_keyword(undef_keyword);
                    if (!is_undef)
                    {
                        expr = parse_expr();
                    }
                }
                return(new_stmt_init(left->pos, name, type, expr, is_undef));
            }

            return(null);
        }
Ejemplo n.º 11
0
        Stmt *parse_stmt()
        {
            Notes notes = parse_notes();
            var   pos   = token.pos;
            Stmt *stmt  = null;

            if (match_keyword(if_keyword))
            {
                stmt = parse_stmt_if(pos);
            }

            else if (match_keyword(while_keyword))
            {
                stmt = parse_stmt_while(pos);
            }

            else if (match_keyword(do_keyword))
            {
                stmt = parse_stmt_do_while(pos);
            }

            else if (match_keyword(for_keyword))
            {
                stmt = parse_stmt_for(pos);
            }

            else if (match_keyword(switch_keyword))
            {
                stmt = parse_stmt_switch(pos);
            }

            else if (is_token(TOKEN_LBRACE))
            {
                stmt = new_stmt_block(pos, parse_stmt_block());
            }

            else if (match_keyword(break_keyword))
            {
                expect_token(TOKEN_SEMICOLON);
                stmt = new_stmt_break(pos);
            }

            else if (match_keyword(continue_keyword))
            {
                expect_token(TOKEN_SEMICOLON);
                stmt = new_stmt_continue(pos);
            }

            else if (match_keyword(return_keyword))
            {
                Expr *expr = null;
                if (!is_token(TOKEN_SEMICOLON))
                {
                    expr = parse_expr();
                }

                expect_token(TOKEN_SEMICOLON);
                stmt = new_stmt_return(pos, expr);
            }
            else if (match_token(TOKEN_POUND))
            {
                Note note = parse_note();
                expect_token(TOKEN_SEMICOLON);
                stmt = new_stmt_note(pos, note);
            }
            else if (match_token(TOKEN_COLON))
            {
                stmt = new_stmt_label(pos, parse_name());
            }
            else if (match_keyword(goto_keyword))
            {
                stmt = new_stmt_goto(pos, parse_name());
                expect_token(TOKEN_SEMICOLON);
            }
            else
            {
                stmt = parse_simple_stmt();
                expect_token(TOKEN_SEMICOLON);
            }
            stmt->notes = notes;
            return(stmt);
        }
Ejemplo n.º 12
0
        void print_stmt(Stmt *stmt)
        {
            var s = stmt;

            switch (s->kind)
            {
            case STMT_DECL:
                print_decl(s->decl);
                break;

            case STMT_RETURN:
                printf("(return");
                if (s->expr != null)
                {
                    printf(" ");
                    print_expr(s->expr);
                }

                printf(")");
                break;

            case STMT_BREAK:
                printf("(break)");
                break;

            case STMT_CONTINUE:
                printf("(continue)");
                break;

            case STMT_BLOCK:
                print_stmt_block(s->block);
                break;

            case STMT_IF:
                printf("(if ");
                print_expr(s->if_stmt.cond);
                _indent++;
                print_newline();
                print_stmt_block(s->if_stmt.then_block);
                for (var it = s->if_stmt.elseifs; it != s->if_stmt.elseifs + s->if_stmt.num_elseifs; it++)
                {
                    print_newline();
                    printf("elseif ");
                    print_expr((*it)->cond);
                    print_newline();
                    print_stmt_block((*it)->block);
                }

                if (s->if_stmt.else_block.num_stmts != 0)
                {
                    print_newline();
                    printf("else ");
                    print_newline();
                    print_stmt_block(s->if_stmt.else_block);
                }

                _indent--;
                printf(")");
                break;

            case STMT_WHILE:
                printf("(while ");
                print_expr(s->while_stmt.cond);
                _indent++;
                print_newline();
                print_stmt_block(s->while_stmt.block);
                _indent--;
                printf(")");
                break;

            case STMT_DO_WHILE:
                printf("(do-while ");
                print_expr(s->while_stmt.cond);
                _indent++;
                print_newline();
                print_stmt_block(s->while_stmt.block);
                _indent--;
                printf(")");
                break;

            case STMT_FOR:
                printf("(for ");
                print_stmt(s->for_stmt.init);
                print_expr(s->for_stmt.cond);
                print_stmt(s->for_stmt.next);
                _indent++;
                print_newline();
                print_stmt_block(s->for_stmt.block);
                _indent--;
                printf(")");
                break;

            case STMT_SWITCH:
                printf("(switch ");
                print_expr(s->switch_stmt.expr);
                _indent++;
                for (var it = s->switch_stmt.cases;
                     it != s->switch_stmt.cases + s->switch_stmt.num_cases;
                     it++)
                {
                    print_newline();
                    printf("(case ({0}", it->is_default ? " default" : "");
                    for (var pattern = it->patterns; pattern != it->patterns + it->num_patterns; pattern++)
                    {
                        printf(" ");
                        print_expr(pattern->start);
                        if (pattern->end != null)
                        {
                            printf(", ");
                            print_expr(pattern->end);
                        }
                    }

                    printf(" ) ");
                    _indent++;
                    print_newline();
                    print_stmt_block(it->block);
                    _indent--;
                }

                _indent--;
                printf(")");
                break;

            case STMT_ASSIGN:
                printf("({0} ", token_kind_names[(long)s->assign.op]);
                print_expr(s->assign.left);
                if (s->assign.right != null)
                {
                    printf(" ");
                    print_expr(s->assign.right);
                }

                printf(")");
                break;

            case STMT_INIT:
                printf("(:= {0} ", s->init.name);
                print_expr(s->init.expr);
                printf(")");
                break;

            case STMT_EXPR:
                print_expr(s->expr);
                break;

            default:
                assert(false);
                break;
            }
        }