From 59a2bb6acb975d820ab29be63a6f909d6e6ef40f Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sat, 17 Oct 2026 09:09:54 +0000 Subject: feat(parser): parse INCLUDE and GLOBAL blocks Co-Authored-By: Claude Opus 5.5 --- include/cps/AST.h | 15 +++++++++++++++ include/cps/Lexer.h | 2 ++ lib/CodeGen/StatementGen.cc | 5 +++++ lib/Lexer/Lexer.cc | 3 +++ lib/Parser/Parser.cc | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+) diff --git a/include/cps/AST.h b/include/cps/AST.h index f20b106..8c8c3be 100644 --- a/include/cps/AST.h +++ b/include/cps/AST.h @@ -100,6 +100,21 @@ public: virtual ~StmtAST() = default; }; +class IncludeStmtAST : public StmtAST { + std::string Path; +public: + explicit IncludeStmtAST(std::string Path) : Path(std::move(Path)) {} + const std::string &getPath() const { return Path; } +}; + +class GlobalBlockAST : public StmtAST { + std::vector> Body; +public: + explicit GlobalBlockAST(std::vector> Body) + : Body(std::move(Body)) {} + const auto &getBody() const { return Body; } +}; + class TryStmtAST : public StmtAST { std::vector> Body, CatchBody; public: diff --git a/include/cps/Lexer.h b/include/cps/Lexer.h index b465591..957ca48 100644 --- a/include/cps/Lexer.h +++ b/include/cps/Lexer.h @@ -101,6 +101,8 @@ enum Token { tok_c_double = -612, tok_new = -613, tok_delete = -614, + tok_include = -650, tok_global = -651, tok_endglobal = -652, + tok_try = -700, tok_catch = -701, tok_endtry = -702, diff --git a/lib/CodeGen/StatementGen.cc b/lib/CodeGen/StatementGen.cc index df8c396..529f7f0 100644 --- a/lib/CodeGen/StatementGen.cc +++ b/lib/CodeGen/StatementGen.cc @@ -13,6 +13,11 @@ void CodeGen::emitStmt(StmtAST *Stmt) { SaveAndRestore Location(DiagnosticLine, Stmt && Stmt->getLine() ? Stmt->getLine() : DiagnosticLine); if (!Stmt) return; + if (dynamic_cast(Stmt) || dynamic_cast(Stmt)) { + reportError("INCLUDE and GLOBAL are not supported yet"); + return; + } + if (auto *Class = dynamic_cast(Stmt)) { for (const auto &Method : Class->getMethods()) { // Invalid or duplicate members have already been diagnosed. diff --git a/lib/Lexer/Lexer.cc b/lib/Lexer/Lexer.cc index acdedd0..44d40e5 100644 --- a/lib/Lexer/Lexer.cc +++ b/lib/Lexer/Lexer.cc @@ -74,6 +74,9 @@ int Lexer::readToken() { IdentifierStr += static_cast(LastChar); if (IdentifierStr == "CONSTANT") return tok_constant; + if (IdentifierStr == "INCLUDE") return tok_include; + if (IdentifierStr == "GLOBAL") return tok_global; + if (IdentifierStr == "ENDGLOBAL") return tok_endglobal; if (IdentifierStr == "DECLARE") return tok_declare; if (IdentifierStr == "INTEGER") return tok_integer_kw; if (IdentifierStr == "BOOLEAN") return tok_boolean_kw; diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index 826bc89..d4dd18e 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -46,6 +46,7 @@ std::vector> Parser::Parse() { void Parser::syncToStatementStart() { while (CurTok != tok_eof) { switch (CurTok) { + case tok_include: case tok_global: case tok_endglobal: case tok_delete: case tok_constant: case tok_declare: case tok_identifier: case tok_input: case tok_output: case tok_case: case tok_endcase: case tok_otherwise: case tok_if: case tok_while: case tok_repeat: case tok_for: @@ -95,6 +96,37 @@ std::unique_ptr Parser::ParseStatement() { } std::unique_ptr Parser::ParseStatementImpl() { + if (CurTok == tok_include || CurTok == tok_global) { + bool Include = CurTok == tok_include; + int Line = Lex.getLine(); + getNextToken(); + if (BlockDepth != 1) { + sourceDiagnostic(Line, "error: %s is only allowed at top level at line %d\n", + Include ? "INCLUDE" : "GLOBAL", Line); + return nullptr; + } + if (Include) { + if (CurTok != tok_string_literal) { + sourceDiagnostic(Line, "error: INCLUDE requires a string literal at line %d\n", Line); + return nullptr; + } + auto Stmt = std::make_unique(Lex.StringVal); + getNextToken(); + return Stmt; + } + auto Body = ParseBlock({tok_endglobal}); + if (CurTok != tok_endglobal) { + sourceDiagnostic(Line, "error: Expected ENDGLOBAL at line %d\n", Lex.getLine()); + return nullptr; + } + getNextToken(); + return std::make_unique(std::move(Body)); + } + if (CurTok == tok_endglobal) { + sourceDiagnostic(Lex.getLine(), "error: ENDGLOBAL without matching GLOBAL at line %d\n", Lex.getLine()); + getNextToken(); + return nullptr; + } if (CurTok == tok_delete) { int Line = Lex.getLine(); getNextToken(); -- cgit v1.3.1-4-g156e