aboutsummaryrefslogtreecommitdiff
path: root/lib/Parser/Parser.cc
diff options
context:
space:
mode:
authorov-4 <hausemasterstream@gmail.com>2026-01-29 13:02:49 +0000
committerov-4 <hausemasterstream@gmail.com>2026-01-29 13:02:49 +0000
commit4573880fcc32bd76a72a4ae713190cd997194583 (patch)
tree3ce19dc8805996f65ba60b0f2144cce89c46ea1f /lib/Parser/Parser.cc
parent73634b66d412735c292b3941d1281ff0a3c9e5a1 (diff)
Added loop statements, FOR, WHILE and REPEAT
Diffstat (limited to 'lib/Parser/Parser.cc')
-rw-r--r--lib/Parser/Parser.cc197
1 files changed, 139 insertions, 58 deletions
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<ExprAST> Parser::ParseNumberExpr() {
+ auto Result = std::make_unique<NumberExprAST>(Lex.NumVal);
+ getNextToken();
+ return Result;
+}
+
+std::unique_ptr<ExprAST> Parser::ParseIdentifierExpr() {
+ std::string IdName = Lex.IdentifierStr;
+ getNextToken();
+ return std::make_unique<VariableExprAST>(IdName);
+}
+
std::unique_ptr<ExprAST> Parser::ParseParenExpr() {
getNextToken();
auto V = ParseExpression();
@@ -52,9 +68,7 @@ std::unique_ptr<ExprAST> Parser::ParsePrimary() {
std::unique_ptr<ExprAST> Parser::ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> 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<ExprAST> Parser::ParseBinOpRHS(int ExprPrec, std::unique_ptr<Exp
}
}
-
-int Parser::getNextToken() {
- return CurTok = Lex.gettok();
-}
-
-std::unique_ptr<ExprAST> Parser::ParseNumberExpr() {
- auto Result = std::make_unique<NumberExprAST>(Lex.NumVal);
- getNextToken();
- return Result;
-}
-
-std::unique_ptr<ExprAST> Parser::ParseIdentifierExpr() {
- std::string IdName = Lex.IdentifierStr;
- getNextToken();
- return std::make_unique<VariableExprAST>(IdName);
-}
-
std::unique_ptr<ExprAST> Parser::ParseExpression() {
auto LHS = ParsePrimary();
if (!LHS) return nullptr;
@@ -97,7 +94,6 @@ std::unique_ptr<ExprAST> Parser::ParseExpression() {
std::vector<std::unique_ptr<StmtAST>> Parser::Parse() {
std::vector<std::unique_ptr<StmtAST>> Statements;
-
while (CurTok != tok_eof) {
if (auto Stmt = ParseStatement()) {
Statements.push_back(std::move(Stmt));
@@ -108,10 +104,8 @@ std::vector<std::unique_ptr<StmtAST>> Parser::Parse() {
return Statements;
}
-
std::unique_ptr<StmtAST> Parser::ParseIfStmt() {
getNextToken();
-
auto Cond = ParseExpression();
if (!Cond) return nullptr;
@@ -121,7 +115,6 @@ std::unique_ptr<StmtAST> Parser::ParseIfStmt() {
}
getNextToken();
-
std::vector<std::unique_ptr<StmtAST>> ThenStmts;
while (CurTok != tok_else && CurTok != tok_endif && CurTok != tok_eof) {
auto Stmt = ParseStatement();
@@ -146,69 +139,157 @@ std::unique_ptr<StmtAST> Parser::ParseIfStmt() {
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;
+ 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<WhileStmtAST>(std::move(Cond), std::move(Body));
+}
+
+std::unique_ptr<StmtAST> Parser::ParseRepeatStmt() {
+ getNextToken();
+
+ std::vector<std::unique_ptr<StmtAST>> 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<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();
+ }
+
+ std::vector<std::unique_ptr<StmtAST>> 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<ForStmtAST>(VarName, std::move(Start), std::move(End), std::move(Step), std::move(Body));
+}
+
std::unique_ptr<StmtAST> 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<DeclareStmtAST>(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<AssignStmtAST>(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<InputStmtAST>(Name);
}
-
- // OUTPUT
else if (CurTok == tok_output) {
getNextToken();
auto Expr = ParseExpression();
return std::make_unique<OutputStmtAST>(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;
}