diff --git a/src/ast/statements.hpp b/src/ast/statements.hpp index 01c5914..1197760 100644 --- a/src/ast/statements.hpp +++ b/src/ast/statements.hpp @@ -190,4 +190,26 @@ struct Module : Node } return oss.str(); } +}; + +struct While : Stmt +{ + ptr condition; + std::vector> body; + + While(ptr cond, std::vector> b) + : condition(std::move(cond)), body(std::move(b)) {} + + std::string dump(int indent = 0) const override + { + std::ostringstream oss; + oss << indent_str(indent) << "While\n"; + oss << condition->dump(indent + 1); + for (const auto &stmt : body) + { + oss << "\n" + << stmt->dump(indent + 1); + } + return oss.str(); + } }; \ No newline at end of file diff --git a/src/lexer.l b/src/lexer.l index 21f0bd3..1aa4919 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -49,6 +49,7 @@ pass { return yy::parser::token::TOK_KW_PASS; } else { return yy::parser::token::TOK_KW_ELSE; } elif { return yy::parser::token::TOK_KW_ELIF; } class { return yy::parser::token::TOK_KW_CLASS; } +while { return yy::parser::token::TOK_KW_WHILE; } \=\= { return yy::parser::token::TOK_EQ; } \!\= { return yy::parser::token::TOK_NE; } diff --git a/src/parser.y b/src/parser.y index a7a72cb..df091f1 100644 --- a/src/parser.y +++ b/src/parser.y @@ -32,7 +32,7 @@ %left KW_OR %left KW_AND %right KW_NOT // unary logical NOT -%token KW_DEF KW_IF KW_RETURN KW_FOR KW_IN KW_PASS KW_ELSE KW_ELIF KW_CLASS +%token KW_DEF KW_IF KW_RETURN KW_FOR KW_IN KW_PASS KW_ELSE KW_ELIF KW_CLASS KW_WHILE %token L_PAREN R_PAREN L_BRACKET R_BRACKET L_BRACE R_BRACE %token DOT COLON SEMICOLON COMMA @@ -94,6 +94,9 @@ stmt: | KW_RETURN expr NEWLINE { $$ = std::make_unique(std::move($2)); } + | KW_WHILE expr COLON NEWLINE INDENT stmt_list DEDENT { + $$ = std::make_unique(std::move($2), std::move($6)); + } ; expr: @@ -102,6 +105,7 @@ expr: | STRING { $$ = std::make_unique($1); } | expr PLUS expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::ADD), std::move($1), std::move($3)); } | expr MULTIPLY expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::MUL), std::move($1), std::move($3)); } + | expr MINUS expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::SUB), std::move($1), std::move($3)); } | expr LT expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::LT) , std::move($1), std::move($3)); } | expr KW_AND expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::AND) , std::move($1), std::move($3)); } | expr KW_OR expr { $$ = std::make_unique( BinaryOperator(BinaryOperator::OR) , std::move($1), std::move($3)); } diff --git a/test/parser/25.in b/test/parser/25.in index f505c42..f9afc99 100644 --- a/test/parser/25.in +++ b/test/parser/25.in @@ -1,3 +1,2 @@ while x: - x = x - 1 - + x = x - 1 \ No newline at end of file diff --git a/test/parser/25.out b/test/parser/25.out index bfa717f..51a2439 100644 --- a/test/parser/25.out +++ b/test/parser/25.out @@ -5,5 +5,4 @@ Module Identifier(x) BinOp(-) Identifier(x) - Number(1) - + Number(1) \ No newline at end of file