From ef46796d7ceb081e743d765a2326b966f66f7e2a Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 7 Feb 2025 00:56:54 +0100 Subject: [PATCH] Allow expressions in designators --- boot/ast.cc | 9 +++++---- boot/parser.yy | 9 +++++++-- gcc/elna-generic.cc | 3 +++ include/elna/boot/ast.h | 15 ++++++++------- source.elna | 16 ++++++++-------- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/boot/ast.cc b/boot/ast.cc index 49854ae..8b21165 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -576,7 +576,7 @@ namespace boot } array_access_expression::array_access_expression(const struct position position, - designator_expression *base, expression *index) + expression *base, expression *index) : designator_expression(position), m_base(base), m_index(index) { } @@ -591,7 +591,7 @@ namespace boot return *m_index; } - designator_expression& array_access_expression::base() + expression& array_access_expression::base() { return *m_base; } @@ -603,6 +603,7 @@ namespace boot array_access_expression::~array_access_expression() { + delete m_index; delete m_base; } @@ -638,7 +639,7 @@ namespace boot } dereference_expression::dereference_expression(const struct position position, - designator_expression *base) + expression *base) : designator_expression(position), m_base(base) { } @@ -648,7 +649,7 @@ namespace boot visitor->visit(this); } - designator_expression& dereference_expression::base() + expression& dereference_expression::base() { return *m_base; } diff --git a/boot/parser.yy b/boot/parser.yy index f2371ae..5aadd2b 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -328,6 +328,11 @@ unary: $$ = new elna::boot::unary_expression(elna::boot::make_position(@1), $2, elna::boot::unary_operator::negation); } + | MINUS operand + { + $$ = new elna::boot::unary_expression(elna::boot::make_position(@1), $2, + elna::boot::unary_operator::minus); + } | operand { $$ = $1; } expressions: expression COMMA expressions @@ -337,7 +342,7 @@ expressions: } | expression { $$.emplace_back(std::move($1)); } designator_expression: - designator_expression LEFT_SQUARE expression RIGHT_SQUARE + operand LEFT_SQUARE expression RIGHT_SQUARE { $$ = new elna::boot::array_access_expression(elna::boot::make_position(@1), $1, $3); } @@ -345,7 +350,7 @@ designator_expression: { $$ = new elna::boot::field_access_expression(elna::boot::make_position(@2), $1, $3); } - | designator_expression HAT + | operand HAT { $$ = new elna::boot::dereference_expression(elna::boot::make_position(@1), $1); } diff --git a/gcc/elna-generic.cc b/gcc/elna-generic.cc index 79532e5..a352059 100644 --- a/gcc/elna-generic.cc +++ b/gcc/elna-generic.cc @@ -412,6 +412,9 @@ namespace gcc this->current_expression = build1_loc(get_location(&expression->position()), TRUTH_NOT_EXPR, boolean_type_node, this->current_expression); break; + case boot::unary_operator::minus: + this->current_expression = fold_build1(NEGATE_EXPR, TREE_TYPE(this->current_expression), + this->current_expression); } } diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index 18150b1..4e6cfdf 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -33,7 +33,8 @@ namespace boot enum class unary_operator { reference, - negation + negation, + minus }; class variable_declaration; @@ -528,14 +529,14 @@ namespace boot class array_access_expression : public designator_expression { - designator_expression *m_base; + expression *m_base; expression *m_index; public: - array_access_expression(const struct position position, designator_expression *base, expression *index); + array_access_expression(const struct position position, expression *base, expression *index); virtual void accept(parser_visitor *visitor) override; - designator_expression& base(); + expression& base(); expression& index(); array_access_expression *is_array_access() override; @@ -563,13 +564,13 @@ namespace boot class dereference_expression : public designator_expression { - designator_expression *m_base; + expression *m_base; public: - dereference_expression(const struct position position, designator_expression *base); + dereference_expression(const struct position position, expression *base); virtual void accept(parser_visitor *visitor) override; - designator_expression& base(); + expression& base(); dereference_expression *is_dereference() override; diff --git a/source.elna b/source.elna index dfdc30c..9f8474f 100644 --- a/source.elna +++ b/source.elna @@ -73,7 +73,6 @@ proc malloc(size: Word): pointer to Byte; extern; proc free(ptr: pointer to Byte); extern; proc calloc(nmemb: Word, size: Word): pointer to Byte; extern; proc realloc(ptr: pointer to Byte, size: Word): pointer to Byte; extern; -proc reallocarray(ptr: pointer to Byte, n: Word, size: Word): pointer to Byte; extern; proc memset(ptr: pointer to Char, c: Int, n: Int): pointer to Char; extern; @@ -91,6 +90,11 @@ proc exit(code: Int); extern; (* Standard procedures. *) +proc reallocarray(ptr: pointer to Byte, n: Word, size: Word): pointer to Byte; +begin + return realloc(ptr, n * size) +end; + proc write_s(value: String); begin write(0, value, strlen(value)) @@ -128,7 +132,7 @@ begin buffer[n] := cast(cast('0' as Int) + digit as Char); n := n - 1 end; - while n < 10 do + while n < 9 do n := n + 1; write_c(buffer[n]) end @@ -255,7 +259,6 @@ end; proc lex_comment(input: pointer to Char): pointer to Char; var - current: pointer to Char, next: pointer to Char; begin while input^ <> '\0' do @@ -264,7 +267,7 @@ begin if input^ = '*' and next^ = ')' then return next + 1 end; - input := input + 1 + input := next end; return nil end; @@ -286,16 +289,13 @@ end; proc lex_string(input: pointer to Char, current_token: pointer to Token): pointer to Char; var token_end: pointer to Char, - previous: pointer to Char, constructed_string: pointer to Char, token_length: Word, is_valid: Bool; begin token_end := input; - previous := input - 1; - while token_end^ <> '\0' and not (previous^ <> '\\' and token_end^ = '"') do - previous := token_end; + while token_end^ <> '\0' and not ((token_end - 1)^ <> '\\' and token_end^ = '"') do token_end := token_end + 1 end; if token_end^ <> '\"' then