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

@ -4,19 +4,12 @@
#include "stor-layout.h"
#include "fold-const.h"
#include "diagnostic-core.h"
tree elna_global_trees[ELNA_TI_MAX];
#include "stringpool.h"
namespace elna
{
namespace gcc
{
void init_ttree()
{
elna_string_type_node = build_pointer_type(
build_qualified_type(char_type_node, TYPE_QUAL_CONST)); /* const char* */
}
bool is_pointer_type(tree type)
{
gcc_assert(TYPE_P(type));
@ -60,6 +53,11 @@ namespace gcc
TREE_CHAIN(this->last) = t;
}
void block_chain::chain(tree t)
{
BLOCK_CHAIN(this->last) = t;
}
tree_symbol_mapping::tree_symbol_mapping(tree bind_expression, tree block)
: m_bind_expression(bind_expression), m_block(block)
{
@ -75,6 +73,57 @@ namespace gcc
return m_block;
}
block_scope::block_scope()
: m_statement_list(alloc_stmt_list())
{
}
void block_scope::append_statement(tree statement_tree)
{
if (!defers.empty())
{
append_to_statement_list(statement_tree, &this->defers.front().second);
}
else
{
append_to_statement_list(statement_tree, &this->m_statement_list);
}
}
void block_scope::defer(tree statement_tree)
{
defers.push_front({ statement_tree, alloc_stmt_list() });
}
tree block_scope::chain_defer()
{
if (this->defers.empty())
{
return m_statement_list;
}
std::forward_list<std::pair<tree, tree>>::iterator defer_iterator =
this->defers.begin();
tree defer_tree = build2(TRY_FINALLY_EXPR, void_type_node, defer_iterator->second, defer_iterator->first);
++defer_iterator;
for (; defer_iterator != this->defers.end(); ++defer_iterator)
{
append_to_statement_list(defer_tree, &defer_iterator->second);
defer_tree = build2(TRY_FINALLY_EXPR, void_type_node, defer_iterator->second, defer_iterator->first);
}
return build2(COMPOUND_EXPR, TREE_TYPE(defer_tree), m_statement_list, defer_tree);
}
tree build_field(location_t location, tree record_type, const std::string name, tree type)
{
tree field_declaration = build_decl(location,
FIELD_DECL, get_identifier(name.c_str()), type);
TREE_ADDRESSABLE(field_declaration) = 1;
DECL_CONTEXT(field_declaration) = record_type;
return field_declaration;
}
std::shared_ptr<boot::symbol_table<tree>> builtin_symbol_table()
{
std::shared_ptr<boot::symbol_table<tree>> initial_table =
@ -86,7 +135,18 @@ namespace gcc
initial_table->enter("Float", double_type_node);
initial_table->enter("Char", unsigned_char_type_node);
initial_table->enter("Byte", make_unsigned_type(8));
initial_table->enter("String", elna_string_type_node);
tree string_record = make_node(RECORD_TYPE);
tree_chain record_chain;
record_chain.append(build_field(UNKNOWN_LOCATION, string_record, "length", initial_table->lookup("Word")));
record_chain.append(build_field(UNKNOWN_LOCATION, string_record, "ptr",
build_pointer_type(initial_table->lookup("Char"))));
TYPE_FIELDS(string_record) = record_chain.head();
layout_type(string_record);
initial_table->enter("String", string_record);
return initial_table;
}