From bbd38a5d2600d7ba31f2ae2a6728c7b1b8c95c67 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 5 Jan 2025 00:06:51 +0100 Subject: [PATCH] Make type_expression abstract --- gcc/elna-convert.cc | 2 +- gcc/elna-generic.cc | 15 +++++++++------ include/elna/source/ast.h | 29 ++++++++++++++++++----------- source/ast.cc | 25 ++++++++++++++++++------- source/lexer.ll | 6 ++++++ source/parser.yy | 12 ++++-------- 6 files changed, 56 insertions(+), 33 deletions(-) diff --git a/gcc/elna-convert.cc b/gcc/elna-convert.cc index ad10324..b731494 100644 --- a/gcc/elna-convert.cc +++ b/gcc/elna-convert.cc @@ -8,7 +8,7 @@ /* Creates an expression whose value is that of EXPR, converted to type TYPE. This function implements all reasonable scalar conversions. */ -tree convert(tree type, tree expr) +tree convert(tree /* type */, tree expr) { return expr; } diff --git a/gcc/elna-generic.cc b/gcc/elna-generic.cc index 1783a24..0bb31ed 100644 --- a/gcc/elna-generic.cc +++ b/gcc/elna-generic.cc @@ -285,31 +285,34 @@ namespace gcc void generic_visitor::visit(source::declaration *declaration) { tree declaration_type = error_mark_node; + source::basic_type_expression *basic_type = declaration->type().is_basic(); - if (declaration->type().base() == "Int") + gcc_assert(basic_type != nullptr); + + if (basic_type->base() == "Int") { declaration_type = integer_type_node; } - else if (declaration->type().base() == "Bool") + else if (basic_type->base() == "Bool") { declaration_type = boolean_type_node; } - else if (declaration->type().base() == "Float") + else if (basic_type->base() == "Float") { declaration_type = double_type_node; } - else if (declaration->type().base() == "Char") + else if (basic_type->base() == "Char") { declaration_type = elna_char_type_node; } - else if (declaration->type().base() == "String") + else if (basic_type->base() == "String") { declaration_type = elna_string_type_node; } else { error_at(get_location(&declaration->type().position()), - "type '%s' not declared", declaration->type().base().c_str()); + "type '%s' not declared", basic_type->base().c_str()); return; } auto declaration_location = get_location(&declaration->position()); diff --git a/include/elna/source/ast.h b/include/elna/source/ast.h index ada06e7..e9afadb 100644 --- a/include/elna/source/ast.h +++ b/include/elna/source/ast.h @@ -46,7 +46,7 @@ namespace source class program; class binary_expression; class unary_expression; - class type_expression; + class basic_type_expression; class variable_expression; template class number_literal; @@ -70,7 +70,7 @@ namespace source virtual void visit(program *) = 0; virtual void visit(binary_expression *) = 0; virtual void visit(unary_expression *) = 0; - virtual void visit(type_expression *) = 0; + virtual void visit(basic_type_expression *) = 0; virtual void visit(variable_expression *) = 0; virtual void visit(number_literal *) = 0; virtual void visit(number_literal *) = 0; @@ -96,7 +96,7 @@ namespace source virtual void visit(program *program) override; virtual void visit(binary_expression *expression) override; virtual void visit(unary_expression *expression) override; - virtual void visit(type_expression *) override; + virtual void visit(basic_type_expression *) override; virtual void visit(variable_expression *) override; virtual void visit(number_literal *) override; virtual void visit(number_literal *) override; @@ -223,20 +223,30 @@ namespace source }; /** - * Expression defining a composed type like pointer or an array. + * Some type expression. */ class type_expression : public node + { + public: + virtual basic_type_expression *is_basic(); + + protected: + type_expression(const struct position position); + }; + + /** + * Expression defining a basic type. + */ + class basic_type_expression : public type_expression { std::string m_base; - bool m_pointer{ false }; public: /** * \param position Source code position. * \param name Type name. - * \param is_pointer Whether it is a pointer type. */ - type_expression(const struct position position, const std::string& name, const bool is_pointer = false); + basic_type_expression(const struct position position, const std::string& name); virtual void accept(parser_visitor *visitor) override; /** @@ -244,10 +254,7 @@ namespace source */ const std::string& base() const noexcept; - /** - * \return Whether the type is a pointer. - */ - bool is_pointer() const noexcept; + basic_type_expression *is_basic() override; }; /** diff --git a/source/ast.cc b/source/ast.cc index f3979d3..e8d7eee 100644 --- a/source/ast.cc +++ b/source/ast.cc @@ -87,7 +87,7 @@ namespace source expression->operand().accept(this); } - void empty_visitor::visit(type_expression *) + void empty_visitor::visit(basic_type_expression *) { } @@ -179,24 +179,35 @@ namespace source { } - type_expression::type_expression(const struct position position, const std::string& name, const bool is_pointer) - : node(position), m_base(name), m_pointer(is_pointer) + type_expression::type_expression(const struct position position) + : node(position) { } - void type_expression::accept(parser_visitor *visitor) + basic_type_expression *type_expression::is_basic() + { + return nullptr; + } + + basic_type_expression::basic_type_expression( + const struct position position, const std::string& name) + : type_expression(position), m_base(name) + { + } + + void basic_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - const std::string& type_expression::base() const noexcept + const std::string& basic_type_expression::base() const noexcept { return m_base; } - bool type_expression::is_pointer() const noexcept + basic_type_expression *basic_type_expression::is_basic() { - return m_pointer; + return this; } declaration::declaration(const struct position position, const std::string& identifier, diff --git a/source/lexer.ll b/source/lexer.ll index 7bbc760..4e63adc 100644 --- a/source/lexer.ll +++ b/source/lexer.ll @@ -90,6 +90,12 @@ false { \) { return yy::parser::make_RIGHT_PAREN(this->location); } +\[ { + return yy::parser::make_LEFT_SQUARE(this->location); + } +\] { + return yy::parser::make_RIGHT_SQUARE(this->location); + } \>= { return yy::parser::make_GREATER_EQUAL(this->location); } diff --git a/source/parser.yy b/source/parser.yy index 47b342d..0761ef1 100644 --- a/source/parser.yy +++ b/source/parser.yy @@ -65,7 +65,7 @@ %token IF WHILE DO %token CONST VAR PROCEDURE %token BEGIN_BLOCK END_BLOCK -%token LEFT_PAREN RIGHT_PAREN SEMICOLON DOT COMMA +%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA %token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS %token PLUS MINUS MULTIPLICATION DIVISION %token ASSIGNMENT COLON HAT AT @@ -83,7 +83,7 @@ %type > variable_declaration; %type >> variable_declarations variable_declaration_part formal_parameter_list; -%type > type_expression; +%type > type_expression; %type > expression pointer summand factor address comparand; %type >> expressions actual_parameter_list; %type > variable_expression; @@ -299,13 +299,9 @@ optional_statements: statements { std::swap($$, $1); } | /* no statements */ {} type_expression: - HAT IDENTIFIER + IDENTIFIER { - $$ = std::make_unique(elna::source::make_position(@1), $2, true); - } - | IDENTIFIER - { - $$ = std::make_unique(elna::source::make_position(@1), $1, false); + $$ = std::make_unique(elna::source::make_position(@1), $1); } variable_declaration: IDENTIFIER COLON type_expression {