Make type_expression abstract

This commit is contained in:
Eugen Wissner 2025-01-05 00:06:51 +01:00
parent 98c13f0be3
commit bbd38a5d26
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
6 changed files with 56 additions and 33 deletions

View File

@ -8,7 +8,7 @@
/* Creates an expression whose value is that of EXPR, converted to type TYPE. /* Creates an expression whose value is that of EXPR, converted to type TYPE.
This function implements all reasonable scalar conversions. */ This function implements all reasonable scalar conversions. */
tree convert(tree type, tree expr) tree convert(tree /* type */, tree expr)
{ {
return expr; return expr;
} }

View File

@ -285,31 +285,34 @@ namespace gcc
void generic_visitor::visit(source::declaration *declaration) void generic_visitor::visit(source::declaration *declaration)
{ {
tree declaration_type = error_mark_node; 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; declaration_type = integer_type_node;
} }
else if (declaration->type().base() == "Bool") else if (basic_type->base() == "Bool")
{ {
declaration_type = boolean_type_node; declaration_type = boolean_type_node;
} }
else if (declaration->type().base() == "Float") else if (basic_type->base() == "Float")
{ {
declaration_type = double_type_node; declaration_type = double_type_node;
} }
else if (declaration->type().base() == "Char") else if (basic_type->base() == "Char")
{ {
declaration_type = elna_char_type_node; declaration_type = elna_char_type_node;
} }
else if (declaration->type().base() == "String") else if (basic_type->base() == "String")
{ {
declaration_type = elna_string_type_node; declaration_type = elna_string_type_node;
} }
else else
{ {
error_at(get_location(&declaration->type().position()), 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; return;
} }
auto declaration_location = get_location(&declaration->position()); auto declaration_location = get_location(&declaration->position());

View File

@ -46,7 +46,7 @@ namespace source
class program; class program;
class binary_expression; class binary_expression;
class unary_expression; class unary_expression;
class type_expression; class basic_type_expression;
class variable_expression; class variable_expression;
template<typename T> template<typename T>
class number_literal; class number_literal;
@ -70,7 +70,7 @@ namespace source
virtual void visit(program *) = 0; virtual void visit(program *) = 0;
virtual void visit(binary_expression *) = 0; virtual void visit(binary_expression *) = 0;
virtual void visit(unary_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(variable_expression *) = 0;
virtual void visit(number_literal<std::int32_t> *) = 0; virtual void visit(number_literal<std::int32_t> *) = 0;
virtual void visit(number_literal<double> *) = 0; virtual void visit(number_literal<double> *) = 0;
@ -96,7 +96,7 @@ namespace source
virtual void visit(program *program) override; virtual void visit(program *program) override;
virtual void visit(binary_expression *expression) override; virtual void visit(binary_expression *expression) override;
virtual void visit(unary_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(variable_expression *) override;
virtual void visit(number_literal<std::int32_t> *) override; virtual void visit(number_literal<std::int32_t> *) override;
virtual void visit(number_literal<double> *) override; virtual void visit(number_literal<double> *) 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 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; std::string m_base;
bool m_pointer{ false };
public: public:
/** /**
* \param position Source code position. * \param position Source code position.
* \param name Type name. * \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; virtual void accept(parser_visitor *visitor) override;
/** /**
@ -244,10 +254,7 @@ namespace source
*/ */
const std::string& base() const noexcept; const std::string& base() const noexcept;
/** basic_type_expression *is_basic() override;
* \return Whether the type is a pointer.
*/
bool is_pointer() const noexcept;
}; };
/** /**

View File

@ -87,7 +87,7 @@ namespace source
expression->operand().accept(this); 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) type_expression::type_expression(const struct position position)
: node(position), m_base(name), m_pointer(is_pointer) : 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); visitor->visit(this);
} }
const std::string& type_expression::base() const noexcept const std::string& basic_type_expression::base() const noexcept
{ {
return m_base; 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, declaration::declaration(const struct position position, const std::string& identifier,

View File

@ -90,6 +90,12 @@ false {
\) { \) {
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_RIGHT_SQUARE(this->location);
}
\>= { \>= {
return yy::parser::make_GREATER_EQUAL(this->location); return yy::parser::make_GREATER_EQUAL(this->location);
} }

View File

@ -65,7 +65,7 @@
%token IF WHILE DO %token IF WHILE DO
%token CONST VAR PROCEDURE %token CONST VAR PROCEDURE
%token BEGIN_BLOCK END_BLOCK %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 GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
%token PLUS MINUS MULTIPLICATION DIVISION %token PLUS MINUS MULTIPLICATION DIVISION
%token ASSIGNMENT COLON HAT AT %token ASSIGNMENT COLON HAT AT
@ -83,7 +83,7 @@
%type <std::unique_ptr<elna::source::declaration>> variable_declaration; %type <std::unique_ptr<elna::source::declaration>> variable_declaration;
%type <std::vector<std::unique_ptr<elna::source::declaration>>> variable_declarations variable_declaration_part %type <std::vector<std::unique_ptr<elna::source::declaration>>> variable_declarations variable_declaration_part
formal_parameter_list; formal_parameter_list;
%type <std::unique_ptr<elna::source::type_expression>> type_expression; %type <std::unique_ptr<elna::source::basic_type_expression>> type_expression;
%type <std::unique_ptr<elna::source::expression>> expression pointer summand factor address comparand; %type <std::unique_ptr<elna::source::expression>> expression pointer summand factor address comparand;
%type <std::vector<std::unique_ptr<elna::source::expression>>> expressions actual_parameter_list; %type <std::vector<std::unique_ptr<elna::source::expression>>> expressions actual_parameter_list;
%type <std::unique_ptr<elna::source::variable_expression>> variable_expression; %type <std::unique_ptr<elna::source::variable_expression>> variable_expression;
@ -299,13 +299,9 @@ optional_statements:
statements { std::swap($$, $1); } statements { std::swap($$, $1); }
| /* no statements */ {} | /* no statements */ {}
type_expression: type_expression:
HAT IDENTIFIER IDENTIFIER
{ {
$$ = std::make_unique<elna::source::type_expression>(elna::source::make_position(@1), $2, true); $$ = std::make_unique<elna::source::basic_type_expression>(elna::source::make_position(@1), $1);
}
| IDENTIFIER
{
$$ = std::make_unique<elna::source::type_expression>(elna::source::make_position(@1), $1, false);
} }
variable_declaration: IDENTIFIER COLON type_expression variable_declaration: IDENTIFIER COLON type_expression
{ {