diff --git a/boot/semantic.cc b/boot/semantic.cc
index d29771a..408082a 100644
--- a/boot/semantic.cc
+++ b/boot/semantic.cc
@@ -15,8 +15,6 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
. */
-#include
-
#include "elna/boot/semantic.h"
namespace elna
@@ -110,57 +108,17 @@ namespace boot
this->current_type = type(std::make_shared(this->current_type, type_expression->size));
}
- bool declaration_visitor::build_composite_type(const std::vector& declarations,
- std::vector& fields)
+ void declaration_visitor::visit(record_type_expression *)
{
- std::set field_names;
-
- for (auto& field : declarations)
- {
- if (field_names.find(field.first) != field_names.cend())
- {
- add_error(field.first, this->input_file, field.second->position());
- this->current_type = type();
- return false;
- }
- field.second->accept(this);
- if (!this->current_type.empty())
- {
- fields.push_back({ field.first, type(this->current_type) });
- }
- }
- return true;
+ this->current_type = type(std::make_shared());
}
- void declaration_visitor::visit(record_type_expression *type_expression)
+ void declaration_visitor::visit(union_type_expression *)
{
- auto type_definition = std::make_shared();
-
- if (build_composite_type(type_expression->fields, type_definition->fields))
- {
- this->current_type = type(type_definition);
- }
- else
- {
- this->current_type = type();
- }
+ this->current_type = type(std::make_shared());
}
- void declaration_visitor::visit(union_type_expression *type_expression)
- {
- auto type_definition = std::make_shared();
-
- if (build_composite_type(type_expression->fields, type_definition->fields))
- {
- this->current_type = type(type_definition);
- }
- else
- {
- this->current_type = type();
- }
- }
-
- void declaration_visitor::visit(procedure_type_expression *type_expression)
+ void declaration_visitor::visit(procedure_type_expression *)
{
}
}
diff --git a/boot/symbol.cc b/boot/symbol.cc
index 0391579..c3ba0f2 100644
--- a/boot/symbol.cc
+++ b/boot/symbol.cc
@@ -22,7 +22,6 @@ namespace elna
namespace boot
{
type::type()
- : tag(type_tag::alias)
{
}
@@ -145,6 +144,7 @@ namespace boot
case type_tag::empty:
break;
case type_tag::alias:
+ this->alias.~weak_ptr();
break;
case type_tag::primitive:
this->primitive.~shared_ptr();
diff --git a/gcc/elna-builtins.cc b/gcc/elna-builtins.cc
index 3f67671..262d567 100644
--- a/gcc/elna-builtins.cc
+++ b/gcc/elna-builtins.cc
@@ -50,5 +50,20 @@ namespace gcc
TYPE_FIELDS(elna_string_type_node) = chainon(elna_string_ptr_field_node, elna_string_length_field_node);
layout_type(elna_string_type_node);
}
+
+ std::shared_ptr builtin_symbol_table()
+ {
+ std::shared_ptr symbol_table = std::make_shared();
+
+ symbol_table->enter("Int", elna_int_type_node);
+ symbol_table->enter("Word", elna_word_type_node);
+ symbol_table->enter("Char", elna_char_type_node);
+ symbol_table->enter("Bool", elna_bool_type_node);
+ symbol_table->enter("Byte", elna_byte_type_node);
+ symbol_table->enter("Float", elna_float_type_node);
+ symbol_table->enter("String", elna_string_type_node);
+
+ return symbol_table;
+ }
}
}
diff --git a/gcc/elna-generic.cc b/gcc/elna-generic.cc
index 6906815..0d4926d 100644
--- a/gcc/elna-generic.cc
+++ b/gcc/elna-generic.cc
@@ -16,6 +16,7 @@ along with GCC; see the file COPYING3. If not see
. */
#include
+#include
#include "elna/gcc/elna-generic.h"
#include "elna/gcc/elna-diagnostic.h"
@@ -32,21 +33,16 @@ along with GCC; see the file COPYING3. If not see
#include "varasm.h"
#include "fold-const.h"
#include "langhooks.h"
-#include
namespace elna
{
namespace gcc
{
- tree handle_symbol(const std::string& symbol_name, const boot::type& type,
- std::shared_ptr from, std::shared_ptr to);
-
- tree get_inner_alias(const boot::type& type,
- std::shared_ptr from, std::shared_ptr to)
+ tree get_inner_alias(const boot::type& type, std::shared_ptr symbols)
{
if (auto reference = type.get())
{
- return to->lookup(reference->identifier);
+ return symbols->lookup(reference->identifier);
}
else if (auto reference = type.get())
{
@@ -58,7 +54,7 @@ namespace gcc
}
else if (auto reference = type.get())
{
- return build_pointer_type_for_mode(get_inner_alias(reference->base, from, to), VOIDmode, true);
+ return build_pointer_type_for_mode(get_inner_alias(reference->base, symbols), VOIDmode, true);
}
else if (auto reference = type.get())
{
@@ -66,45 +62,40 @@ namespace gcc
tree upper_bound = build_int_cst_type(integer_type_node, reference->size);
tree range_type = build_range_type(integer_type_node, lower_bound, upper_bound);
- return build_array_type(get_inner_alias(reference->base, from, to), range_type);
+ return build_array_type(get_inner_alias(reference->base, symbols), range_type);
}
else if (auto reference = type.get())
{
- return handle_symbol(reference->name, reference->reference, from, to);
+ return handle_symbol(reference->name, reference->reference, symbols);
}
return error_mark_node;
}
- tree handle_symbol(const std::string& symbol_name, const boot::type& type,
- std::shared_ptr from, std::shared_ptr to)
+ tree handle_symbol(const std::string& symbol_name, const boot::type& type, std::shared_ptr symbols)
{
- auto looked_up = to->lookup(symbol_name);
+ auto looked_up = symbols->lookup(symbol_name);
if (looked_up == NULL_TREE)
{
- looked_up = get_inner_alias(type, from, to);
- to->enter(symbol_name, looked_up);
+ looked_up = get_inner_alias(type, symbols);
+ symbols->enter(symbol_name, looked_up);
}
return looked_up;
}
std::deque> do_semantic_analysis(const char *path,
- std::unique_ptr& ast, std::shared_ptr symbols)
+ std::unique_ptr& ast, std::shared_ptr info_table,
+ std::shared_ptr symbols)
{
- auto info_table = boot::builtin_symbol_table();
boot::declaration_visitor declaration_visitor(path, info_table);
declaration_visitor.visit(ast.get());
if (declaration_visitor.errors().empty())
{
- for (auto& [symbol_name, symbol_info] : *info_table)
+ for (auto& [symbol_name, symbol_info] : declaration_visitor.unresolved)
{
- handle_symbol(symbol_name, symbol_info->is_type()->symbol, info_table, symbols);
- }
- for (auto& [symbol_name, symbol_info] : *info_table)
- {
- // printf("%s\n", symbol_name.c_str());
+ handle_symbol(symbol_name, boot::type(symbol_info), symbols);
}
}
return std::move(declaration_visitor.errors());
@@ -418,11 +409,6 @@ namespace gcc
return bind_expr;
}
- tree generic_visitor::lookup(const std::string& name)
- {
- return this->symbols->lookup(name);
- }
-
void generic_visitor::visit(boot::number_literal *literal)
{
this->current_expression = build_int_cst(elna_int_type_node, literal->value);
@@ -775,7 +761,7 @@ namespace gcc
void generic_visitor::visit(boot::type_definition *definition)
{
location_t definition_location = get_location(&definition->position());
- this->current_expression = lookup(definition->identifier);
+ this->current_expression = this->symbols->lookup(definition->identifier);
definition->body().accept(this);
tree definition_tree = build_decl(definition_location, TYPE_DECL,
@@ -809,6 +795,36 @@ namespace gcc
return build_function_type_array(return_type, type.parameters.size(), parameter_types.data());
}
+ void generic_visitor::build_composite_type(const std::vector& fields,
+ tree composite_type_node)
+ {
+ std::set field_names;
+
+ for (auto& field : fields)
+ {
+ if (field_names.find(field.first) != field_names.cend())
+ {
+ error_at(get_location(&field.second->position()), "repeated field name");
+ this->current_expression = error_mark_node;
+ return;
+ }
+ field_names.insert(field.first);
+
+ field.second->accept(this);
+ if (this->current_expression == NULL_TREE || this->current_expression == error_mark_node)
+ {
+ return;
+ }
+ tree field_declaration = build_field(get_location(&field.second->position()),
+ composite_type_node, field.first, this->current_expression);
+ TYPE_FIELDS(composite_type_node) = chainon(TYPE_FIELDS(composite_type_node), field_declaration);
+ this->current_expression = NULL_TREE;
+ }
+ layout_type(composite_type_node);
+
+ this->current_expression = composite_type_node;
+ }
+
void generic_visitor::visit(boot::variable_declaration *declaration)
{
declaration->variable_type().accept(this);
@@ -847,7 +863,7 @@ namespace gcc
void generic_visitor::visit(boot::variable_expression *expression)
{
- auto symbol = lookup(expression->name);
+ auto symbol = this->symbols->lookup(expression->name);
if (symbol == NULL_TREE)
{
@@ -1140,7 +1156,7 @@ namespace gcc
void generic_visitor::visit(boot::primitive_type_expression *type)
{
- tree symbol = lookup(type->name);
+ tree symbol = this->symbols->lookup(type->name);
if (symbol == NULL_TREE || !TYPE_P(symbol))
{
@@ -1181,66 +1197,20 @@ namespace gcc
void generic_visitor::visit(boot::record_type_expression *type)
{
- std::set field_names;
tree composite_type_node = this->current_expression == NULL_TREE
? make_node(RECORD_TYPE)
: this->current_expression;
- for (auto& field : type->fields)
- {
- if (field_names.find(field.first) != field_names.cend())
- {
- error_at(get_location(&field.second->position()), "repeated field name");
- this->current_expression = error_mark_node;
- return;
- }
- field_names.insert(field.first);
-
- field.second->accept(this);
- if (this->current_expression == NULL_TREE || this->current_expression == error_mark_node)
- {
- return;
- }
- tree field_declaration = build_field(get_location(&field.second->position()),
- composite_type_node, field.first, this->current_expression);
- TYPE_FIELDS(composite_type_node) = chainon(TYPE_FIELDS(composite_type_node), field_declaration);
- this->current_expression = NULL_TREE;
- }
- layout_type(composite_type_node);
-
- this->current_expression = composite_type_node;
+ build_composite_type(type->fields, composite_type_node);
}
void generic_visitor::visit(boot::union_type_expression *type)
{
- std::set field_names;
tree composite_type_node = this->current_expression == NULL_TREE
? make_node(UNION_TYPE)
: this->current_expression;
- for (auto& field : type->fields)
- {
- if (field_names.find(field.first) != field_names.cend())
- {
- error_at(get_location(&field.second->position()), "repeated field name");
- this->current_expression = error_mark_node;
- return;
- }
- field_names.insert(field.first);
-
- field.second->accept(this);
- if (this->current_expression == NULL_TREE || this->current_expression == error_mark_node)
- {
- return;
- }
- tree field_declaration = build_field(get_location(&field.second->position()),
- composite_type_node, field.first, this->current_expression);
- TYPE_FIELDS(composite_type_node) = chainon(TYPE_FIELDS(composite_type_node), field_declaration);
- this->current_expression = NULL_TREE;
- }
- layout_type(composite_type_node);
-
- this->current_expression = composite_type_node;
+ build_composite_type(type->fields, composite_type_node);
}
void generic_visitor::visit(boot::procedure_type_expression *type)
diff --git a/gcc/elna1.cc b/gcc/elna1.cc
index eac5d76..1d45781 100644
--- a/gcc/elna1.cc
+++ b/gcc/elna1.cc
@@ -83,17 +83,10 @@ static void elna_parse_file(const char *filename)
}
else
{
- std::shared_ptr symbol_table = std::make_shared();
+ std::shared_ptr info_table = elna::boot::builtin_symbol_table();
+ std::shared_ptr symbol_table = elna::gcc::builtin_symbol_table();
- symbol_table->enter("Int", elna_int_type_node);
- symbol_table->enter("Word", elna_word_type_node);
- symbol_table->enter("Char", elna_char_type_node);
- symbol_table->enter("Bool", elna_bool_type_node);
- symbol_table->enter("Byte", elna_byte_type_node);
- symbol_table->enter("Float", elna_float_type_node);
- symbol_table->enter("String", elna_string_type_node);
-
- auto semantic_errors = elna::gcc::do_semantic_analysis(filename, driver.tree, symbol_table);
+ auto semantic_errors = elna::gcc::do_semantic_analysis(filename, driver.tree, info_table, symbol_table);
if (semantic_errors.empty())
{
diff --git a/include/elna/boot/semantic.h b/include/elna/boot/semantic.h
index c17287e..5517026 100644
--- a/include/elna/boot/semantic.h
+++ b/include/elna/boot/semantic.h
@@ -52,12 +52,10 @@ namespace boot
{
type current_type;
std::shared_ptr symbols;
- std::unordered_map> unresolved;
-
- bool build_composite_type(const std::vector& declarations,
- std::vector& fields);
public:
+ std::unordered_map> unresolved;
+
explicit declaration_visitor(const char *path, std::shared_ptr symbols);
void visit(primitive_type_expression *type_expression) override;
@@ -65,9 +63,9 @@ namespace boot
void visit(pointer_type_expression *type_expression) override;
void visit(program *program) override;
void visit(type_definition *definition) override;
- void visit(record_type_expression *type_expression) override;
- void visit(union_type_expression *type_expression) override;
- void visit(procedure_type_expression *type_expression) override;
+ void visit(record_type_expression *) override;
+ void visit(union_type_expression *) override;
+ void visit(procedure_type_expression *) override;
};
}
}
diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h
index 404cf30..ac783ab 100644
--- a/include/elna/boot/symbol.h
+++ b/include/elna/boot/symbol.h
@@ -113,16 +113,12 @@ namespace boot
explicit primitive_type(const std::string& identifier);
};
- using type_field = typename std::pair;
-
struct record_type
{
- std::vector fields;
};
struct union_type
{
- std::vector fields;
};
class type_info;
diff --git a/include/elna/gcc/elna-builtins.h b/include/elna/gcc/elna-builtins.h
index a7d6b9f..ed5b749 100644
--- a/include/elna/gcc/elna-builtins.h
+++ b/include/elna/gcc/elna-builtins.h
@@ -15,16 +15,21 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
. */
+#include
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "tree-iterator.h"
+#include "elna/gcc/elna-tree.h"
+
namespace elna
{
namespace gcc
{
void init_ttree();
+ std::shared_ptr builtin_symbol_table();
}
}
diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h
index a426f8a..5ae5f90 100644
--- a/include/elna/gcc/elna-generic.h
+++ b/include/elna/gcc/elna-generic.h
@@ -35,7 +35,9 @@ namespace elna
namespace gcc
{
std::deque> do_semantic_analysis(const char *path,
- std::unique_ptr& ast, std::shared_ptr symbols);
+ std::unique_ptr& ast, std::shared_ptr info_table,
+ std::shared_ptr symbols);
+ tree handle_symbol(const std::string& symbol_name, const boot::type& type, std::shared_ptr symbols);
class generic_visitor final : public boot::empty_visitor
{
@@ -44,12 +46,12 @@ namespace gcc
tree build_label_decl(const char *name, location_t loc);
tree build_procedure_type(boot::procedure_type_expression& type);
+ void build_composite_type(const std::vector& fields,
+ tree composite_type_node);
void enter_scope();
tree leave_scope();
- tree lookup(const std::string& name);
-
void make_if_branch(boot::conditional_statements& branch, tree goto_endif);
tree build_arithmetic_operation(boot::binary_expression *expression,