diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-16 10:09:47 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-16 10:09:47 +0000 |
| commit | e2c65706e61be09ddb7eeb28cd1957acd4317bcf (patch) | |
| tree | 15447a03d67d395a722c5be3f0b05bc9f197197a /lib/Parser | |
| parent | 45c9d37eb27d204a6202b33cb37e890af0171357 (diff) | |
feat(constants): implement literal constants with lexical scope
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'lib/Parser')
| -rw-r--r-- | lib/Parser/Parser.cc | 3 | ||||
| -rw-r--r-- | lib/Parser/ParserType.cc | 33 |
2 files changed, 35 insertions, 1 deletions
diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index 58422fc..d8fecdc 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -45,7 +45,7 @@ std::vector<std::unique_ptr<StmtAST>> Parser::Parse() { void Parser::syncToStatementStart() { while (CurTok != tok_eof) { switch (CurTok) { - case tok_declare: case tok_identifier: case tok_input: case tok_output: + 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: case tok_function: case tok_procedure: case tok_call: case tok_return: @@ -98,6 +98,7 @@ std::unique_ptr<StmtAST> Parser::ParseStatementImpl() { getNextToken(); return nullptr; } + if (CurTok == tok_constant) return ParseConstant(); if (CurTok == tok_declare) { return ParseDeclare(); } diff --git a/lib/Parser/ParserType.cc b/lib/Parser/ParserType.cc index 6c7703c..918b7f6 100644 --- a/lib/Parser/ParserType.cc +++ b/lib/Parser/ParserType.cc @@ -297,3 +297,36 @@ std::unique_ptr<StmtAST> Parser::ParseDeclare() { return std::make_unique<DeclareStmtAST>(Name, TypeStr); } } + +std::unique_ptr<StmtAST> Parser::ParseConstant() { + int Line = Lex.getLine(); + getNextToken(); + if (CurTok != tok_identifier) { + fprintf(stderr, "error: Expected identifier after CONSTANT at line %d\n", Line); + return nullptr; + } + std::string Name = Lex.IdentifierStr; + getNextToken(); + if (CurTok != tok_eq) { + fprintf(stderr, "error: Expected '=' in CONSTANT declaration at line %d\n", Line); + return nullptr; + } + getNextToken(); + bool Negative = CurTok == '-'; + if (Negative) getNextToken(); + bool Numeric = CurTok == tok_number_int || CurTok == tok_number_real; + bool Literal = Numeric || CurTok == tok_true || CurTok == tok_false || + CurTok == tok_string_literal || CurTok == tok_char_literal; + if (!Literal || (Negative && !Numeric)) { + fprintf(stderr, "error: CONSTANT initializer must be a literal at line %d\n", Line); + return nullptr; + } + auto Value = ParsePrimary(); + if (!Value) return nullptr; + if (Negative) Value = std::make_unique<UnaryExprAST>('-', std::move(Value)); + if (GetTokPrecedence() >= 0) { + fprintf(stderr, "error: CONSTANT initializer must be a literal, not an expression, at line %d\n", Line); + return nullptr; + } + return std::make_unique<ConstantStmtAST>(std::move(Name), std::move(Value)); +} |
