Support hexadecimal literals

This commit is contained in:
2025-08-04 22:49:49 +02:00
parent 4b18a98581
commit b18effbdd8
3 changed files with 282 additions and 235 deletions

View File

@@ -117,7 +117,7 @@ namespace elna::boot
} }
++current_position; ++current_position;
} }
result.pop_back(); result.pop_back(); // Remove the terminating quote character.
return result; return result;
} }

View File

@@ -32,16 +32,21 @@ along with GCC; see the file COPYING3. If not see
%x IN_COMMENT %x IN_COMMENT
ID1 [A-Za-z_]
ID2 [A-Za-z0-9_]
HIGIT [0-9a-fA-F]
BIGIT [01]
%% %%
%{ %{
this->location.step(); this->location.step();
%} %}
<IN_COMMENT>{ <IN_COMMENT>{
\*\) BEGIN(INITIAL); \*\) BEGIN(INITIAL);
[^*\n]+ ; /* Eat comment in chunks. */ [^*\n]+ ; /* Eat comment in chunks. */
\* ; /* Eat the lone star. */ \* ; /* Eat the lone star. */
\n+ { \n+ {
this->location.lines(yyleng); this->location.lines(yyleng);
this->location.step(); this->location.step();
} }
@@ -49,141 +54,177 @@ along with GCC; see the file COPYING3. If not see
\(\* BEGIN(IN_COMMENT); \(\* BEGIN(IN_COMMENT);
[ \t\r] { [ \t\r] {
this->location.step(); this->location.step();
} }
\n+ { \n+ {
this->location.lines(yyleng); this->location.lines(yyleng);
} }
if { if {
return yy::parser::make_IF(this->location); return yy::parser::make_IF(this->location);
} }
then { then {
return yy::parser::make_THEN(this->location); return yy::parser::make_THEN(this->location);
} }
else { else {
return yy::parser::make_ELSE(this->location); return yy::parser::make_ELSE(this->location);
} }
elsif { elsif {
return yy::parser::make_ELSIF(this->location); return yy::parser::make_ELSIF(this->location);
} }
while { while {
return yy::parser::make_WHILE(this->location); return yy::parser::make_WHILE(this->location);
} }
do { do {
return yy::parser::make_DO(this->location); return yy::parser::make_DO(this->location);
} }
proc { proc {
return yy::parser::make_PROCEDURE(this->location); return yy::parser::make_PROCEDURE(this->location);
} }
begin { begin {
return yy::parser::make_BEGIN_BLOCK(this->location); return yy::parser::make_BEGIN_BLOCK(this->location);
} }
end { end {
return yy::parser::make_END_BLOCK(this->location); return yy::parser::make_END_BLOCK(this->location);
} }
extern { extern {
return yy::parser::make_EXTERN(this->location); return yy::parser::make_EXTERN(this->location);
} }
const { const {
return yy::parser::make_CONST(this->location); return yy::parser::make_CONST(this->location);
} }
var { var {
return yy::parser::make_VAR(this->location); return yy::parser::make_VAR(this->location);
} }
type { type {
return yy::parser::make_TYPE(this->location); return yy::parser::make_TYPE(this->location);
} }
record { record {
return yy::parser::make_RECORD(this->location); return yy::parser::make_RECORD(this->location);
} }
union { union {
return yy::parser::make_UNION(this->location); return yy::parser::make_UNION(this->location);
} }
true { true {
return yy::parser::make_BOOLEAN(true, this->location); return yy::parser::make_BOOLEAN(true, this->location);
} }
false { false {
return yy::parser::make_BOOLEAN(false, this->location); return yy::parser::make_BOOLEAN(false, this->location);
} }
nil { nil {
return yy::parser::make_NIL(this->location); return yy::parser::make_NIL(this->location);
} }
\& { \& {
return yy::parser::make_AND(this->location); return yy::parser::make_AND(this->location);
} }
xor { xor {
return yy::parser::make_XOR(this->location); return yy::parser::make_XOR(this->location);
} }
or { or {
return yy::parser::make_OR(this->location); return yy::parser::make_OR(this->location);
} }
\| { \| {
return yy::parser::make_PIPE(this->location); return yy::parser::make_PIPE(this->location);
} }
\~ { \~ {
return yy::parser::make_NOT(this->location); return yy::parser::make_NOT(this->location);
} }
return { return {
return yy::parser::make_RETURN(this->location); return yy::parser::make_RETURN(this->location);
} }
module { module {
return yy::parser::make_MODULE(this->location); return yy::parser::make_MODULE(this->location);
} }
program { program {
return yy::parser::make_PROGRAM(this->location); return yy::parser::make_PROGRAM(this->location);
} }
import { import {
return yy::parser::make_IMPORT(this->location); return yy::parser::make_IMPORT(this->location);
} }
cast { cast {
return yy::parser::make_CAST(this->location); return yy::parser::make_CAST(this->location);
} }
defer { defer {
return yy::parser::make_DEFER(this->location); return yy::parser::make_DEFER(this->location);
} }
case { case {
return yy::parser::make_CASE(this->location); return yy::parser::make_CASE(this->location);
} }
of { of {
return yy::parser::make_OF(this->location); return yy::parser::make_OF(this->location);
} }
[A-Za-z_][A-Za-z0-9_]* { {ID1}{ID2}* {
return yy::parser::make_IDENTIFIER(yytext, this->location); 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); return yy::parser::make_TRAIT(yytext + 1, this->location);
} }
[0-9]+u { [[:digit:]]+u {
return yy::parser::make_WORD(strtoul(yytext, NULL, 10), this->location); unsigned long result = strtoul(yytext, NULL, 10);
}
[0-9]+ { if (errno == ERANGE)
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] == '\'')
{ {
REJECT; REJECT;
} }
else 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}' { [[:digit:]]+ {
char character = static_cast<char>(std::stoi(yytext + 3, nullptr, 16)); long result = strtol(yytext, NULL, 10);
return yy::parser::make_CHARACTER(std::string(&character, 1), this->location); if (errno == ERANGE)
}
'\\[0nabtfrv\\'"?]' {
char escape = escape_char(yytext[2]);
if (escape == escape_invalid_char)
{ {
REJECT; 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);
}
}
0b{BIGIT}+ {
unsigned long result = strtoul(yytext, NULL, 2);
if (errno == ERANGE)
{
REJECT;
}
else
{
return yy::parser::make_WORD(result, this->location);
}
}
[[:digit:]]+\.[[:digit:]]+ {
float result = strtof(yytext, NULL);
if (errno == ERANGE)
{
REJECT;
}
else
{
return yy::parser::make_FLOAT(result, this->location);
}
}
'[[:print:]]+' {
std::optional<std::string> result = escape_string(yytext);
if (!result.has_value() || result.value().size() != 1)
{
REJECT;
}
return yy::parser::make_CHARACTER(result.value(), this->location);
}
\"[[:print:]]*\" { \"[[:print:]]*\" {
std::optional<std::string> result = escape_string(yytext); std::optional<std::string> result = escape_string(yytext);
if (!result.has_value()) if (!result.has_value())
@@ -191,89 +232,89 @@ of {
REJECT; REJECT;
} }
return yy::parser::make_STRING(result.value(), this->location); return yy::parser::make_STRING(result.value(), this->location);
} }
\( { \( {
return yy::parser::make_LEFT_PAREN(this->location); return yy::parser::make_LEFT_PAREN(this->location);
} }
\) { \) {
return yy::parser::make_RIGHT_PAREN(this->location); return yy::parser::make_RIGHT_PAREN(this->location);
} }
\[ { \[ {
return yy::parser::make_LEFT_SQUARE(this->location); return yy::parser::make_LEFT_SQUARE(this->location);
} }
\] { \] {
return yy::parser::make_RIGHT_SQUARE(this->location); return yy::parser::make_RIGHT_SQUARE(this->location);
} }
\<\< { \<\< {
return yy::parser::make_SHIFT_LEFT(this->location); return yy::parser::make_SHIFT_LEFT(this->location);
} }
\>\> { \>\> {
return yy::parser::make_SHIFT_RIGHT(this->location); return yy::parser::make_SHIFT_RIGHT(this->location);
} }
\>= { \>= {
return yy::parser::make_GREATER_EQUAL(this->location); return yy::parser::make_GREATER_EQUAL(this->location);
} }
\<= { \<= {
return yy::parser::make_LESS_EQUAL(this->location); return yy::parser::make_LESS_EQUAL(this->location);
} }
\> { \> {
return yy::parser::make_GREATER_THAN(this->location); return yy::parser::make_GREATER_THAN(this->location);
} }
\< { \< {
return yy::parser::make_LESS_THAN(this->location); return yy::parser::make_LESS_THAN(this->location);
} }
\<\> { \<\> {
return yy::parser::make_NOT_EQUAL(this->location); return yy::parser::make_NOT_EQUAL(this->location);
} }
= { = {
return yy::parser::make_EQUALS(this->location); return yy::parser::make_EQUALS(this->location);
} }
; { ; {
return yy::parser::make_SEMICOLON(this->location); return yy::parser::make_SEMICOLON(this->location);
} }
\. { \. {
return yy::parser::make_DOT(this->location); return yy::parser::make_DOT(this->location);
} }
, { , {
return yy::parser::make_COMMA(this->location); return yy::parser::make_COMMA(this->location);
} }
\+ { \+ {
return yy::parser::make_PLUS(this->location); return yy::parser::make_PLUS(this->location);
} }
\-> { \-> {
return yy::parser::make_ARROW(this->location); return yy::parser::make_ARROW(this->location);
} }
\- { \- {
return yy::parser::make_MINUS(this->location); return yy::parser::make_MINUS(this->location);
} }
\* { \* {
return yy::parser::make_MULTIPLICATION(this->location); return yy::parser::make_MULTIPLICATION(this->location);
} }
\/ { \/ {
return yy::parser::make_DIVISION(this->location); return yy::parser::make_DIVISION(this->location);
} }
% { % {
return yy::parser::make_REMAINDER(this->location); return yy::parser::make_REMAINDER(this->location);
} }
:= { := {
return yy::parser::make_ASSIGNMENT(this->location); return yy::parser::make_ASSIGNMENT(this->location);
} }
: { : {
return yy::parser::make_COLON(this->location); return yy::parser::make_COLON(this->location);
} }
\^ { \^ {
return yy::parser::make_HAT(this->location); return yy::parser::make_HAT(this->location);
} }
@ { @ {
return yy::parser::make_AT(this->location); return yy::parser::make_AT(this->location);
} }
! { ! {
return yy::parser::make_EXCLAMATION(this->location); return yy::parser::make_EXCLAMATION(this->location);
} }
. { . {
std::stringstream ss; std::stringstream ss;
ss << "Illegal character 0x" << std::hex << static_cast<unsigned int>(yytext[0]); ss << "Illegal character 0x" << std::hex << static_cast<unsigned int>(yytext[0]);
driver.add_error<syntax_error>(ss.str(), driver.input_file, this->location); driver.add_error<syntax_error>(ss.str(), driver.input_file, this->location);
} }
%% %%

View File

@@ -1074,6 +1074,12 @@ begin
return return_code return return_code
end; end;
proc f();
var x: Char;
begin
x := '\x4'
end;
begin begin
exit(process(count, parameters)) exit(process(count, parameters))
end. end.