Handle array variable declaration

This commit is contained in:
Eugen Wissner 2025-01-06 15:08:23 +01:00
parent e8747a803f
commit ed1bb621d6
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
6 changed files with 178 additions and 77 deletions

View File

@ -282,37 +282,56 @@ namespace gcc
this->current_expression = NULL_TREE; this->current_expression = NULL_TREE;
} }
tree generic_visitor::build_type(source::type_expression& type)
{
if (source::basic_type_expression *basic_type = type.is_basic())
{
if (basic_type->base_name() == "Int")
{
return integer_type_node;
}
else if (basic_type->base_name() == "Bool")
{
return boolean_type_node;
}
else if (basic_type->base_name() == "Float")
{
return double_type_node;
}
else if (basic_type->base_name() == "Char")
{
return elna_char_type_node;
}
else if (basic_type->base_name() == "String")
{
return elna_string_type_node;
}
}
else if (source::array_type_expression *array_type = type.is_array())
{
tree lower_bound = build_int_cst_type(integer_type_node, 0);
tree upper_bound = build_int_cst_type(integer_type_node, array_type->size);
tree base_type = build_type(array_type->base());
if (base_type == NULL_TREE)
{
return NULL_TREE;
}
tree range_type = build_range_type(integer_type_node, lower_bound, upper_bound);
return build_array_type(base_type, range_type);
}
return NULL_TREE;
}
void generic_visitor::visit(source::declaration *declaration) void generic_visitor::visit(source::declaration *declaration)
{ {
tree declaration_type = error_mark_node; tree declaration_type = build_type(declaration->type());
source::basic_type_expression *basic_type = declaration->type().is_basic();
gcc_assert(basic_type != nullptr); if (declaration_type == NULL_TREE)
if (basic_type->base() == "Int")
{
declaration_type = integer_type_node;
}
else if (basic_type->base() == "Bool")
{
declaration_type = boolean_type_node;
}
else if (basic_type->base() == "Float")
{
declaration_type = double_type_node;
}
else if (basic_type->base() == "Char")
{
declaration_type = elna_char_type_node;
}
else if (basic_type->base() == "String")
{
declaration_type = elna_string_type_node;
}
else
{ {
error_at(get_location(&declaration->type().position()), error_at(get_location(&declaration->type().position()),
"type '%s' not declared", basic_type->base().c_str()); "type '%s' not declared", declaration->type().base_name().c_str());
return; return;
} }
auto declaration_location = get_location(&declaration->position()); auto declaration_location = get_location(&declaration->position());

View File

@ -25,6 +25,7 @@ namespace gcc
tree_chain variable_chain; tree_chain variable_chain;
tree build_label_decl(const char *name, location_t loc); tree build_label_decl(const char *name, location_t loc);
tree build_type(source::type_expression& type);
void enter_scope(); void enter_scope();
tree_symbol_mapping leave_scope(); tree_symbol_mapping leave_scope();

View File

@ -47,6 +47,7 @@ namespace source
class binary_expression; class binary_expression;
class unary_expression; class unary_expression;
class basic_type_expression; class basic_type_expression;
class array_type_expression;
class variable_expression; class variable_expression;
template<typename T> template<typename T>
class number_literal; class number_literal;
@ -71,6 +72,7 @@ namespace source
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(basic_type_expression *) = 0; virtual void visit(basic_type_expression *) = 0;
virtual void visit(array_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;
@ -97,6 +99,7 @@ namespace source
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(basic_type_expression *) override; virtual void visit(basic_type_expression *) override;
virtual void visit(array_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;
@ -111,7 +114,7 @@ namespace source
struct operand struct operand
{ {
public: public:
virtual ~operand() noexcept = 0; virtual ~operand() = 0;
}; };
struct integer_operand final : public operand struct integer_operand final : public operand
@ -121,7 +124,7 @@ namespace source
public: public:
explicit integer_operand(const std::int32_t value); explicit integer_operand(const std::int32_t value);
std::int32_t value() const noexcept; std::int32_t value() const;
}; };
class variable_operand final : public operand class variable_operand final : public operand
@ -131,7 +134,7 @@ namespace source
public: public:
explicit variable_operand(const std::string& name); explicit variable_operand(const std::string& name);
const std::string& name() const noexcept; const std::string& name() const;
}; };
struct temporary_variable final : public operand struct temporary_variable final : public operand
@ -141,7 +144,7 @@ namespace source
public: public:
explicit temporary_variable(const std::size_t counter); explicit temporary_variable(const std::size_t counter);
std::size_t counter() const noexcept; std::size_t counter() const;
}; };
struct label_operand final : public operand struct label_operand final : public operand
@ -151,7 +154,7 @@ namespace source
public: public:
explicit label_operand(const std::size_t counter); explicit label_operand(const std::size_t counter);
std::size_t counter() const noexcept; std::size_t counter() const;
}; };
/** /**
@ -168,13 +171,13 @@ namespace source
explicit node(const position position); explicit node(const position position);
public: public:
virtual ~node() noexcept = default; virtual ~node() = default;
virtual void accept(parser_visitor *) = 0; virtual void accept(parser_visitor *) = 0;
/** /**
* \return Node position in the source code. * \return Node position in the source code.
*/ */
const struct position& position() const noexcept; const struct position& position() const;
}; };
class statement : public node class statement : public node
@ -219,7 +222,7 @@ namespace source
/** /**
* \return Definition name. * \return Definition name.
*/ */
std::string& identifier() noexcept; std::string& identifier();
}; };
/** /**
@ -228,7 +231,9 @@ namespace source
class type_expression : public node class type_expression : public node
{ {
public: public:
virtual const std::string& base_name() = 0;
virtual basic_type_expression *is_basic(); virtual basic_type_expression *is_basic();
virtual array_type_expression *is_array();
protected: protected:
type_expression(const struct position position); type_expression(const struct position position);
@ -239,7 +244,7 @@ namespace source
*/ */
class basic_type_expression : public type_expression class basic_type_expression : public type_expression
{ {
std::string m_base; const std::string m_name;
public: public:
/** /**
@ -249,14 +254,40 @@ namespace source
basic_type_expression(const struct position position, const std::string& name); 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;
/** const std::string& base_name() override;
* \return Name of the base type.
*/
const std::string& base() const noexcept;
basic_type_expression *is_basic() override; basic_type_expression *is_basic() override;
}; };
class array_type_expression : public type_expression
{
type_expression *m_base;
public:
/**
* Array size.
*/
const std::uint32_t size;
/**
* \param position Source code position.
* \param name Array base type.
* \param name Array size.
*/
array_type_expression(const struct position position, type_expression *base, const std::uint32_t size);
virtual void accept(parser_visitor *visitor) override;
/**
* \return Array base type.
*/
type_expression& base();
const std::string& base_name() override;
array_type_expression *is_array() override;
virtual ~array_type_expression() override;
};
/** /**
* Variable declaration. * Variable declaration.
*/ */
@ -276,7 +307,7 @@ namespace source
type_expression *type); type_expression *type);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
type_expression& type() noexcept; type_expression& type();
virtual ~declaration() override; virtual ~declaration() override;
}; };
@ -322,7 +353,7 @@ namespace source
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
block& body(); block& body();
std::vector<declaration *>& parameters() noexcept; std::vector<declaration *>& parameters();
virtual ~procedure_definition() override; virtual ~procedure_definition() override;
}; };
@ -343,8 +374,8 @@ namespace source
call_statement(const struct position position, const std::string& name); call_statement(const struct position position, const std::string& name);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
std::string& name() noexcept; std::string& name();
std::vector<expression *>& arguments() noexcept; std::vector<expression *>& arguments();
virtual ~call_statement() override; virtual ~call_statement() override;
}; };
@ -377,7 +408,7 @@ namespace source
expression *rvalue); expression *rvalue);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
std::string& lvalue() noexcept; std::string& lvalue();
expression& rvalue(); expression& rvalue();
virtual ~assign_statement() override; virtual ~assign_statement() override;
@ -447,8 +478,8 @@ namespace source
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
statement& body(); statement& body();
std::vector<definition *>& definitions() noexcept; std::vector<definition *>& definitions();
std::vector<declaration *>& declarations() noexcept; std::vector<declaration *>& declarations();
virtual ~block() override; virtual ~block() override;
}; };
@ -478,7 +509,7 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
T number() const noexcept T number() const
{ {
return m_number; return m_number;
} }
@ -492,7 +523,7 @@ namespace source
char_literal(const struct position position, const unsigned char value); char_literal(const struct position position, const unsigned char value);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
unsigned char character() const noexcept; unsigned char character() const;
}; };
class string_literal : public expression class string_literal : public expression
@ -503,7 +534,7 @@ namespace source
string_literal(const struct position position, const std::string& value); string_literal(const struct position position, const std::string& value);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
const std::string& string() const noexcept; const std::string& string() const;
}; };
class variable_expression : public expression class variable_expression : public expression
@ -514,7 +545,7 @@ namespace source
variable_expression(const struct position position, const std::string& name); variable_expression(const struct position position, const std::string& name);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
const std::string& name() const noexcept; const std::string& name() const;
}; };
class binary_expression : public expression class binary_expression : public expression
@ -530,7 +561,7 @@ namespace source
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
expression& lhs(); expression& lhs();
expression& rhs(); expression& rhs();
binary_operator operation() const noexcept; binary_operator operation() const;
virtual ~binary_expression() override; virtual ~binary_expression() override;
}; };
@ -546,7 +577,7 @@ namespace source
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
expression& operand(); expression& operand();
unary_operator operation() const noexcept; unary_operator operation() const;
virtual ~unary_expression() override; virtual ~unary_expression() override;
}; };

View File

@ -91,6 +91,10 @@ namespace source
{ {
} }
void empty_visitor::visit(array_type_expression *)
{
}
void empty_visitor::visit(variable_expression *) void empty_visitor::visit(variable_expression *)
{ {
} }
@ -115,7 +119,7 @@ namespace source
{ {
} }
operand::~operand() noexcept operand::~operand()
{ {
} }
@ -124,7 +128,7 @@ namespace source
{ {
} }
std::int32_t integer_operand::value() const noexcept std::int32_t integer_operand::value() const
{ {
return m_value; return m_value;
} }
@ -134,7 +138,7 @@ namespace source
{ {
} }
const std::string& variable_operand::name() const noexcept const std::string& variable_operand::name() const
{ {
return m_name; return m_name;
} }
@ -144,7 +148,7 @@ namespace source
{ {
} }
std::size_t temporary_variable::counter() const noexcept std::size_t temporary_variable::counter() const
{ {
return m_counter; return m_counter;
} }
@ -154,7 +158,7 @@ namespace source
{ {
} }
std::size_t label_operand::counter() const noexcept std::size_t label_operand::counter() const
{ {
return m_counter; return m_counter;
} }
@ -164,7 +168,7 @@ namespace source
{ {
} }
const struct position& node::position() const noexcept const struct position& node::position() const
{ {
return this->source_position; return this->source_position;
} }
@ -189,9 +193,14 @@ namespace source
return nullptr; return nullptr;
} }
array_type_expression *type_expression::is_array()
{
return nullptr;
}
basic_type_expression::basic_type_expression( basic_type_expression::basic_type_expression(
const struct position position, const std::string& name) const struct position position, const std::string& name)
: type_expression(position), m_base(name) : type_expression(position), m_name(name)
{ {
} }
@ -200,9 +209,9 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
const std::string& basic_type_expression::base() const noexcept const std::string& basic_type_expression::base_name()
{ {
return m_base; return m_name;
} }
basic_type_expression *basic_type_expression::is_basic() basic_type_expression *basic_type_expression::is_basic()
@ -210,6 +219,37 @@ namespace source
return this; return this;
} }
array_type_expression::array_type_expression(const struct position position, type_expression *base,
const std::uint32_t size)
: type_expression(position), m_base(base), size(size)
{
}
void array_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
type_expression& array_type_expression::base()
{
return *m_base;
}
const std::string& array_type_expression::base_name()
{
return base().base_name();
}
array_type_expression *array_type_expression::is_array()
{
return this;
}
array_type_expression::~array_type_expression()
{
delete m_base;
}
declaration::declaration(const struct position position, const std::string& identifier, declaration::declaration(const struct position position, const std::string& identifier,
type_expression *type) type_expression *type)
: definition(position, identifier), m_type(type) : definition(position, identifier), m_type(type)
@ -226,7 +266,7 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
type_expression& declaration::type() noexcept type_expression& declaration::type()
{ {
return *m_type; return *m_type;
} }
@ -236,7 +276,7 @@ namespace source
{ {
} }
std::string& definition::identifier() noexcept std::string& definition::identifier()
{ {
return m_identifier; return m_identifier;
} }
@ -278,7 +318,7 @@ namespace source
return *m_body; return *m_body;
} }
std::vector<declaration *>& procedure_definition::parameters() noexcept std::vector<declaration *>& procedure_definition::parameters()
{ {
return m_parameters; return m_parameters;
} }
@ -310,12 +350,12 @@ namespace source
return *m_body; return *m_body;
} }
std::vector<definition *>& block::definitions() noexcept std::vector<definition *>& block::definitions()
{ {
return m_definitions; return m_definitions;
} }
std::vector<declaration *>& block::declarations() noexcept std::vector<declaration *>& block::declarations()
{ {
return m_declarations; return m_declarations;
} }
@ -355,7 +395,7 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
unsigned char char_literal::character() const noexcept unsigned char char_literal::character() const
{ {
return m_character; return m_character;
} }
@ -370,7 +410,7 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
const std::string& string_literal::string() const noexcept const std::string& string_literal::string() const
{ {
return m_string; return m_string;
} }
@ -385,7 +425,7 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
const std::string& variable_expression::name() const noexcept const std::string& variable_expression::name() const
{ {
return m_name; return m_name;
} }
@ -446,7 +486,7 @@ namespace source
return *m_rhs; return *m_rhs;
} }
binary_operator binary_expression::operation() const noexcept binary_operator binary_expression::operation() const
{ {
return m_operator; return m_operator;
} }
@ -484,7 +524,7 @@ namespace source
return *m_operand; return *m_operand;
} }
unary_operator unary_expression::operation() const noexcept unary_operator unary_expression::operation() const
{ {
return this->m_operator; return this->m_operator;
} }
@ -504,12 +544,12 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
std::string& call_statement::name() noexcept std::string& call_statement::name()
{ {
return m_name; return m_name;
} }
std::vector<expression *>& call_statement::arguments() noexcept std::vector<expression *>& call_statement::arguments()
{ {
return m_arguments; return m_arguments;
} }
@ -556,7 +596,7 @@ namespace source
{ {
} }
std::string& assign_statement::lvalue() noexcept std::string& assign_statement::lvalue()
{ {
return m_lvalue; return m_lvalue;
} }

View File

@ -61,6 +61,12 @@ const {
var { var {
return yy::parser::make_VAR(this->location); return yy::parser::make_VAR(this->location);
} }
array {
return yy::parser::make_ARRAY(this->location);
}
of {
return yy::parser::make_OF(this->location);
}
true { true {
return yy::parser::make_BOOLEAN(true, this->location); return yy::parser::make_BOOLEAN(true, this->location);
} }

View File

@ -63,7 +63,7 @@
%token <std::string> STRING "string" %token <std::string> STRING "string"
%token <bool> BOOLEAN %token <bool> BOOLEAN
%token IF WHILE DO %token IF WHILE DO
%token CONST VAR PROCEDURE %token CONST VAR PROCEDURE ARRAY OF
%token BEGIN_BLOCK END_BLOCK %token BEGIN_BLOCK END_BLOCK
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE 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
@ -83,7 +83,7 @@
%type <elna::source::declaration *> variable_declaration; %type <elna::source::declaration *> variable_declaration;
%type <std::vector<elna::source::declaration *>> variable_declarations variable_declaration_part %type <std::vector<elna::source::declaration *>> variable_declarations variable_declaration_part
formal_parameter_list; formal_parameter_list;
%type <elna::source::basic_type_expression *> type_expression; %type <elna::source::type_expression *> type_expression;
%type <elna::source::expression *> expression pointer summand factor address comparand; %type <elna::source::expression *> expression pointer summand factor address comparand;
%type <std::vector<elna::source::expression *>> expressions actual_parameter_list; %type <std::vector<elna::source::expression *>> expressions actual_parameter_list;
%type <elna::source::variable_expression *> variable_expression; %type <elna::source::variable_expression *> variable_expression;
@ -299,7 +299,11 @@ optional_statements:
statements { std::swap($$, $1); } statements { std::swap($$, $1); }
| /* no statements */ {} | /* no statements */ {}
type_expression: type_expression:
IDENTIFIER ARRAY INTEGER OF type_expression
{
$$ = new elna::source::array_type_expression(elna::source::make_position(@1), $4, $2);
}
| IDENTIFIER
{ {
$$ = new elna::source::basic_type_expression(elna::source::make_position(@1), $1); $$ = new elna::source::basic_type_expression(elna::source::make_position(@1), $1);
} }