From 93175ba5edb0eacc182f573c4fd4556f089da305 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Fri, 30 Jan 2026 13:28:45 +0000 Subject: Added BYREF and BYVAL --- lib/Parser/ParserFunction.cc | 139 ++++++++++++++++++++++++++++++++++++++++++ lib/Parser/Parser_Function.cc | 129 --------------------------------------- 2 files changed, 139 insertions(+), 129 deletions(-) create mode 100644 lib/Parser/ParserFunction.cc delete mode 100644 lib/Parser/Parser_Function.cc (limited to 'lib/Parser') diff --git a/lib/Parser/ParserFunction.cc b/lib/Parser/ParserFunction.cc new file mode 100644 index 0000000..d689aa6 --- /dev/null +++ b/lib/Parser/ParserFunction.cc @@ -0,0 +1,139 @@ +#include "cps/Parser.h" +#include "cps/FunctionAST.h" +#include + +using namespace cps; + +std::vector> Parser::ParsePrototypeArgs() { + std::vector> Args; + if (CurTok != '(') return Args; + getNextToken(); + + while (CurTok != ')') { + if (CurTok == -1000 || CurTok == -1001) getNextToken(); + + bool IsRef = false; + if (CurTok == tok_byref) { + IsRef = true; + getNextToken(); + } else if (CurTok == tok_byval) { + IsRef = false; + 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.emplace_back(Name, Type, IsRef); + + 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)); +} diff --git a/lib/Parser/Parser_Function.cc b/lib/Parser/Parser_Function.cc deleted file mode 100644 index bdb4ee7..0000000 --- a/lib/Parser/Parser_Function.cc +++ /dev/null @@ -1,129 +0,0 @@ -#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