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..041c617 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); } @@ -416,20 +421,21 @@ variable_declarations: variable_part: /* no variable declarations */ {} | VAR variable_declarations SEMICOLON { std::swap($$, $2); } -constant_definition: IDENTIFIER EQUALS literal +constant_definition: IDENTIFIER EQUALS literal SEMICOLON { $$ = new elna::boot::constant_definition(elna::boot::make_position(@1), $1, $3); } constant_definitions: - constant_definition COMMA constant_definitions + constant_definition constant_definitions { - std::swap($$, $3); + std::swap($$, $2); $$.emplace($$.cbegin(), std::move($1)); } | constant_definition { $$.emplace_back(std::move($1)); } constant_part: /* no constant definitions */ {} - | CONST constant_definitions SEMICOLON { std::swap($$, $2); } + | CONST {} + | CONST constant_definitions { std::swap($$, $2); } type_definition: IDENTIFIER EQUALS type_expression { $$ = new elna::boot::type_definition(elna::boot::make_position(@1), $1, $3); 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..38a7a8b 100644 --- a/source.elna +++ b/source.elna @@ -1,20 +1,20 @@ const - SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2, + SEEK_SET = 0; SEEK_CUR = 1; SEEK_END = 2; - TOKEN_IDENTIFIER = 1, TOKEN_IF = 2, TOKEN_THEN = 3, TOKEN_ELSE = 4, TOKEN_ELSIF = 5, - TOKEN_WHILE = 6, TOKEN_DO = 7, TOKEN_PROC = 8, TOKEN_BEGIN = 9, TOKEN_END = 10, - TOKEN_EXTERN = 11, TOKEN_CONST = 12, TOKEN_VAR = 13, TOKEN_ARRAY = 14, TOKEN_OF = 15, - TOKEN_TYPE = 16, TOKEN_RECORD = 17, TOKEN_UNION = 18, TOKEN_POINTER = 19, TOKEN_TO = 20, - TOKEN_BOOLEAN = 21, TOKEN_NIL = 22, TOKEN_AND = 23, TOKEN_OR = 24, TOKEN_NOT = 25, - TOKEN_RETURN = 26, TOKEN_CAST = 27, TOKEN_AS = 28, TOKEN_SIZEOF = 29, - TOKEN_LEFT_PAREN = 30, TOKEN_RIGHT_PAREN = 31, TOKEN_LEFT_SQUARE = 32, - TOKEN_RIGHT_SQUARE = 33, TOKEN_GREATER_EQUAL = 34, TOKEN_LESS_EQUAL = 35, - TOKEN_GREATER_THAN = 36, TOKEN_LESS_THAN = 37, TOKEN_NOT_EQUAL = 38, TOKEN_EQUAL = 39, - TOKEN_SEMICOLON = 40, TOKEN_DOT = 41, TOKEN_COMMA = 42, - TOKEN_PLUS = 43, TOKEN_MINUS = 44, TOKEN_MULTIPLICATION = 45, TOKEN_DIVISION = 46, - TOKEN_REMAINDER = 47, TOKEN_ASSIGNMENT = 48, TOKEN_COLON = 49, TOKEN_HAT = 50, - TOKEN_AT = 51, TOKEN_COMMENT = 52, TOKEN_INTEGER = 53, TOKEN_WORD = 54, - TOKEN_CHARACTER = 55, TOKEN_STRING = 56; + TOKEN_IDENTIFIER = 1; TOKEN_IF = 2; TOKEN_THEN = 3; TOKEN_ELSE = 4; TOKEN_ELSIF = 5; + TOKEN_WHILE = 6; TOKEN_DO = 7; TOKEN_PROC = 8; TOKEN_BEGIN = 9; TOKEN_END = 10; + TOKEN_EXTERN = 11; TOKEN_CONST = 12; TOKEN_VAR = 13; TOKEN_ARRAY = 14; TOKEN_OF = 15; + TOKEN_TYPE = 16; TOKEN_RECORD = 17; TOKEN_UNION = 18; TOKEN_POINTER = 19; TOKEN_TO = 20; + TOKEN_BOOLEAN = 21; TOKEN_NIL = 22; TOKEN_AND = 23; TOKEN_OR = 24; TOKEN_NOT = 25; + TOKEN_RETURN = 26; TOKEN_CAST = 27; TOKEN_AS = 28; TOKEN_SIZEOF = 29; + TOKEN_LEFT_PAREN = 30; TOKEN_RIGHT_PAREN = 31; TOKEN_LEFT_SQUARE = 32; + TOKEN_RIGHT_SQUARE = 33; TOKEN_GREATER_EQUAL = 34; TOKEN_LESS_EQUAL = 35; + TOKEN_GREATER_THAN = 36; TOKEN_LESS_THAN = 37; TOKEN_NOT_EQUAL = 38; TOKEN_EQUAL = 39; + TOKEN_SEMICOLON = 40; TOKEN_DOT = 41; TOKEN_COMMA = 42; + TOKEN_PLUS = 43; TOKEN_MINUS = 44; TOKEN_MULTIPLICATION = 45; TOKEN_DIVISION = 46; + TOKEN_REMAINDER = 47; TOKEN_ASSIGNMENT = 48; TOKEN_COLON = 49; TOKEN_HAT = 50; + TOKEN_AT = 51; TOKEN_COMMENT = 52; TOKEN_INTEGER = 53; TOKEN_WORD = 54; + TOKEN_CHARACTER = 55; TOKEN_STRING = 56; type Position = record @@ -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