diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-16 09:41:13 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-16 09:41:13 +0000 |
| commit | db6ac29d0ac769ff780f3901ed987b97965f3f5e (patch) | |
| tree | c7d5f4b06712aefa2a885f338143aec9fe68e322 /lib/Parser/ParserControlFlow.cc | |
| parent | 7ee2b877cf396e680582b4a2d6094d4f3ad89abb (diff) | |
refactor(parser): split expression and control flow parsing
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'lib/Parser/ParserControlFlow.cc')
| -rw-r--r-- | lib/Parser/ParserControlFlow.cc | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/lib/Parser/ParserControlFlow.cc b/lib/Parser/ParserControlFlow.cc new file mode 100644 index 0000000..cb32466 --- /dev/null +++ b/lib/Parser/ParserControlFlow.cc @@ -0,0 +1,146 @@ +#include "cps/Parser.h" +#include "cps/FunctionAST.h" +#include <cstdio> + +using namespace cps; + +std::unique_ptr<StmtAST> Parser::ParseTryStmt() { + getNextToken(); + auto Body = ParseBlock({tok_catch, tok_endtry}); + if (CurTok != tok_catch) { + fprintf(stderr, "error: Expected CATCH in TRY at line %d\n", Lex.getLine()); + return nullptr; + } + getNextToken(); + auto CatchBody = ParseBlock({tok_endtry, tok_catch}); + if (CurTok != tok_endtry) { + fprintf(stderr, "error: Expected ENDTRY after CATCH at line %d\n", Lex.getLine()); + return nullptr; + } + getNextToken(); + return std::make_unique<TryStmtAST>(std::move(Body), std::move(CatchBody)); +} + +std::unique_ptr<StmtAST> Parser::ParseIfStmt() { + getNextToken(); + auto Cond = ParseExpression(); + if (!Cond) return nullptr; + + if (CurTok != tok_then) { + fprintf(stderr, "error: expected THEN\n"); + return nullptr; + } + getNextToken(); + + std::vector<std::unique_ptr<StmtAST>> ThenStmts = ParseBlock({tok_else, tok_endif}); + + std::vector<std::unique_ptr<StmtAST>> ElseStmts; + if (CurTok == tok_else) { + getNextToken(); + ElseStmts = ParseBlock({tok_endif}); + } + + if (CurTok != tok_endif) { + fprintf(stderr, "error: expected ENDIF\n"); + return nullptr; + } + getNextToken(); + + return std::make_unique<IfStmtAST>(std::move(Cond), std::move(ThenStmts), std::move(ElseStmts)); +} + +std::unique_ptr<StmtAST> Parser::ParseWhileStmt() { + getNextToken(); + auto Cond = ParseExpression(); + if (!Cond) return nullptr; + + if (CurTok != tok_do) { + fprintf(stderr, "error: expected DO after WHILE condition\n"); + return nullptr; + } + getNextToken(); + + std::vector<std::unique_ptr<StmtAST>> Body = ParseBlock({tok_endwhile}); + + if (CurTok != tok_endwhile) { + fprintf(stderr, "error: expected ENDWHILE\n"); + return nullptr; + } + getNextToken(); + + return std::make_unique<WhileStmtAST>(std::move(Cond), std::move(Body)); +} + +std::unique_ptr<StmtAST> Parser::ParseRepeatStmt() { + getNextToken(); + + std::vector<std::unique_ptr<StmtAST>> Body = ParseBlock({tok_until}); + + if (CurTok != tok_until) { + fprintf(stderr, "error: expected UNTIL\n"); + return nullptr; + } + getNextToken(); + + auto Cond = ParseExpression(); + if (!Cond) return nullptr; + + return std::make_unique<RepeatStmtAST>(std::move(Body), std::move(Cond)); +} + +std::unique_ptr<StmtAST> Parser::ParseForStmt() { + getNextToken(); + if (CurTok != tok_identifier) { + fprintf(stderr, "error: expected identifier after FOR\n"); + return nullptr; + } + std::string VarName = Lex.IdentifierStr; + getNextToken(); + + if (CurTok != tok_assign) { + fprintf(stderr, "error: expected '<-' in FOR loop\n"); + return nullptr; + } + getNextToken(); + + auto Start = ParseExpression(); + if (!Start) return nullptr; + + if (CurTok != tok_to) { + fprintf(stderr, "error: expected TO in FOR loop\n"); + return nullptr; + } + getNextToken(); + + auto End = ParseExpression(); + if (!End) return nullptr; + + std::unique_ptr<ExprAST> Step = nullptr; + if (CurTok == tok_step) { + getNextToken(); + Step = ParseExpression(); + if (!Step) return nullptr; + } + + std::vector<std::unique_ptr<StmtAST>> Body = ParseBlock({tok_next}); + + if (CurTok != tok_next) { + fprintf(stderr, "error: expected NEXT\n"); + return nullptr; + } + getNextToken(); + + if (CurTok != tok_identifier) { + fprintf(stderr, "error: expected identifier after NEXT (e.g., NEXT %s)\n", VarName.c_str()); + return nullptr; + } + + if (Lex.IdentifierStr != VarName) { + fprintf(stderr, "error: NEXT identifier '%s' does not match FOR variable '%s'\n", + Lex.IdentifierStr.c_str(), VarName.c_str()); + return nullptr; + } + getNextToken(); + + return std::make_unique<ForStmtAST>(VarName, std::move(Start), std::move(End), std::move(Step), std::move(Body)); +} |
