Implement defer

This commit is contained in:
2025-02-07 22:12:59 +01:00
parent 077de53c74
commit 8a0f282714
13 changed files with 484 additions and 335 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;
};
}
}

View File

@ -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);
}
}