Implement defer
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user