Construct the parse tree with raw pointers
This commit is contained in:
parent
bbd38a5d26
commit
e8747a803f
@ -262,7 +262,7 @@ namespace source
|
|||||||
*/
|
*/
|
||||||
class declaration : public definition
|
class declaration : public definition
|
||||||
{
|
{
|
||||||
std::unique_ptr<type_expression> m_type;
|
type_expression *m_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -273,10 +273,12 @@ namespace source
|
|||||||
* \param type Declared type.
|
* \param type Declared type.
|
||||||
*/
|
*/
|
||||||
declaration(const struct position position, const std::string& identifier,
|
declaration(const struct position position, const std::string& identifier,
|
||||||
std::unique_ptr<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() noexcept;
|
||||||
|
|
||||||
|
virtual ~declaration() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -284,7 +286,7 @@ namespace source
|
|||||||
*/
|
*/
|
||||||
class constant_definition : public definition
|
class constant_definition : public definition
|
||||||
{
|
{
|
||||||
std::unique_ptr<number_literal<std::int32_t>> m_body;
|
number_literal<std::int32_t> *m_body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -293,10 +295,12 @@ namespace source
|
|||||||
* \param body Constant value.
|
* \param body Constant value.
|
||||||
*/
|
*/
|
||||||
constant_definition(const struct position position, const std::string& identifier,
|
constant_definition(const struct position position, const std::string& identifier,
|
||||||
std::unique_ptr<number_literal<std::int32_t>>&& body);
|
number_literal<std::int32_t> *body);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
number_literal<std::int32_t>& body();
|
number_literal<std::int32_t>& body();
|
||||||
|
|
||||||
|
virtual ~constant_definition() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -304,8 +308,8 @@ namespace source
|
|||||||
*/
|
*/
|
||||||
class procedure_definition : public definition
|
class procedure_definition : public definition
|
||||||
{
|
{
|
||||||
std::unique_ptr<block> m_body;
|
block *m_body;
|
||||||
std::vector<std::unique_ptr<declaration>> m_parameters;
|
std::vector<declaration *> m_parameters;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -314,11 +318,13 @@ namespace source
|
|||||||
* \param body Procedure body.
|
* \param body Procedure body.
|
||||||
*/
|
*/
|
||||||
procedure_definition(const struct position position, const std::string& identifier,
|
procedure_definition(const struct position position, const std::string& identifier,
|
||||||
std::unique_ptr<block>&& body);
|
block *body);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
block& body();
|
block& body();
|
||||||
std::vector<std::unique_ptr<declaration>>& parameters() noexcept;
|
std::vector<declaration *>& parameters() noexcept;
|
||||||
|
|
||||||
|
virtual ~procedure_definition() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,7 +333,7 @@ namespace source
|
|||||||
class call_statement : public statement
|
class call_statement : public statement
|
||||||
{
|
{
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::vector<std::unique_ptr<expression>> m_arguments;
|
std::vector<expression *> m_arguments;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -338,24 +344,28 @@ namespace source
|
|||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
std::string& name() noexcept;
|
std::string& name() noexcept;
|
||||||
std::vector<std::unique_ptr<expression>>& arguments() noexcept;
|
std::vector<expression *>& arguments() noexcept;
|
||||||
|
|
||||||
|
virtual ~call_statement() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class compound_statement : public statement
|
class compound_statement : public statement
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<statement>> m_statements;
|
std::vector<statement *> m_statements;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit compound_statement(const struct position position);
|
explicit compound_statement(const struct position position);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<statement>>& statements();
|
std::vector<statement *>& statements();
|
||||||
|
|
||||||
|
virtual ~compound_statement() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class assign_statement : public statement
|
class assign_statement : public statement
|
||||||
{
|
{
|
||||||
std::string m_lvalue;
|
std::string m_lvalue;
|
||||||
std::unique_ptr<expression> m_rvalue;
|
expression *m_rvalue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -364,11 +374,13 @@ namespace source
|
|||||||
* \param rvalue Assigned expression.
|
* \param rvalue Assigned expression.
|
||||||
*/
|
*/
|
||||||
assign_statement(const struct position position, const std::string& lvalue,
|
assign_statement(const struct position position, const std::string& lvalue,
|
||||||
std::unique_ptr<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() noexcept;
|
||||||
expression& rvalue();
|
expression& rvalue();
|
||||||
|
|
||||||
|
virtual ~assign_statement() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -376,9 +388,9 @@ namespace source
|
|||||||
*/
|
*/
|
||||||
class if_statement : public statement
|
class if_statement : public statement
|
||||||
{
|
{
|
||||||
std::unique_ptr<expression> m_prerequisite;
|
expression *m_prerequisite;
|
||||||
std::unique_ptr<statement> m_body;
|
statement *m_body;
|
||||||
std::unique_ptr<statement> m_alternative;
|
statement *m_alternative;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -387,13 +399,15 @@ namespace source
|
|||||||
* \param body Statement executed if the condition is met.
|
* \param body Statement executed if the condition is met.
|
||||||
* \param alternative Statement executed if the condition is not met.
|
* \param alternative Statement executed if the condition is not met.
|
||||||
*/
|
*/
|
||||||
if_statement(const struct position position, std::unique_ptr<expression>&& prerequisite,
|
if_statement(const struct position position, expression *prerequisite,
|
||||||
std::unique_ptr<statement>&& body, std::unique_ptr<statement>&& alternative = nullptr);
|
statement *body, statement *alternative = nullptr);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
expression& prerequisite();
|
expression& prerequisite();
|
||||||
statement& body();
|
statement& body();
|
||||||
std::unique_ptr<statement>& alternative();
|
statement *alternative();
|
||||||
|
|
||||||
|
virtual ~if_statement() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -401,8 +415,8 @@ namespace source
|
|||||||
*/
|
*/
|
||||||
class while_statement : public statement
|
class while_statement : public statement
|
||||||
{
|
{
|
||||||
std::unique_ptr<expression> m_prerequisite;
|
expression *m_prerequisite;
|
||||||
std::unique_ptr<statement> m_body;
|
statement *m_body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -410,37 +424,41 @@ namespace source
|
|||||||
* \param prerequisite Condition.
|
* \param prerequisite Condition.
|
||||||
* \param body Statement executed while the condition is met.
|
* \param body Statement executed while the condition is met.
|
||||||
*/
|
*/
|
||||||
while_statement(const struct position position, std::unique_ptr<expression>&& prerequisite,
|
while_statement(const struct position position, expression *prerequisite,
|
||||||
std::unique_ptr<statement>&& body);
|
statement *body);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
expression& prerequisite();
|
expression& prerequisite();
|
||||||
statement& body();
|
statement& body();
|
||||||
|
|
||||||
|
virtual ~while_statement() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class block : public node
|
class block : public node
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<definition>> m_definitions;
|
std::vector<definition *> m_definitions;
|
||||||
std::vector<std::unique_ptr<declaration>> m_declarations;
|
std::vector<declaration *> m_declarations;
|
||||||
std::unique_ptr<statement> m_body;
|
statement *m_body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
block(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions,
|
block(const struct position position, std::vector<definition *>&& definitions,
|
||||||
std::vector<std::unique_ptr<declaration>>&& declarations,
|
std::vector<declaration *>&& declarations,
|
||||||
std::unique_ptr<statement>&& body);
|
statement *body);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
statement& body();
|
statement& body();
|
||||||
std::vector<std::unique_ptr<definition>>& definitions() noexcept;
|
std::vector<definition *>& definitions() noexcept;
|
||||||
std::vector<std::unique_ptr<declaration>>& declarations() noexcept;
|
std::vector<declaration *>& declarations() noexcept;
|
||||||
|
|
||||||
|
virtual ~block() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class program : public block
|
class program : public block
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
program(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions,
|
program(const struct position position, std::vector<definition *>&& definitions,
|
||||||
std::vector<std::unique_ptr<declaration>>&& declarations,
|
std::vector<declaration *>&& declarations,
|
||||||
std::unique_ptr<statement>&& body);
|
statement *body);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -501,32 +519,36 @@ namespace source
|
|||||||
|
|
||||||
class binary_expression : public expression
|
class binary_expression : public expression
|
||||||
{
|
{
|
||||||
std::unique_ptr<expression> m_lhs;
|
expression *m_lhs;
|
||||||
std::unique_ptr<expression> m_rhs;
|
expression *m_rhs;
|
||||||
binary_operator m_operator;
|
binary_operator m_operator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
binary_expression(const struct position position, std::unique_ptr<expression>&& lhs,
|
binary_expression(const struct position position, expression *lhs,
|
||||||
std::unique_ptr<expression>&& rhs, const unsigned char operation);
|
expression *rhs, const unsigned char operation);
|
||||||
|
|
||||||
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 noexcept;
|
||||||
|
|
||||||
|
virtual ~binary_expression() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class unary_expression : public expression
|
class unary_expression : public expression
|
||||||
{
|
{
|
||||||
std::unique_ptr<expression> m_operand;
|
expression *m_operand;
|
||||||
unary_operator m_operator;
|
unary_operator m_operator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unary_expression(const struct position position, std::unique_ptr<expression>&& operand,
|
unary_expression(const struct position position, expression *operand,
|
||||||
const unsigned char operation);
|
const unsigned char operation);
|
||||||
|
|
||||||
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 noexcept;
|
||||||
|
|
||||||
|
virtual ~unary_expression() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *print_binary_operator(const binary_operator operation);
|
const char *print_binary_operator(const binary_operator operation);
|
||||||
|
145
source/ast.cc
145
source/ast.cc
@ -18,7 +18,7 @@ namespace source
|
|||||||
|
|
||||||
void empty_visitor::visit(procedure_definition *definition)
|
void empty_visitor::visit(procedure_definition *definition)
|
||||||
{
|
{
|
||||||
for (auto& parameter : definition->parameters())
|
for (auto parameter : definition->parameters())
|
||||||
{
|
{
|
||||||
parameter->accept(this);
|
parameter->accept(this);
|
||||||
}
|
}
|
||||||
@ -211,11 +211,16 @@ namespace source
|
|||||||
}
|
}
|
||||||
|
|
||||||
declaration::declaration(const struct position position, const std::string& identifier,
|
declaration::declaration(const struct position position, const std::string& identifier,
|
||||||
std::unique_ptr<type_expression>&& type)
|
type_expression *type)
|
||||||
: definition(position, identifier), m_type(std::move(type))
|
: definition(position, identifier), m_type(type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declaration::~declaration()
|
||||||
|
{
|
||||||
|
delete m_type;
|
||||||
|
}
|
||||||
|
|
||||||
void declaration::accept(parser_visitor *visitor)
|
void declaration::accept(parser_visitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visit(this);
|
visitor->visit(this);
|
||||||
@ -237,8 +242,8 @@ namespace source
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_definition::constant_definition(const struct position position, const std::string& identifier,
|
constant_definition::constant_definition(const struct position position, const std::string& identifier,
|
||||||
std::unique_ptr<number_literal<std::int32_t>>&& body)
|
number_literal<std::int32_t> *body)
|
||||||
: definition(position, identifier), m_body(std::move(body))
|
: definition(position, identifier), m_body(body)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,9 +257,14 @@ namespace source
|
|||||||
return *m_body;
|
return *m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constant_definition::~constant_definition()
|
||||||
|
{
|
||||||
|
delete m_body;
|
||||||
|
}
|
||||||
|
|
||||||
procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
|
procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
|
||||||
std::unique_ptr<block>&& body)
|
block *body)
|
||||||
: definition(position, identifier), m_body(std::move(body))
|
: definition(position, identifier), m_body(body)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,14 +278,23 @@ namespace source
|
|||||||
return *m_body;
|
return *m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<declaration>>& procedure_definition::parameters() noexcept
|
std::vector<declaration *>& procedure_definition::parameters() noexcept
|
||||||
{
|
{
|
||||||
return m_parameters;
|
return m_parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
block::block(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions,
|
procedure_definition::~procedure_definition()
|
||||||
std::vector<std::unique_ptr<declaration>>&& declarations,
|
{
|
||||||
std::unique_ptr<statement>&& body)
|
delete m_body;
|
||||||
|
for (auto parameter : m_parameters)
|
||||||
|
{
|
||||||
|
delete parameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
block::block(const struct position position, std::vector<definition *>&& definitions,
|
||||||
|
std::vector<declaration *>&& declarations,
|
||||||
|
statement *body)
|
||||||
: node(position), m_definitions(std::move(definitions)),
|
: node(position), m_definitions(std::move(definitions)),
|
||||||
m_declarations(std::move(declarations)), m_body(std::move(body))
|
m_declarations(std::move(declarations)), m_body(std::move(body))
|
||||||
{
|
{
|
||||||
@ -291,20 +310,33 @@ namespace source
|
|||||||
return *m_body;
|
return *m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<definition>>& block::definitions() noexcept
|
std::vector<definition *>& block::definitions() noexcept
|
||||||
{
|
{
|
||||||
return m_definitions;
|
return m_definitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<declaration>>& block::declarations() noexcept
|
std::vector<declaration *>& block::declarations() noexcept
|
||||||
{
|
{
|
||||||
return m_declarations;
|
return m_declarations;
|
||||||
}
|
}
|
||||||
|
|
||||||
program::program(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions,
|
block::~block()
|
||||||
std::vector<std::unique_ptr<declaration>>&& declarations,
|
{
|
||||||
std::unique_ptr<statement>&& body)
|
for (auto definition : m_definitions)
|
||||||
: block(position, std::move(definitions), std::move(declarations), std::move(body))
|
{
|
||||||
|
delete definition;
|
||||||
|
}
|
||||||
|
for (auto declaration : m_declarations)
|
||||||
|
{
|
||||||
|
delete declaration;
|
||||||
|
}
|
||||||
|
delete m_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
program::program(const struct position position, std::vector<definition *>&& definitions,
|
||||||
|
std::vector<declaration *>&& declarations,
|
||||||
|
statement *body)
|
||||||
|
: block(position, std::move(definitions), std::move(declarations), body)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,8 +390,8 @@ namespace source
|
|||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
binary_expression::binary_expression(const struct position position, std::unique_ptr<expression>&& lhs,
|
binary_expression::binary_expression(const struct position position, expression *lhs,
|
||||||
std::unique_ptr<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))
|
||||||
{
|
{
|
||||||
switch (operation)
|
switch (operation)
|
||||||
@ -419,7 +451,13 @@ namespace source
|
|||||||
return m_operator;
|
return m_operator;
|
||||||
}
|
}
|
||||||
|
|
||||||
unary_expression::unary_expression(const struct position position, std::unique_ptr<expression>&& operand,
|
binary_expression::~binary_expression()
|
||||||
|
{
|
||||||
|
delete m_lhs;
|
||||||
|
delete m_rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
unary_expression::unary_expression(const struct position position, expression *operand,
|
||||||
const unsigned char operation)
|
const unsigned char operation)
|
||||||
: expression(position), m_operand(std::move(operand))
|
: expression(position), m_operand(std::move(operand))
|
||||||
{
|
{
|
||||||
@ -451,6 +489,11 @@ namespace source
|
|||||||
return this->m_operator;
|
return this->m_operator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unary_expression::~unary_expression()
|
||||||
|
{
|
||||||
|
delete m_operand;
|
||||||
|
}
|
||||||
|
|
||||||
call_statement::call_statement(const struct position position, const std::string& name)
|
call_statement::call_statement(const struct position position, const std::string& name)
|
||||||
: statement(position), m_name(name)
|
: statement(position), m_name(name)
|
||||||
{
|
{
|
||||||
@ -466,11 +509,19 @@ namespace source
|
|||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<expression>>& call_statement::arguments() noexcept
|
std::vector<expression *>& call_statement::arguments() noexcept
|
||||||
{
|
{
|
||||||
return m_arguments;
|
return m_arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
call_statement::~call_statement()
|
||||||
|
{
|
||||||
|
for (auto argument : m_arguments)
|
||||||
|
{
|
||||||
|
delete argument;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
compound_statement::compound_statement(const struct position position)
|
compound_statement::compound_statement(const struct position position)
|
||||||
: statement(position)
|
: statement(position)
|
||||||
{
|
{
|
||||||
@ -481,19 +532,27 @@ namespace source
|
|||||||
visitor->visit(this);
|
visitor->visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<statement>>& compound_statement::statements()
|
std::vector<statement *>& compound_statement::statements()
|
||||||
{
|
{
|
||||||
return m_statements;
|
return m_statements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compound_statement::~compound_statement()
|
||||||
|
{
|
||||||
|
for (auto statement : m_statements)
|
||||||
|
{
|
||||||
|
delete statement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void assign_statement::accept(parser_visitor *visitor)
|
void assign_statement::accept(parser_visitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visit(this);
|
visitor->visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
assign_statement::assign_statement(const struct position position, const std::string& lvalue,
|
assign_statement::assign_statement(const struct position position, const std::string& lvalue,
|
||||||
std::unique_ptr<expression>&& rvalue)
|
expression *rvalue)
|
||||||
: statement(position), m_lvalue(lvalue), m_rvalue(std::move(rvalue))
|
: statement(position), m_lvalue(lvalue), m_rvalue(rvalue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,10 +566,15 @@ namespace source
|
|||||||
return *m_rvalue;
|
return *m_rvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if_statement::if_statement(const struct position position, std::unique_ptr<expression>&& prerequisite,
|
assign_statement::~assign_statement()
|
||||||
std::unique_ptr<statement>&& body, std::unique_ptr<statement>&& alternative)
|
{
|
||||||
: statement(position), m_prerequisite(std::move(prerequisite)), m_body(std::move(body)),
|
delete m_rvalue;
|
||||||
m_alternative(std::move(alternative))
|
}
|
||||||
|
|
||||||
|
if_statement::if_statement(const struct position position, expression *prerequisite,
|
||||||
|
statement *body, statement *alternative)
|
||||||
|
: statement(position), m_prerequisite(prerequisite), m_body(body),
|
||||||
|
m_alternative(alternative)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,14 +593,25 @@ namespace source
|
|||||||
return *m_body;
|
return *m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<statement>& if_statement::alternative()
|
statement *if_statement::alternative()
|
||||||
{
|
{
|
||||||
return m_alternative;
|
return m_alternative;
|
||||||
}
|
}
|
||||||
|
|
||||||
while_statement::while_statement(const struct position position, std::unique_ptr<expression>&& prerequisite,
|
if_statement::~if_statement()
|
||||||
std::unique_ptr<statement>&& body)
|
{
|
||||||
: statement(position), m_prerequisite(std::move(prerequisite)), m_body(std::move(body))
|
delete m_prerequisite;
|
||||||
|
delete m_body;
|
||||||
|
|
||||||
|
if (m_alternative != nullptr)
|
||||||
|
{
|
||||||
|
delete m_alternative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while_statement::while_statement(const struct position position, expression *prerequisite,
|
||||||
|
statement *body)
|
||||||
|
: statement(position), m_prerequisite(prerequisite), m_body(body)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,6 +630,12 @@ namespace source
|
|||||||
return *m_body;
|
return *m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while_statement::~while_statement()
|
||||||
|
{
|
||||||
|
delete m_prerequisite;
|
||||||
|
delete m_body;
|
||||||
|
}
|
||||||
|
|
||||||
const char *print_binary_operator(const binary_operator operation)
|
const char *print_binary_operator(const binary_operator operation)
|
||||||
{
|
{
|
||||||
switch (operation)
|
switch (operation)
|
||||||
|
186
source/parser.yy
186
source/parser.yy
@ -73,44 +73,44 @@
|
|||||||
%precedence THEN
|
%precedence THEN
|
||||||
%precedence ELSE
|
%precedence ELSE
|
||||||
|
|
||||||
%type <std::unique_ptr<elna::source::number_literal<std::int32_t>>> integer_literal;
|
%type <elna::source::number_literal<std::int32_t> *> integer_literal;
|
||||||
%type <std::unique_ptr<elna::source::number_literal<double>>> float_literal;
|
%type <elna::source::number_literal<double> *> float_literal;
|
||||||
%type <std::unique_ptr<elna::source::number_literal<bool>>> boolean_literal;
|
%type <elna::source::number_literal<bool> *> boolean_literal;
|
||||||
%type <std::unique_ptr<elna::source::char_literal>> character_literal;
|
%type <elna::source::char_literal *> character_literal;
|
||||||
%type <std::unique_ptr<elna::source::string_literal>> string_literal;
|
%type <elna::source::string_literal *> string_literal;
|
||||||
%type <std::unique_ptr<elna::source::constant_definition>> constant_definition;
|
%type <elna::source::constant_definition *> constant_definition;
|
||||||
%type <std::vector<std::unique_ptr<elna::source::constant_definition>>> constant_definition_part constant_definitions;
|
%type <std::vector<elna::source::constant_definition *>> constant_definition_part constant_definitions;
|
||||||
%type <std::unique_ptr<elna::source::declaration>> variable_declaration;
|
%type <elna::source::declaration *> variable_declaration;
|
||||||
%type <std::vector<std::unique_ptr<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 <std::unique_ptr<elna::source::basic_type_expression>> type_expression;
|
%type <elna::source::basic_type_expression *> type_expression;
|
||||||
%type <std::unique_ptr<elna::source::expression>> expression pointer summand factor address comparand;
|
%type <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<elna::source::expression *>> expressions actual_parameter_list;
|
||||||
%type <std::unique_ptr<elna::source::variable_expression>> variable_expression;
|
%type <elna::source::variable_expression *> variable_expression;
|
||||||
%type <std::unique_ptr<elna::source::compound_statement>> compound_statement;
|
%type <elna::source::compound_statement *> compound_statement;
|
||||||
%type <std::unique_ptr<elna::source::assign_statement>> assign_statement;
|
%type <elna::source::assign_statement *> assign_statement;
|
||||||
%type <std::unique_ptr<elna::source::call_statement>> call_statement;
|
%type <elna::source::call_statement *> call_statement;
|
||||||
%type <std::unique_ptr<elna::source::while_statement>> while_statement;
|
%type <elna::source::while_statement *> while_statement;
|
||||||
%type <std::unique_ptr<elna::source::if_statement>> if_statement;
|
%type <elna::source::if_statement *> if_statement;
|
||||||
%type <std::unique_ptr<elna::source::statement>> statement;
|
%type <elna::source::statement *> statement;
|
||||||
%type <std::vector<std::unique_ptr<elna::source::statement>>> statements optional_statements;
|
%type <std::vector<elna::source::statement *>> statements optional_statements;
|
||||||
%type <std::unique_ptr<elna::source::procedure_definition>> procedure_definition;
|
%type <elna::source::procedure_definition *> procedure_definition;
|
||||||
%type <std::vector<std::unique_ptr<elna::source::procedure_definition>>> procedure_definitions
|
%type <std::vector<elna::source::procedure_definition *>> procedure_definitions
|
||||||
procedure_definition_part;
|
procedure_definition_part;
|
||||||
%type <std::unique_ptr<elna::source::block>> block;
|
%type <elna::source::block *> block;
|
||||||
%%
|
%%
|
||||||
program: constant_definition_part procedure_definition_part variable_declaration_part statement DOT
|
program: constant_definition_part procedure_definition_part variable_declaration_part statement DOT
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<elna::source::definition>> definitions($1.size() + $2.size());
|
std::vector<elna::source::definition *> definitions($1.size() + $2.size());
|
||||||
std::vector<std::unique_ptr<elna::source::definition>>::iterator definition = definitions.begin();
|
std::vector<elna::source::definition *>::iterator definition = definitions.begin();
|
||||||
|
|
||||||
for (auto& constant : $1)
|
for (auto& constant : $1)
|
||||||
{
|
{
|
||||||
*definition++ = std::move(constant);
|
*definition++ = constant;
|
||||||
}
|
}
|
||||||
for (auto& procedure : $2)
|
for (auto& procedure : $2)
|
||||||
{
|
{
|
||||||
*definition++ = std::move(procedure);
|
*definition++ = procedure;
|
||||||
}
|
}
|
||||||
driver.tree = std::make_unique<elna::source::program>(elna::source::position{},
|
driver.tree = std::make_unique<elna::source::program>(elna::source::position{},
|
||||||
std::move(definitions), std::move($3),
|
std::move(definitions), std::move($3),
|
||||||
@ -118,21 +118,21 @@ program: constant_definition_part procedure_definition_part variable_declaration
|
|||||||
}
|
}
|
||||||
block: constant_definition_part variable_declaration_part statement
|
block: constant_definition_part variable_declaration_part statement
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<elna::source::definition>> definitions($1.size());
|
std::vector<elna::source::definition *> definitions($1.size());
|
||||||
std::vector<std::unique_ptr<elna::source::definition>>::iterator definition = definitions.begin();
|
std::vector<elna::source::definition *>::iterator definition = definitions.begin();
|
||||||
|
|
||||||
for (auto& constant : $1)
|
for (auto& constant : $1)
|
||||||
{
|
{
|
||||||
*definition++ = std::move(constant);
|
*definition++ = constant;
|
||||||
}
|
}
|
||||||
$$ = std::make_unique<elna::source::block>(elna::source::position{},
|
$$ = new elna::source::block(elna::source::position{},
|
||||||
std::move(definitions), std::move($2), std::move($3));
|
std::move(definitions), std::move($2), std::move($3));
|
||||||
};
|
};
|
||||||
procedure_definition:
|
procedure_definition:
|
||||||
PROCEDURE IDENTIFIER formal_parameter_list SEMICOLON block SEMICOLON
|
PROCEDURE IDENTIFIER formal_parameter_list SEMICOLON block SEMICOLON
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::procedure_definition>(elna::source::position{},
|
$$ = new elna::source::procedure_definition(elna::source::position{},
|
||||||
std::move($2), std::move($5));
|
std::move($2), $5);
|
||||||
std::swap($$->parameters(), $3);
|
std::swap($$->parameters(), $3);
|
||||||
};
|
};
|
||||||
procedure_definitions:
|
procedure_definitions:
|
||||||
@ -147,172 +147,172 @@ procedure_definition_part:
|
|||||||
| procedure_definitions { std::swap($$, $1); }
|
| procedure_definitions { std::swap($$, $1); }
|
||||||
integer_literal: INTEGER
|
integer_literal: INTEGER
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::number_literal<std::int32_t>>(elna::source::make_position(@1), $1);
|
$$ = new elna::source::number_literal<std::int32_t>(elna::source::make_position(@1), $1);
|
||||||
};
|
};
|
||||||
float_literal: FLOAT
|
float_literal: FLOAT
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::number_literal<double>>(elna::source::make_position(@1), $1);
|
$$ = new elna::source::number_literal<double>(elna::source::make_position(@1), $1);
|
||||||
};
|
};
|
||||||
character_literal: CHARACTER
|
character_literal: CHARACTER
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::char_literal>(elna::source::make_position(@1), $1.at(0));
|
$$ = new elna::source::char_literal(elna::source::make_position(@1), $1.at(0));
|
||||||
};
|
};
|
||||||
string_literal: STRING
|
string_literal: STRING
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::string_literal>(elna::source::make_position(@1), $1);
|
$$ = new elna::source::string_literal(elna::source::make_position(@1), $1);
|
||||||
};
|
};
|
||||||
boolean_literal: BOOLEAN
|
boolean_literal: BOOLEAN
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::number_literal<bool>>(elna::source::make_position(@1), $1);
|
$$ = new elna::source::number_literal<bool>(elna::source::make_position(@1), $1);
|
||||||
};
|
};
|
||||||
compound_statement: BEGIN_BLOCK optional_statements END_BLOCK
|
compound_statement: BEGIN_BLOCK optional_statements END_BLOCK
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::compound_statement>(elna::source::make_position(@1));
|
$$ = new elna::source::compound_statement(elna::source::make_position(@1));
|
||||||
std::swap($$->statements(), $2);
|
std::swap($$->statements(), $2);
|
||||||
}
|
}
|
||||||
assign_statement: IDENTIFIER ASSIGNMENT expression
|
assign_statement: IDENTIFIER ASSIGNMENT expression
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::assign_statement>(elna::source::make_position(@1), $1, std::move($3));
|
$$ = new elna::source::assign_statement(elna::source::make_position(@1), $1, $3);
|
||||||
}
|
}
|
||||||
call_statement: IDENTIFIER actual_parameter_list
|
call_statement: IDENTIFIER actual_parameter_list
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::call_statement>(elna::source::make_position(@1), $1);
|
$$ = new elna::source::call_statement(elna::source::make_position(@1), $1);
|
||||||
std::swap($$->arguments(), $2);
|
std::swap($$->arguments(), $2);
|
||||||
}
|
}
|
||||||
while_statement: WHILE expression DO statement
|
while_statement: WHILE expression DO statement
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::while_statement>(elna::source::make_position(@1),
|
$$ = new elna::source::while_statement(elna::source::make_position(@1),
|
||||||
std::move($2), std::move($4));
|
$2, $4);
|
||||||
}
|
}
|
||||||
if_statement:
|
if_statement:
|
||||||
IF expression THEN statement
|
IF expression THEN statement
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::if_statement>(elna::source::make_position(@1),
|
$$ = new elna::source::if_statement(elna::source::make_position(@1),
|
||||||
std::move($2), std::move($4));
|
$2, $4);
|
||||||
}
|
}
|
||||||
| IF expression THEN statement ELSE statement
|
| IF expression THEN statement ELSE statement
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::if_statement>(elna::source::make_position(@1),
|
$$ = new elna::source::if_statement(elna::source::make_position(@1),
|
||||||
std::move($2), std::move($4), std::move($6));
|
$2, $4, $6);
|
||||||
}
|
}
|
||||||
pointer:
|
pointer:
|
||||||
integer_literal { $$ = std::move($1); }
|
integer_literal { $$ = $1; }
|
||||||
| float_literal { $$ = std::move($1); }
|
| float_literal { $$ = $1; }
|
||||||
| boolean_literal { $$ = std::move($1); }
|
| boolean_literal { $$ = $1; }
|
||||||
| character_literal { $$ = std::move($1); }
|
| character_literal { $$ = $1; }
|
||||||
| string_literal { $$ = std::move($1); }
|
| string_literal { $$ = $1; }
|
||||||
| variable_expression { $$ = std::move($1); }
|
| variable_expression { $$ = $1; }
|
||||||
| LEFT_PAREN expression RIGHT_PAREN { $$ = std::move($2); }
|
| LEFT_PAREN expression RIGHT_PAREN { $$ = std::move($2); }
|
||||||
summand:
|
summand:
|
||||||
factor { $$ = std::move($1); }
|
factor { $$ = std::move($1); }
|
||||||
| factor MULTIPLICATION factor
|
| factor MULTIPLICATION factor
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), '*');
|
$1, $3, '*');
|
||||||
}
|
}
|
||||||
| factor DIVISION factor
|
| factor DIVISION factor
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), '/');
|
$1, $3, '/');
|
||||||
}
|
}
|
||||||
address:
|
address:
|
||||||
pointer HAT
|
pointer HAT
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::unary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::unary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), '^');
|
$1, '^');
|
||||||
}
|
}
|
||||||
| pointer { $$ = std::move($1); }
|
| pointer { $$ = $1; }
|
||||||
factor:
|
factor:
|
||||||
AT address
|
AT address
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::unary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::unary_expression(elna::source::make_position(@1),
|
||||||
std::move($2), '@');
|
$2, '@');
|
||||||
}
|
}
|
||||||
| address { $$ = std::move($1); }
|
| address { $$ = $1; }
|
||||||
comparand:
|
comparand:
|
||||||
summand PLUS summand
|
summand PLUS summand
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), '+');
|
$1, $3, '+');
|
||||||
}
|
}
|
||||||
| summand MINUS summand
|
| summand MINUS summand
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), '-');
|
$1, $3, '-');
|
||||||
}
|
}
|
||||||
| summand { $$ = std::move($1); }
|
| summand { $$ = std::move($1); }
|
||||||
expression:
|
expression:
|
||||||
comparand EQUALS comparand
|
comparand EQUALS comparand
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), '=');
|
$1, $3, '=');
|
||||||
}
|
}
|
||||||
| comparand NOT_EQUAL comparand
|
| comparand NOT_EQUAL comparand
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), 'n');
|
$1, $3, 'n');
|
||||||
}
|
}
|
||||||
| comparand LESS_THAN comparand
|
| comparand LESS_THAN comparand
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), '<');
|
$1, $3, '<');
|
||||||
}
|
}
|
||||||
| comparand GREATER_THAN comparand
|
| comparand GREATER_THAN comparand
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), '>');
|
$1, $3, '>');
|
||||||
}
|
}
|
||||||
| comparand LESS_EQUAL comparand
|
| comparand LESS_EQUAL comparand
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), '<');
|
$1, $3, '<');
|
||||||
}
|
}
|
||||||
| comparand GREATER_EQUAL comparand
|
| comparand GREATER_EQUAL comparand
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1),
|
$$ = new elna::source::binary_expression(elna::source::make_position(@1),
|
||||||
std::move($1), std::move($3), '>');
|
$1, $3, '>');
|
||||||
}
|
}
|
||||||
| comparand { $$ = std::move($1); }
|
| comparand { $$ = std::move($1); }
|
||||||
expressions:
|
expressions:
|
||||||
expression COMMA expressions
|
expression COMMA expressions
|
||||||
{
|
{
|
||||||
std::swap($$, $3);
|
std::swap($$, $3);
|
||||||
$$.emplace($$.cbegin(), std::move($1));
|
$$.emplace($$.cbegin(), $1);
|
||||||
}
|
}
|
||||||
| expression { $$.emplace_back(std::move($1)); }
|
| expression { $$.emplace_back(std::move($1)); }
|
||||||
variable_expression: IDENTIFIER
|
variable_expression: IDENTIFIER
|
||||||
{ $$ = std::make_unique<elna::source::variable_expression>(elna::source::make_position(@1), $1); }
|
{ $$ = new elna::source::variable_expression(elna::source::make_position(@1), $1); }
|
||||||
statement:
|
statement:
|
||||||
compound_statement { $$ = std::move($1); }
|
compound_statement { $$ = $1; }
|
||||||
| assign_statement { $$ = std::move($1); }
|
| assign_statement { $$ = $1; }
|
||||||
| call_statement { $$ = std::move($1); }
|
| call_statement { $$ = $1; }
|
||||||
| while_statement { $$ = std::move($1); }
|
| while_statement { $$ = $1; }
|
||||||
| if_statement { $$ = std::move($1); }
|
| if_statement { $$ = $1; }
|
||||||
statements:
|
statements:
|
||||||
statement SEMICOLON statements
|
statement SEMICOLON statements
|
||||||
{
|
{
|
||||||
std::swap($$, $3);
|
std::swap($$, $3);
|
||||||
$$.emplace($$.cbegin(), std::move($1));
|
$$.emplace($$.cbegin(), std::move($1));
|
||||||
}
|
}
|
||||||
| statement { $$.emplace_back(std::move($1)); }
|
| statement { $$.emplace_back($1); }
|
||||||
optional_statements:
|
optional_statements:
|
||||||
statements { std::swap($$, $1); }
|
statements { std::swap($$, $1); }
|
||||||
| /* no statements */ {}
|
| /* no statements */ {}
|
||||||
type_expression:
|
type_expression:
|
||||||
IDENTIFIER
|
IDENTIFIER
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<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
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::declaration>(elna::source::make_position(@1),
|
$$ = new elna::source::declaration(elna::source::make_position(@1),
|
||||||
$1, std::move($3));
|
$1, $3);
|
||||||
};
|
};
|
||||||
variable_declarations:
|
variable_declarations:
|
||||||
variable_declaration COMMA variable_declarations
|
variable_declaration COMMA variable_declarations
|
||||||
{
|
{
|
||||||
std::swap($$, $3);
|
std::swap($$, $3);
|
||||||
$$.emplace($$.cbegin(), std::move($1));
|
$$.emplace($$.cbegin(), $1);
|
||||||
}
|
}
|
||||||
| variable_declaration { $$.emplace_back(std::move($1)); }
|
| variable_declaration { $$.emplace_back(std::move($1)); }
|
||||||
variable_declaration_part:
|
variable_declaration_part:
|
||||||
@ -320,8 +320,8 @@ variable_declaration_part:
|
|||||||
| VAR variable_declarations SEMICOLON { std::swap($$, $2); }
|
| VAR variable_declarations SEMICOLON { std::swap($$, $2); }
|
||||||
constant_definition: IDENTIFIER EQUALS integer_literal
|
constant_definition: IDENTIFIER EQUALS integer_literal
|
||||||
{
|
{
|
||||||
$$ = std::make_unique<elna::source::constant_definition>(elna::source::make_position(@1),
|
$$ = new elna::source::constant_definition(elna::source::make_position(@1),
|
||||||
$1, std::move($3));
|
$1, $3);
|
||||||
};
|
};
|
||||||
constant_definitions:
|
constant_definitions:
|
||||||
constant_definition COMMA constant_definitions
|
constant_definition COMMA constant_definitions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user