From 4573880fcc32bd76a72a4ae713190cd997194583 Mon Sep 17 00:00:00 2001 From: ov-4 Date: Thu, 29 Jan 2026 13:02:49 +0000 Subject: Added loop statements, FOR, WHILE and REPEAT --- lib/Parser/Parser.cc | 197 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 139 insertions(+), 58 deletions(-) (limited to 'lib/Parser') diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index 998d50b..7a1af89 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -26,6 +26,22 @@ int Parser::GetTokPrecedence() { return TokPrec; } +int Parser::getNextToken() { + return CurTok = Lex.gettok(); +} + +std::unique_ptr Parser::ParseNumberExpr() { + auto Result = std::make_unique(Lex.NumVal); + getNextToken(); + return Result; +} + +std::unique_ptr Parser::ParseIdentifierExpr() { + std::string IdName = Lex.IdentifierStr; + getNextToken(); + return std::make_unique(IdName); +} + std::unique_ptr Parser::ParseParenExpr() { getNextToken(); auto V = ParseExpression(); @@ -52,9 +68,7 @@ std::unique_ptr Parser::ParsePrimary() { std::unique_ptr Parser::ParseBinOpRHS(int ExprPrec, std::unique_ptr LHS) { while (true) { int TokPrec = GetTokPrecedence(); - - if (TokPrec < ExprPrec) - return LHS; + if (TokPrec < ExprPrec) return LHS; int BinOp = CurTok; getNextToken(); @@ -72,23 +86,6 @@ std::unique_ptr Parser::ParseBinOpRHS(int ExprPrec, std::unique_ptr Parser::ParseNumberExpr() { - auto Result = std::make_unique(Lex.NumVal); - getNextToken(); - return Result; -} - -std::unique_ptr Parser::ParseIdentifierExpr() { - std::string IdName = Lex.IdentifierStr; - getNextToken(); - return std::make_unique(IdName); -} - std::unique_ptr Parser::ParseExpression() { auto LHS = ParsePrimary(); if (!LHS) return nullptr; @@ -97,7 +94,6 @@ std::unique_ptr Parser::ParseExpression() { std::vector> Parser::Parse() { std::vector> Statements; - while (CurTok != tok_eof) { if (auto Stmt = ParseStatement()) { Statements.push_back(std::move(Stmt)); @@ -108,10 +104,8 @@ std::vector> Parser::Parse() { return Statements; } - std::unique_ptr Parser::ParseIfStmt() { getNextToken(); - auto Cond = ParseExpression(); if (!Cond) return nullptr; @@ -121,7 +115,6 @@ std::unique_ptr Parser::ParseIfStmt() { } getNextToken(); - std::vector> ThenStmts; while (CurTok != tok_else && CurTok != tok_endif && CurTok != tok_eof) { auto Stmt = ParseStatement(); @@ -146,69 +139,157 @@ std::unique_ptr Parser::ParseIfStmt() { return std::make_unique(std::move(Cond), std::move(ThenStmts), std::move(ElseStmts)); } +std::unique_ptr 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> Body; + while (CurTok != tok_endwhile && CurTok != tok_eof) { + auto Stmt = ParseStatement(); + if (Stmt) Body.push_back(std::move(Stmt)); + } + + if (CurTok != tok_endwhile) { + fprintf(stderr, "Error: expected ENDWHILE\n"); + return nullptr; + } + getNextToken(); + + return std::make_unique(std::move(Cond), std::move(Body)); +} + +std::unique_ptr Parser::ParseRepeatStmt() { + getNextToken(); + + std::vector> Body; + while (CurTok != tok_until && CurTok != tok_eof) { + auto Stmt = ParseStatement(); + if (Stmt) Body.push_back(std::move(Stmt)); + } + + if (CurTok != tok_until) { + fprintf(stderr, "Error: expected UNTIL\n"); + return nullptr; + } + getNextToken(); + + auto Cond = ParseExpression(); + if (!Cond) return nullptr; + + return std::make_unique(std::move(Body), std::move(Cond)); +} + +std::unique_ptr 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 Step = nullptr; + if (CurTok == tok_step) { + getNextToken(); + Step = ParseExpression(); + } + + std::vector> Body; + while (CurTok != tok_next && CurTok != tok_eof) { + auto Stmt = ParseStatement(); + if (Stmt) Body.push_back(std::move(Stmt)); + } + + 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(VarName, std::move(Start), std::move(End), std::move(Step), std::move(Body)); +} + std::unique_ptr Parser::ParseStatement() { - // DECLARE if (CurTok == tok_declare) { getNextToken(); - if (CurTok != tok_identifier) { - fprintf(stderr, "Error: expected identifier after DECLARE\n"); - return nullptr; - } + if (CurTok != tok_identifier) return nullptr; std::string Name = Lex.IdentifierStr; getNextToken(); - - if (CurTok != tok_colon) { - fprintf(stderr, "Error: expected ':' after identifier\n"); - return nullptr; - } + if (CurTok != tok_colon) return nullptr; getNextToken(); - - if (CurTok != tok_integer_kw) { - fprintf(stderr, "Error: expected INTEGER type\n"); - return nullptr; - } + if (CurTok != tok_integer_kw) return nullptr; getNextToken(); return std::make_unique(Name); } - - // ASSIGNMENT (x <- expr) else if (CurTok == tok_identifier) { std::string Name = Lex.IdentifierStr; - getNextToken(); // eat Name - - if (CurTok != tok_assign) { - fprintf(stderr, "Error: expected '<-' for assignment\n"); - return nullptr; - } getNextToken(); - + if (CurTok != tok_assign) return nullptr; + getNextToken(); auto Expr = ParseExpression(); return std::make_unique(Name, std::move(Expr)); } - - // INPUT else if (CurTok == tok_input) { getNextToken(); - if (CurTok != tok_identifier) { - fprintf(stderr, "Error: expected identifier after INPUT\n"); - return nullptr; - } + if (CurTok != tok_identifier) return nullptr; std::string Name = Lex.IdentifierStr; getNextToken(); return std::make_unique(Name); } - - // OUTPUT else if (CurTok == tok_output) { getNextToken(); auto Expr = ParseExpression(); return std::make_unique(std::move(Expr)); } - - // IF else if (CurTok == tok_if) { return ParseIfStmt(); } + else if (CurTok == tok_while) { + return ParseWhileStmt(); + } + else if (CurTok == tok_repeat) { + return ParseRepeatStmt(); + } + else if (CurTok == tok_for) { + return ParseForStmt(); + } return nullptr; } -- cgit v1.3.1-4-g156e