Add pointer and field access nodes
This commit is contained in:
parent
2d61828903
commit
cf4b6b7ccc
@ -49,8 +49,12 @@ namespace source
|
|||||||
class unary_expression;
|
class unary_expression;
|
||||||
class basic_type_expression;
|
class basic_type_expression;
|
||||||
class array_type_expression;
|
class array_type_expression;
|
||||||
|
class pointer_type_expression;
|
||||||
|
class record_type_expression;
|
||||||
class variable_expression;
|
class variable_expression;
|
||||||
class array_access_expression;
|
class array_access_expression;
|
||||||
|
class field_access_expression;
|
||||||
|
class dereference_expression;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class number_literal;
|
class number_literal;
|
||||||
class char_literal;
|
class char_literal;
|
||||||
@ -76,8 +80,12 @@ namespace source
|
|||||||
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(array_type_expression *) = 0;
|
||||||
|
virtual void visit(pointer_type_expression *) = 0;
|
||||||
|
virtual void visit(record_type_expression *) = 0;
|
||||||
virtual void visit(variable_expression *) = 0;
|
virtual void visit(variable_expression *) = 0;
|
||||||
virtual void visit(array_access_expression *) = 0;
|
virtual void visit(array_access_expression *) = 0;
|
||||||
|
virtual void visit(field_access_expression *is_field_access) = 0;
|
||||||
|
virtual void visit(dereference_expression *is_dereference) = 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;
|
||||||
virtual void visit(number_literal<bool> *) = 0;
|
virtual void visit(number_literal<bool> *) = 0;
|
||||||
@ -105,8 +113,12 @@ namespace source
|
|||||||
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 *expression) override;
|
virtual void visit(array_type_expression *expression) override;
|
||||||
|
virtual void visit(pointer_type_expression *) override;
|
||||||
|
virtual void visit(record_type_expression *expression) override;
|
||||||
virtual void visit(variable_expression *) override;
|
virtual void visit(variable_expression *) override;
|
||||||
virtual void visit(array_access_expression *expression) override;
|
virtual void visit(array_access_expression *expression) override;
|
||||||
|
virtual void visit(field_access_expression *is_field_access) override;
|
||||||
|
virtual void visit(dereference_expression *is_dereference) 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;
|
||||||
virtual void visit(number_literal<bool> *) override;
|
virtual void visit(number_literal<bool> *) override;
|
||||||
@ -240,6 +252,8 @@ namespace source
|
|||||||
virtual const std::string& base_name() = 0;
|
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();
|
virtual array_type_expression *is_array();
|
||||||
|
virtual pointer_type_expression *is_pointer();
|
||||||
|
virtual record_type_expression *is_record();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
type_expression(const struct position position);
|
type_expression(const struct position position);
|
||||||
@ -270,22 +284,11 @@ namespace source
|
|||||||
type_expression *m_base;
|
type_expression *m_base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Array size.
|
|
||||||
*/
|
|
||||||
const std::uint32_t 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);
|
array_type_expression(const struct position position, type_expression *base, const std::uint32_t size);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* \return Array base type.
|
|
||||||
*/
|
|
||||||
type_expression& base();
|
type_expression& base();
|
||||||
const std::string& base_name() override;
|
const std::string& base_name() override;
|
||||||
|
|
||||||
@ -294,6 +297,39 @@ namespace source
|
|||||||
virtual ~array_type_expression() override;
|
virtual ~array_type_expression() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class pointer_type_expression : public type_expression
|
||||||
|
{
|
||||||
|
type_expression *m_base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
pointer_type_expression(const struct position position, type_expression *base);
|
||||||
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
|
type_expression& base();
|
||||||
|
const std::string& base_name() override;
|
||||||
|
|
||||||
|
pointer_type_expression *is_pointer() override;
|
||||||
|
|
||||||
|
virtual ~pointer_type_expression() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class record_type_expression : public type_expression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using field_t = std::pair<std::string, type_expression *>;
|
||||||
|
using fields_t = std::vector<field_t>;
|
||||||
|
|
||||||
|
record_type_expression(const struct position position, fields_t&& fields);
|
||||||
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
|
fields_t& fields();
|
||||||
|
|
||||||
|
record_type_expression *is_record() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
fields_t m_fields;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable declaration.
|
* Variable declaration.
|
||||||
*/
|
*/
|
||||||
@ -418,6 +454,8 @@ namespace source
|
|||||||
public:
|
public:
|
||||||
virtual variable_expression *is_variable();
|
virtual variable_expression *is_variable();
|
||||||
virtual array_access_expression *is_array_access();
|
virtual array_access_expression *is_array_access();
|
||||||
|
virtual field_access_expression *is_field_access();
|
||||||
|
virtual dereference_expression *is_dereference();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
designator_expression(const struct position position);
|
designator_expression(const struct position position);
|
||||||
@ -453,6 +491,39 @@ namespace source
|
|||||||
~array_access_expression() override;
|
~array_access_expression() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class field_access_expression : public designator_expression
|
||||||
|
{
|
||||||
|
designator_expression *m_base;
|
||||||
|
std::string m_field;
|
||||||
|
|
||||||
|
public:
|
||||||
|
field_access_expression(const struct position position, designator_expression *base,
|
||||||
|
const std::string& field);
|
||||||
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
|
designator_expression& base();
|
||||||
|
std::string& field();
|
||||||
|
|
||||||
|
field_access_expression *is_field_access() override;
|
||||||
|
|
||||||
|
~field_access_expression() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class dereference_expression : public designator_expression
|
||||||
|
{
|
||||||
|
designator_expression *m_base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
dereference_expression(const struct position position, designator_expression *base);
|
||||||
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
|
designator_expression& base();
|
||||||
|
|
||||||
|
dereference_expression *is_dereference() override;
|
||||||
|
|
||||||
|
~dereference_expression() override;
|
||||||
|
};
|
||||||
|
|
||||||
class assign_statement : public statement
|
class assign_statement : public statement
|
||||||
{
|
{
|
||||||
designator_expression *m_lvalue;
|
designator_expression *m_lvalue;
|
||||||
|
@ -51,23 +51,5 @@ namespace source
|
|||||||
/// Error column in the source text.
|
/// Error column in the source text.
|
||||||
std::size_t column() const noexcept;
|
std::size_t column() const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
class name_collision final : public error
|
|
||||||
{
|
|
||||||
const struct position previous;
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* \param name Symbol name.
|
|
||||||
* \param path Source file name.
|
|
||||||
* \param current Current symbol position.
|
|
||||||
* \param previous Position of the previously defined symbol.
|
|
||||||
*/
|
|
||||||
name_collision(const std::string& name, const char *path,
|
|
||||||
const struct position current, const struct position previous);
|
|
||||||
|
|
||||||
std::string what() const override;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
151
source/ast.cc
151
source/ast.cc
@ -101,6 +101,19 @@ namespace source
|
|||||||
expression->base().accept(this);
|
expression->base().accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void empty_visitor::visit(pointer_type_expression *expression)
|
||||||
|
{
|
||||||
|
expression->base().accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void empty_visitor::visit(record_type_expression *expression)
|
||||||
|
{
|
||||||
|
for (auto& field : expression->fields())
|
||||||
|
{
|
||||||
|
field.second->accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(variable_expression *)
|
void empty_visitor::visit(variable_expression *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -111,6 +124,16 @@ namespace source
|
|||||||
expression->index().accept(this);
|
expression->index().accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void empty_visitor::visit(field_access_expression *expression)
|
||||||
|
{
|
||||||
|
expression->base().accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void empty_visitor::visit(dereference_expression *expression)
|
||||||
|
{
|
||||||
|
expression->base().accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
void empty_visitor::visit(number_literal<std::int32_t> *)
|
void empty_visitor::visit(number_literal<std::int32_t> *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -210,6 +233,16 @@ namespace source
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record_type_expression *type_expression::is_record()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer_type_expression *type_expression::is_pointer()
|
||||||
|
{
|
||||||
|
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_name(name)
|
: type_expression(position), m_name(name)
|
||||||
@ -262,6 +295,57 @@ namespace source
|
|||||||
delete m_base;
|
delete m_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pointer_type_expression::pointer_type_expression(const struct position position, type_expression *base)
|
||||||
|
: type_expression(position), m_base(base)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void pointer_type_expression::accept(parser_visitor *visitor)
|
||||||
|
{
|
||||||
|
visitor->visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
type_expression& pointer_type_expression::base()
|
||||||
|
{
|
||||||
|
return *m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& pointer_type_expression::base_name()
|
||||||
|
{
|
||||||
|
return base().base_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer_type_expression *pointer_type_expression::is_pointer()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer_type_expression::~pointer_type_expression()
|
||||||
|
{
|
||||||
|
delete m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
record_type_expression::record_type_expression(const struct position position,
|
||||||
|
record_type_expression::fields_t&& fields)
|
||||||
|
: type_expression(position), m_fields(std::move(fields))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void record_type_expression::accept(parser_visitor *visitor)
|
||||||
|
{
|
||||||
|
visitor->visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
record_type_expression::fields_t& record_type_expression::fields()
|
||||||
|
{
|
||||||
|
return m_fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
record_type_expression *record_type_expression::is_record()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -504,6 +588,63 @@ namespace source
|
|||||||
delete m_base;
|
delete m_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
field_access_expression::field_access_expression(const struct position position,
|
||||||
|
designator_expression *base, const std::string& field)
|
||||||
|
: designator_expression(position), m_base(base), m_field(field)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void field_access_expression::accept(parser_visitor *visitor)
|
||||||
|
{
|
||||||
|
visitor->visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
designator_expression& field_access_expression::base()
|
||||||
|
{
|
||||||
|
return *m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string& field_access_expression::field()
|
||||||
|
{
|
||||||
|
return m_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
field_access_expression *field_access_expression::is_field_access()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
field_access_expression::~field_access_expression()
|
||||||
|
{
|
||||||
|
delete m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
dereference_expression::dereference_expression(const struct position position,
|
||||||
|
designator_expression *base)
|
||||||
|
: designator_expression(position), m_base(base)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void dereference_expression::accept(parser_visitor *visitor)
|
||||||
|
{
|
||||||
|
visitor->visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
designator_expression& dereference_expression::base()
|
||||||
|
{
|
||||||
|
return *m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
dereference_expression *dereference_expression::is_dereference()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
dereference_expression::~dereference_expression()
|
||||||
|
{
|
||||||
|
delete m_base;
|
||||||
|
}
|
||||||
|
|
||||||
binary_expression::binary_expression(const struct position position, expression *lhs,
|
binary_expression::binary_expression(const struct position position, expression *lhs,
|
||||||
expression *rhs, const unsigned char operation)
|
expression *rhs, const unsigned char operation)
|
||||||
: expression(position), m_lhs(std::move(lhs)), m_rhs(std::move(rhs))
|
: expression(position), m_lhs(std::move(lhs)), m_rhs(std::move(rhs))
|
||||||
@ -680,6 +821,16 @@ namespace source
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
field_access_expression *designator_expression::is_field_access()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
dereference_expression *designator_expression::is_dereference()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
designator_expression& assign_statement::lvalue()
|
designator_expression& assign_statement::lvalue()
|
||||||
{
|
{
|
||||||
return *m_lvalue;
|
return *m_lvalue;
|
||||||
|
@ -70,7 +70,9 @@ of {
|
|||||||
type {
|
type {
|
||||||
return yy::parser::make_TYPE(this->location);
|
return yy::parser::make_TYPE(this->location);
|
||||||
}
|
}
|
||||||
|
record {
|
||||||
|
return yy::parser::make_RECORD(this->location);
|
||||||
|
}
|
||||||
true {
|
true {
|
||||||
return yy::parser::make_BOOLEAN(true, this->location);
|
return yy::parser::make_BOOLEAN(true, this->location);
|
||||||
}
|
}
|
||||||
|
@ -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 ARRAY OF TYPE
|
%token CONST VAR PROCEDURE ARRAY OF TYPE RECORD
|
||||||
%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
|
||||||
@ -315,14 +315,17 @@ type_expression:
|
|||||||
{
|
{
|
||||||
$$ = new elna::source::array_type_expression(elna::source::make_position(@1), $4, $2);
|
$$ = new elna::source::array_type_expression(elna::source::make_position(@1), $4, $2);
|
||||||
}
|
}
|
||||||
|
| HAT type_expression
|
||||||
|
{
|
||||||
|
$$ = new elna::source::pointer_type_expression(elna::source::make_position(@1), $2);
|
||||||
|
}
|
||||||
| IDENTIFIER
|
| 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);
|
||||||
}
|
}
|
||||||
variable_declaration: IDENTIFIER COLON type_expression
|
variable_declaration: IDENTIFIER COLON type_expression
|
||||||
{
|
{
|
||||||
$$ = new elna::source::declaration(elna::source::make_position(@1),
|
$$ = new elna::source::declaration(elna::source::make_position(@1), $1, $3);
|
||||||
$1, $3);
|
|
||||||
};
|
};
|
||||||
variable_declarations:
|
variable_declarations:
|
||||||
variable_declaration COMMA variable_declarations
|
variable_declaration COMMA variable_declarations
|
||||||
|
@ -21,16 +21,5 @@ namespace source
|
|||||||
{
|
{
|
||||||
return this->position.column;
|
return this->position.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
name_collision::name_collision(const std::string& name, const char *path,
|
|
||||||
const struct position current, const struct position previous)
|
|
||||||
: error(path, current), previous(previous), name(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name_collision::what() const
|
|
||||||
{
|
|
||||||
return "Name '" + name + "' was already defined";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user