From 17b32b6bddbfc5659ea1670b2d4c00a2ca8a5812 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 4 Aug 2025 22:49:49 +0200 Subject: [PATCH] Support hexadecimal literals --- boot/driver.cc | 2 +- boot/lexer.ll | 65 +++++++++++++++++++++++++++++++----------------- source/main.elna | 6 +++++ 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/boot/driver.cc b/boot/driver.cc index 2443dbc..c9a8e58 100644 --- a/boot/driver.cc +++ b/boot/driver.cc @@ -117,7 +117,7 @@ namespace elna::boot } ++current_position; } - result.pop_back(); + result.pop_back(); // Remove the terminating quote character. return result; } diff --git a/boot/lexer.ll b/boot/lexer.ll index 5ac68ff..4f697e6 100644 --- a/boot/lexer.ll +++ b/boot/lexer.ll @@ -32,6 +32,10 @@ along with GCC; see the file COPYING3. If not see %x IN_COMMENT +ID1 [A-Za-z_] +ID2 [A-Za-z0-9_] +HIGIT [0-9a-fA-F] + %% %{ this->location.step(); @@ -113,7 +117,7 @@ nil { xor { return yy::parser::make_XOR(this->location); } -or { +or { return yy::parser::make_OR(this->location); } \| { @@ -146,43 +150,58 @@ case { of { return yy::parser::make_OF(this->location); } -[A-Za-z_][A-Za-z0-9_]* { +{ID1}{ID2}* { return yy::parser::make_IDENTIFIER(yytext, this->location); } -#[A-Za-z_][A-Za-z0-9_]* { +#{ID1}{ID2}* { return yy::parser::make_TRAIT(yytext + 1, this->location); } -[0-9]+u { - return yy::parser::make_WORD(strtoul(yytext, NULL, 10), this->location); - } -[0-9]+ { - return yy::parser::make_INTEGER(strtol(yytext, NULL, 10), this->location); - } -[0-9]+\.[0-9] { - return yy::parser::make_FLOAT(strtof(yytext, NULL), this->location); - } -'[[:print:]]' { - if (yytext[1] == '\\' || yytext[1] == '\'') +[[:digit:]]+u { + unsigned long result = strtoul(yytext, NULL, 10); + + if (errno == ERANGE) { REJECT; } else { - return yy::parser::make_CHARACTER(std::string(yytext, 1, 1), this->location); + return yy::parser::make_WORD(result, this->location); } } -'\\x[0-9a-fA-F]{1,2}' { - char character = static_cast(std::stoi(yytext + 3, nullptr, 16)); +[[:digit:]]+ { + long result = strtol(yytext, NULL, 10); - return yy::parser::make_CHARACTER(std::string(&character, 1), this->location); - } -'\\[0nabtfrv\\'"?]' { - char escape = escape_char(yytext[2]); - if (escape == escape_invalid_char) + if (errno == ERANGE) { REJECT; } - return yy::parser::make_CHARACTER(std::string(&escape, 1), this->location); + else + { + return yy::parser::make_INTEGER(result, this->location); + } + } +0x{HIGIT}+ { + unsigned long result = strtoul(yytext, NULL, 16); + + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_WORD(result, this->location); + } + } +[0-9]+\.[0-9] { + return yy::parser::make_FLOAT(strtof(yytext, NULL), this->location); + } +'[[:print:]]+' { + std::optional result = escape_string(yytext); + if (!result.has_value() || result.value().size() != 1) + { + REJECT; + } + return yy::parser::make_CHARACTER(result.value(), this->location); } \"[[:print:]]*\" { std::optional result = escape_string(yytext); diff --git a/source/main.elna b/source/main.elna index 0f3d001..2da63e7 100644 --- a/source/main.elna +++ b/source/main.elna @@ -1074,6 +1074,12 @@ begin return return_code end; +proc f(); +var x: Char; +begin + x := '\x4' +end; + begin exit(process(count, parameters)) end.