From bd799e42b40613983c6e3cb9aedf58866ac68605 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Fri, 30 Jan 2026 13:11:20 +0000 Subject: Added FUNCTION and PROCEDURE --- lib/Parser/Parser.cc | 49 ++++++++++++---- lib/Parser/Parser_Function.cc | 129 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 10 deletions(-) create mode 100644 lib/Parser/Parser_Function.cc (limited to 'lib/Parser') diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index b9396ce..563dd9b 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -1,4 +1,5 @@ #include "cps/Parser.h" +#include "cps/FunctionAST.h" using namespace cps; @@ -40,24 +41,40 @@ std::unique_ptr Parser::ParseIdentifierExpr() { std::string IdName = Lex.IdentifierStr; int Line = Lex.getLine(); getNextToken(); + + if (CurTok == '(') { + getNextToken(); + std::vector> Args; + if (CurTok != ')') { + while (true) { + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; + + if (CurTok == ')') break; + + if (CurTok != ',') { + fprintf(stderr, "Error: Expected ')' or ',' in function call.\n"); + return nullptr; + } + getNextToken(); + } + } + getNextToken(); + return std::make_unique(IdName, std::move(Args)); + } if (CurTok == '[') { getNextToken(); std::vector> Indices; - while (true) { auto Exp = ParseExpression(); if (!Exp) return nullptr; Indices.push_back(std::move(Exp)); - - if (CurTok == ']') { - break; - } - if (CurTok == ',') { - getNextToken(); - continue; - } - fprintf(stderr, "Error: Expected ',' or ']' in array index\n"); + if (CurTok == ']') break; + if (CurTok == ',') { getNextToken(); continue; } + fprintf(stderr, "Error: Expected ',' or ']'\n"); return nullptr; } getNextToken(); @@ -407,6 +424,18 @@ std::unique_ptr Parser::ParseStatement() { else if (CurTok == tok_for) { return ParseForStmt(); } + else if (CurTok == tok_function) { + return ParseFunction(); + } + else if (CurTok == tok_procedure) { + return ParseProcedure(); + } + else if (CurTok == tok_call) { + return ParseCallStmt(); + } + else if (CurTok == tok_return) { + return ParseReturnStmt(); + } return nullptr; } diff --git a/lib/Parser/Parser_Function.cc b/lib/Parser/Parser_Function.cc new file mode 100644 index 0000000..bdb4ee7 --- /dev/null +++ b/lib/Parser/Parser_Function.cc @@ -0,0 +1,129 @@ +#include "cps/Parser.h" +#include "cps/FunctionAST.h" + +using namespace cps; + +std::vector> Parser::ParsePrototypeArgs() { + std::vector> Args; + if (CurTok != '(') return Args; + getNextToken(); + + while (CurTok != ')') { + if (CurTok == -1000 || CurTok == -1001) getNextToken(); + + if (CurTok != tok_identifier) { + fprintf(stderr, "Error: Expected argument name\n"); + return Args; + } + std::string Name = Lex.IdentifierStr; + getNextToken(); + + if (CurTok != tok_colon) { + fprintf(stderr, "Error: Expected ':' after argument name\n"); + return Args; + } + getNextToken(); + + std::string Type = "INTEGER"; + if (CurTok == tok_integer_kw) { + getNextToken(); + } else if (CurTok == tok_identifier) { + Type = Lex.IdentifierStr; + getNextToken(); + } else { + fprintf(stderr, "Error: Expected type (e.g. INTEGER) for argument '%s'\n", Name.c_str()); + return Args; + } + + Args.push_back({Name, Type}); + + if (CurTok == ')') break; + if (CurTok != ',') { + fprintf(stderr, "Error: Expected ',' or ')'\n"); + return Args; + } + getNextToken(); + } + getNextToken(); + return Args; +} + + +std::unique_ptr Parser::ParseFunction() { + getNextToken(); + std::string Name = Lex.IdentifierStr; + getNextToken(); + + auto Args = ParsePrototypeArgs(); + + std::string RetType = "INTEGER"; + if (CurTok == tok_returns) { + getNextToken(); + getNextToken(); + } + + auto Proto = std::make_unique(Name, std::move(Args), RetType); + + std::vector> Body; + while (CurTok != tok_endfunction && CurTok != tok_eof) { + auto Stmt = ParseStatement(); + if (Stmt) Body.push_back(std::move(Stmt)); + else if (CurTok != tok_eof && CurTok != tok_endfunction) getNextToken(); + } + getNextToken(); + + return std::make_unique(std::move(Proto), std::move(Body)); +} + +std::unique_ptr Parser::ParseProcedure() { + getNextToken(); + std::string Name = Lex.IdentifierStr; + getNextToken(); + + auto Args = ParsePrototypeArgs(); + auto Proto = std::make_unique(Name, std::move(Args), "VOID"); + + std::vector> Body; + while (CurTok != tok_endprocedure && CurTok != tok_eof) { + auto Stmt = ParseStatement(); + if (Stmt) Body.push_back(std::move(Stmt)); + else if (CurTok != tok_eof && CurTok != tok_endprocedure) getNextToken(); + } + getNextToken(); + + return std::make_unique(std::move(Proto), std::move(Body)); +} + +std::unique_ptr Parser::ParseCallStmt() { + getNextToken(); + std::string Callee = Lex.IdentifierStr; + getNextToken(); + + std::vector> Args; + if (CurTok == '(') { + getNextToken(); + while (CurTok != ')') { + auto Arg = ParseExpression(); + if (Arg) Args.push_back(std::move(Arg)); + + if (CurTok == ')') break; + if (CurTok != ',') { + fprintf(stderr, "Error: Expected ',' or ')' in call\n"); + return nullptr; + } + getNextToken(); + } + getNextToken(); + } + + return std::make_unique(Callee, std::move(Args)); +} + +std::unique_ptr Parser::ParseReturnStmt() { + getNextToken(); + std::unique_ptr Expr = nullptr; + if (CurTok != tok_endif && CurTok != tok_else && CurTok != tok_endfunction && CurTok != tok_endprocedure) { + Expr = ParseExpression(); + } + return std::make_unique(std::move(Expr)); +} -- cgit v1.3.1-4-g156e