Implement character escape sequences

This commit is contained in:
Eugen Wissner 2025-01-22 20:19:26 +01:00
parent 156506e8fa
commit 0dc95d4466
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
7 changed files with 83 additions and 52 deletions

View File

@ -12,6 +12,9 @@ type
dummy: Int
end;
const
SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2;
proc test_array();
var a: T, x: Int;
begin
@ -66,19 +69,6 @@ begin
end
end;
proc test_not();
var x: Bool;
begin
x := false;
writei("");
if not x then
writei("Test not true.")
else
writei("Test not false")
end
end;
proc test_param(d: Int, e: Int);
begin
writei("");
@ -124,14 +114,14 @@ proc fseek(stream: pointer to FILE, off: Int, whence: Int): Int; extern;
proc ftell(stream: pointer to FILE): Int; extern;
proc fread(ptr: pointer to Char, size: Int, nmemb: Int, stream: pointer to FILE): Int; extern;
proc write(fd: Int, buf: pointer to Char, count: Int): Int; extern;
proc malloc(size: Int): pointer to Char; extern;
proc free(ptr: pointer to Char); extern;
proc calloc(nmemb: Int, size: Int): pointer to Char; extern;
proc memset(ptr: pointer to Char, c: Int, n: Int): pointer to Char; extern;
proc read_source(filename: String): pointer to Char;
const
-- Bug: The procedure doesn't see global constants.
SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2;
var
input_file: pointer to FILE,
source_size: Int,
@ -143,8 +133,7 @@ begin
source_size := ftell(input_file);
fseek(input_file, 0, SEEK_SET);
input := malloc(source_size + 1);
memset(input, 0, source_size + 1);
input := calloc(source_size + 1, 1);
fread(input, source_size, 1, input_file);
fclose(input_file);
@ -152,12 +141,6 @@ begin
return input
end;
-- Bug: "while not is_eof(…) do" is a syntax error.
proc is_not_eof(buffer: pointer to Int): Bool;
begin
return buffer^ /= 0
end;
proc compile();
var
input: pointer to Char,
@ -166,7 +149,7 @@ begin
input := read_source("example.elna");
input_pointer := input;
while is_not_eof(input_pointer) do
while input_pointer^ /= '\0' do
write(0, input_pointer, 1);
input_pointer := input_pointer + 1
end;
@ -179,7 +162,6 @@ begin
test_array();
test_record();
test_if();
test_not();
test_param(8, 7);
test_const_char();
writei(test_return_int());

View File

@ -124,11 +124,14 @@ namespace gcc
void generic_visitor::visit(source::program *program)
{
for (const auto definition : program->value_definitions)
{
definition->accept(this);
}
for (const auto& constant : program->type_definitions)
{
constant->accept(this);
}
tree parameter_types[] = {
integer_type_node,
build_pointer_type(build_pointer_type(char_type_node))
@ -141,10 +144,6 @@ namespace gcc
enter_scope();
for (const auto definition : program->value_definitions)
{
definition->accept(this);
}
for (const auto body_statement : program->body)
{
body_statement->accept(this);

View File

@ -736,7 +736,7 @@ namespace source
public:
unary_expression(const struct position position, expression *operand,
const unsigned char operation);
const unary_operator operation);
virtual void accept(parser_visitor *visitor) override;
expression& operand();

View File

@ -41,6 +41,8 @@ namespace source
{
public:
using symbol_ptr = std::shared_ptr<info<T>>;
using iterator = typename std::unordered_map<std::string, symbol_ptr>::iterator;
using const_iterator = typename std::unordered_map<std::string, symbol_ptr>::const_iterator;
private:
std::unordered_map<std::string, symbol_ptr> entries;
@ -57,6 +59,26 @@ namespace source
{
}
iterator begin()
{
return entries.begin();
}
iterator end()
{
return entries.end();
}
const_iterator cbegin() const
{
return entries.cbegin();
}
const_iterator cend() const
{
return entries.cend();
}
/**
* Looks for symbol in the table by name. Returns nullptr if the symbol
* can not be found.

View File

@ -752,20 +752,9 @@ namespace source
}
unary_expression::unary_expression(const struct position position, expression *operand,
const unsigned char operation)
: expression(position), m_operand(std::move(operand))
const unary_operator operation)
: expression(position), m_operand(std::move(operand)), m_operator(operation)
{
switch (operation)
{
case '@':
this->m_operator = unary_operator::reference;
break;
case '!':
this->m_operator = unary_operator::negation;
break;
default:
__builtin_unreachable();
}
}
void unary_expression::accept(parser_visitor *visitor)

View File

@ -112,13 +112,50 @@ return {
[0-9]+\.[0-9] {
return yy::parser::make_FLOAT(strtof(yytext, NULL), this->location);
}
'[^']' {
return yy::parser::make_CHARACTER(
std::string(yytext, 1, strlen(yytext) - 2), this->location);
'[[:print:]]' {
if (yytext[1] == '\\')
{
REJECT;
}
else
{
return yy::parser::make_CHARACTER(std::string(yytext, 1, 1), this->location);
}
}
'\\[0nabtfrv\\'"?]' {
switch (yytext[2])
{
case 'n':
return yy::parser::make_CHARACTER(std::string("\n"), this->location);
case 'a':
return yy::parser::make_CHARACTER(std::string("\a"), this->location);
case 'b':
return yy::parser::make_CHARACTER(std::string("\b"), this->location);
case 't':
return yy::parser::make_CHARACTER(std::string("\t"), this->location);
case 'f':
return yy::parser::make_CHARACTER(std::string("\f"), this->location);
case 'r':
return yy::parser::make_CHARACTER(std::string("\r"), this->location);
case 'v':
return yy::parser::make_CHARACTER(std::string("\v"), this->location);
case '\\':
return yy::parser::make_CHARACTER(std::string("\\"), this->location);
case '\'':
return yy::parser::make_CHARACTER(std::string("'"), this->location);
case '"':
return yy::parser::make_CHARACTER(std::string("\""), this->location);
case '?':
return yy::parser::make_CHARACTER(std::string("\?"), this->location);
case '0':
return yy::parser::make_CHARACTER(std::string("\0", 1), this->location);
default:
REJECT;
}
}
\"[^\"]*\" {
return yy::parser::make_STRING(
std::string(yytext, 1, strlen(yytext) - 2), this->location);
std::string(yytext, 1, strlen(yytext) - 2), this->location);
}
\( {
return yy::parser::make_LEFT_PAREN(this->location);

View File

@ -227,6 +227,7 @@ literal:
pointer:
literal { $$ = $1; }
| designator_expression { $$ = $1; }
| call_expression { $$ = $1; }
| LEFT_PAREN expression RIGHT_PAREN { $$ = std::move($2); }
summand:
factor { $$ = std::move($1); }
@ -243,11 +244,13 @@ summand:
factor:
AT pointer
{
$$ = new elna::source::unary_expression(elna::source::make_position(@1), $2, '@');
$$ = new elna::source::unary_expression(elna::source::make_position(@1), $2,
elna::source::unary_operator::reference);
}
| NOT pointer
{
$$ = new elna::source::unary_expression(elna::source::make_position(@1), $2, '!');
$$ = new elna::source::unary_expression(elna::source::make_position(@1), $2,
elna::source::unary_operator::negation);
}
| pointer { $$ = $1; }
comparand:
@ -296,7 +299,6 @@ expression:
$$ = new elna::source::binary_expression(elna::source::make_position(@1), $1, $3, 'o');
}
| logical_operand { $$ = $1; }
| call_expression { $$ = $1; }
expressions:
expression COMMA expressions
{