aboutsummaryrefslogtreecommitdiff
path: root/lib/Parser/ParserExpression.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-16 13:21:05 +0000
committer_ov4 <ov4@ov4.org>2026-10-16 13:21:05 +0000
commite44bdc6a2a0cf624b08046ecc7e5c5d5d9d2d66c (patch)
treef5276cc0dd2f34e4d30a58f80223912265a1c5a0 /lib/Parser/ParserExpression.cc
parente1e789ac0249149a4aa1671f5f9260d488cb617a (diff)
fix(compiler): correct CIE semantics and diagnostic locations
Use standard WHILE headers and default-public class fields, resolve pseudocode identifiers without case sensitivity, and check signed i64 literal boundaries before conversion. Preserve source locations across recursive emission and function diagnostics. Add 22 regression cases and update compiler examples and documentation. Validated all 69 CTest entries with the original Linux Actions seed and verified the release package's embedded, native and IR output paths.
Diffstat (limited to 'lib/Parser/ParserExpression.cc')
-rw-r--r--lib/Parser/ParserExpression.cc42
1 files changed, 38 insertions, 4 deletions
diff --git a/lib/Parser/ParserExpression.cc b/lib/Parser/ParserExpression.cc
index d32c407..b8952a8 100644
--- a/lib/Parser/ParserExpression.cc
+++ b/lib/Parser/ParserExpression.cc
@@ -1,6 +1,7 @@
#include "cps/Parser.h"
#include "cps/FunctionAST.h"
#include <cstdio>
+#include <limits>
using namespace cps;
@@ -13,15 +14,29 @@ int Parser::GetTokPrecedence() {
}
+bool Parser::ParseIntegerValue(bool Negative, int64_t &Out) {
+ const uint64_t Max = uint64_t(std::numeric_limits<int64_t>::max());
+ if (Lex.NumVal > Max + (Negative ? 1u : 0u)) {
+ fprintf(stderr, "error: Integer literal is outside the i64 range at line %d\n", Lex.getLine());
+ getNextToken();
+ return false;
+ }
+ Out = Negative && Lex.NumVal == Max + 1
+ ? std::numeric_limits<int64_t>::min()
+ : Negative ? -static_cast<int64_t>(Lex.NumVal) : static_cast<int64_t>(Lex.NumVal);
+ getNextToken();
+ return true;
+}
+
std::unique_ptr<ExprAST> Parser::ParseNumberExpr() {
if (CurTok == tok_number_real) {
auto Result = std::make_unique<RealExprAST>(Lex.RealVal);
getNextToken();
return Result;
}
- auto Result = std::make_unique<IntegerExprAST>(Lex.NumVal);
- getNextToken();
- return Result;
+ int64_t Value;
+ if (!ParseIntegerValue(false, Value)) return nullptr;
+ return std::make_unique<IntegerExprAST>(Value);
}
std::unique_ptr<ExprAST> Parser::ParseIdentifierExpr() {
@@ -109,7 +124,7 @@ std::unique_ptr<ExprAST> Parser::ParseParenExpr() {
auto V = ParseExpression();
if (!V) return nullptr;
if (CurTok != ')') {
- fprintf(stderr, "error: expected ')'\n");
+ fprintf(stderr, "error: expected ')' at line %d\n", Lex.getLine());
return nullptr;
}
getNextToken();
@@ -117,6 +132,13 @@ std::unique_ptr<ExprAST> Parser::ParseParenExpr() {
}
std::unique_ptr<ExprAST> Parser::ParsePrimary() {
+ int Line = Lex.getLine();
+ auto Expr = ParsePrimaryImpl();
+ if (Expr && !Expr->getLine()) Expr->setLine(Line);
+ return Expr;
+}
+
+std::unique_ptr<ExprAST> Parser::ParsePrimaryImpl() {
switch (CurTok) {
case tok_identifier: return ParseIdentifierExpr();
case tok_number_int: return ParseNumberExpr();
@@ -148,6 +170,13 @@ std::unique_ptr<ExprAST> Parser::ParsePrimary() {
}
std::unique_ptr<ExprAST> Parser::ParseUnary() {
+ int Line = Lex.getLine();
+ auto Expr = ParseUnaryImpl();
+ if (Expr && !Expr->getLine()) Expr->setLine(Line);
+ return Expr;
+}
+
+std::unique_ptr<ExprAST> Parser::ParseUnaryImpl() {
if (CurTok == tok_not) {
getNextToken();
auto Operand = ParseUnary();
@@ -178,6 +207,11 @@ std::unique_ptr<ExprAST> Parser::ParseUnary() {
if (CurTok == '-') {
getNextToken();
+ if (CurTok == tok_number_int) {
+ int64_t Value;
+ if (!ParseIntegerValue(true, Value)) return nullptr;
+ return std::make_unique<IntegerExprAST>(Value);
+ }
auto Operand = ParseUnary();
if (!Operand) return nullptr;
return std::make_unique<UnaryExprAST>('-', std::move(Operand));