Implement defer
This commit is contained in:
@ -64,7 +64,7 @@ namespace boot
|
||||
class dereference_expression;
|
||||
template<typename T>
|
||||
class number_literal;
|
||||
class string_literal;
|
||||
class defer_statement;
|
||||
|
||||
/**
|
||||
* Interface for AST visitors.
|
||||
@ -83,6 +83,7 @@ namespace boot
|
||||
virtual void visit(if_statement *) = 0;
|
||||
virtual void visit(while_statement *) = 0;
|
||||
virtual void visit(return_statement *) = 0;
|
||||
virtual void visit(defer_statement *) = 0;
|
||||
virtual void visit(block *) = 0;
|
||||
virtual void visit(program *) = 0;
|
||||
virtual void visit(binary_expression *) = 0;
|
||||
@ -102,7 +103,7 @@ namespace boot
|
||||
virtual void visit(number_literal<bool> *) = 0;
|
||||
virtual void visit(number_literal<unsigned char> *) = 0;
|
||||
virtual void visit(number_literal<std::nullptr_t> *) = 0;
|
||||
virtual void visit(string_literal *) = 0;
|
||||
virtual void visit(number_literal<std::string> *) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -122,6 +123,7 @@ namespace boot
|
||||
virtual void visit(if_statement *) override;
|
||||
virtual void visit(while_statement *) override;
|
||||
virtual void visit(return_statement *) override;
|
||||
virtual void visit(defer_statement *defer) override;
|
||||
virtual void visit(block *block) override;
|
||||
virtual void visit(program *program) override;
|
||||
virtual void visit(binary_expression *expression) override;
|
||||
@ -141,7 +143,7 @@ namespace boot
|
||||
virtual void visit(number_literal<bool> *) override;
|
||||
virtual void visit(number_literal<unsigned char> *) override;
|
||||
virtual void visit(number_literal<std::nullptr_t> *) override;
|
||||
virtual void visit(string_literal *) override;
|
||||
virtual void visit(number_literal<std::string> *) override;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -190,22 +192,12 @@ namespace boot
|
||||
*/
|
||||
class definition : public node
|
||||
{
|
||||
std::string m_identifier;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructs a definition identified by some name.
|
||||
*
|
||||
* \param position Source code position.
|
||||
* \param identifier Definition name.
|
||||
*/
|
||||
definition(const struct position position, const std::string& identifier);
|
||||
definition(const struct position position, const std::string& identifier, const bool exported);
|
||||
|
||||
public:
|
||||
/**
|
||||
* \return Definition name.
|
||||
*/
|
||||
std::string& identifier();
|
||||
const std::string identifier;
|
||||
const bool exported;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -316,15 +308,8 @@ namespace boot
|
||||
type_expression *m_type;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs a declaration with a name and a type.
|
||||
*
|
||||
* \param position Source code position.
|
||||
* \param identifier Definition name.
|
||||
* \param type Declared type.
|
||||
*/
|
||||
variable_declaration(const struct position position, const std::string& identifier,
|
||||
type_expression *type);
|
||||
const bool exported, type_expression *type);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
type_expression& type();
|
||||
@ -332,6 +317,9 @@ namespace boot
|
||||
virtual ~variable_declaration() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Literal expression.
|
||||
*/
|
||||
class literal : public expression
|
||||
{
|
||||
protected:
|
||||
@ -352,7 +340,7 @@ namespace boot
|
||||
* \param body Constant value.
|
||||
*/
|
||||
constant_definition(const struct position position, const std::string& identifier,
|
||||
literal *body);
|
||||
const bool exported, literal *body);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
literal& body();
|
||||
@ -371,31 +359,28 @@ namespace boot
|
||||
public:
|
||||
std::vector<variable_declaration *> parameters;
|
||||
|
||||
/**
|
||||
* \param position Source code position.
|
||||
* \param identifier Procedure name.
|
||||
* \param parameters Procedure formal parameters.
|
||||
* \param return_type Return type if any.
|
||||
* \param body Procedure body.
|
||||
*/
|
||||
procedure_definition(const struct position position, const std::string& identifier,
|
||||
std::vector<variable_declaration *>&& parameters,
|
||||
type_expression *return_type = nullptr, block *body = nullptr);
|
||||
const bool exported, type_expression *return_type = nullptr);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
type_expression *return_type();
|
||||
|
||||
block *body();
|
||||
procedure_definition *add_body(block *procedure_body);
|
||||
|
||||
virtual ~procedure_definition() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Type definition.
|
||||
*/
|
||||
class type_definition : public definition
|
||||
{
|
||||
type_expression *m_body;
|
||||
|
||||
public:
|
||||
type_definition(const struct position position, const std::string& identifier,
|
||||
type_expression *expression);
|
||||
const bool exported, type_expression *expression);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
type_expression& body();
|
||||
@ -546,15 +531,15 @@ namespace boot
|
||||
|
||||
class field_access_expression : public designator_expression
|
||||
{
|
||||
designator_expression *m_base;
|
||||
expression *m_base;
|
||||
std::string m_field;
|
||||
|
||||
public:
|
||||
field_access_expression(const struct position position, designator_expression *base,
|
||||
field_access_expression(const struct position position, expression *base,
|
||||
const std::string& field);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
designator_expression& base();
|
||||
expression& base();
|
||||
std::string& field();
|
||||
|
||||
field_access_expression *is_field_access() override;
|
||||
@ -676,21 +661,21 @@ namespace boot
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
T number() const
|
||||
const T& number() const
|
||||
{
|
||||
return m_number;
|
||||
}
|
||||
};
|
||||
|
||||
class string_literal : public literal
|
||||
class defer_statement : public statement
|
||||
{
|
||||
std::string m_string;
|
||||
|
||||
public:
|
||||
string_literal(const struct position position, const std::string& value);
|
||||
std::vector<statement *> statements;
|
||||
|
||||
defer_statement(const struct position position);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
const std::string& string() const;
|
||||
virtual ~defer_statement() override;
|
||||
};
|
||||
|
||||
class binary_expression : public expression
|
||||
|
@ -39,6 +39,8 @@ namespace boot
|
||||
const std::list<std::unique_ptr<struct error>>& errors() const noexcept;
|
||||
};
|
||||
|
||||
std::optional<char> escape_char(char escape);
|
||||
constexpr char escape_invalid_char = '\xff';
|
||||
|
||||
char escape_char(char escape);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "tree.h"
|
||||
#include "tree-iterator.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <forward_list>
|
||||
#include <string>
|
||||
|
||||
namespace elna
|
||||
@ -19,11 +19,10 @@ namespace gcc
|
||||
{
|
||||
class generic_visitor final : public boot::empty_visitor
|
||||
{
|
||||
tree current_statements{ NULL_TREE };
|
||||
std::forward_list<block_scope> scope;
|
||||
tree current_expression{ NULL_TREE };
|
||||
std::shared_ptr<boot::symbol_table<tree>> symbol_map;
|
||||
tree main_fndecl{ NULL_TREE };
|
||||
tree_chain variable_chain;
|
||||
|
||||
tree build_label_decl(const char *name, location_t loc);
|
||||
tree build_type(boot::type_expression& type);
|
||||
@ -58,7 +57,7 @@ namespace gcc
|
||||
void visit(boot::number_literal<bool> *boolean) override;
|
||||
void visit(boot::number_literal<unsigned char> *character) override;
|
||||
void visit(boot::number_literal<std::nullptr_t> *) override;
|
||||
void visit(boot::string_literal *string) override;
|
||||
void visit(boot::number_literal<std::string> *string) override;
|
||||
void visit(boot::binary_expression *expression) override;
|
||||
void visit(boot::unary_expression *expression) override;
|
||||
void visit(boot::constant_definition *definition) override;
|
||||
@ -73,6 +72,7 @@ namespace gcc
|
||||
void visit(boot::while_statement *statement) override;
|
||||
void visit(boot::call_statement *statement) override;
|
||||
void visit(boot::return_statement *statement) override;
|
||||
void visit(boot::defer_statement *statement) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tree.h"
|
||||
#include "tree-iterator.h"
|
||||
|
||||
#include "elna/boot/ast.h"
|
||||
#include "elna/boot/symbol.h"
|
||||
|
||||
enum elna_tree_index
|
||||
{
|
||||
ELNA_TI_STRING_TYPE,
|
||||
ELNA_TI_MAX
|
||||
};
|
||||
|
||||
extern GTY(()) tree elna_global_trees[ELNA_TI_MAX];
|
||||
|
||||
#define elna_string_type_node elna_global_trees[ELNA_TI_STRING_TYPE]
|
||||
|
||||
namespace elna
|
||||
{
|
||||
namespace gcc
|
||||
{
|
||||
void init_ttree();
|
||||
bool is_pointer_type(tree type);
|
||||
bool is_integral_type(tree type);
|
||||
bool are_compatible_pointers(tree lhs, tree rhs);
|
||||
@ -43,6 +35,13 @@ namespace gcc
|
||||
|
||||
class tree_chain final : public tree_chain_base
|
||||
{
|
||||
protected:
|
||||
void chain(tree t) override;
|
||||
};
|
||||
|
||||
class block_chain final : public tree_chain_base
|
||||
{
|
||||
protected:
|
||||
void chain(tree t) override;
|
||||
};
|
||||
|
||||
@ -58,6 +57,22 @@ namespace gcc
|
||||
tree block();
|
||||
};
|
||||
|
||||
class block_scope
|
||||
{
|
||||
tree m_statement_list{ NULL_TREE };
|
||||
std::forward_list<std::pair<tree, tree>> defers;
|
||||
|
||||
public:
|
||||
tree_chain variables;
|
||||
block_chain blocks;
|
||||
|
||||
block_scope();
|
||||
|
||||
void append_statement(tree statement_tree);
|
||||
void defer(tree statement_tree);
|
||||
tree chain_defer();
|
||||
};
|
||||
|
||||
std::shared_ptr<boot::symbol_table<tree>> builtin_symbol_table();
|
||||
|
||||
tree do_pointer_arithmetic(boot::binary_operator binary_operator, tree left, tree right);
|
||||
@ -65,5 +80,6 @@ namespace gcc
|
||||
tree_code operator_code, tree left, tree right, tree target_type);
|
||||
tree build_arithmetic_operation(boot::binary_expression *expression,
|
||||
tree_code operator_code, tree left, tree right);
|
||||
tree build_field(location_t location, tree record_type, const std::string name, tree type);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user