Add struct access! Uses new translation_unit_generative pass depended on by scope lookups to generate compiler_intrinsics that access members of structs'
This commit is contained in:
85
k.krak
85
k.krak
@@ -16,6 +16,11 @@ import tree:*
|
||||
import symbol:*
|
||||
import binding:*
|
||||
|
||||
adt OptionVecAst {
|
||||
Some: vec<*tree<ast>>,
|
||||
None
|
||||
}
|
||||
|
||||
fun main(argc: int, argv: **char): int {
|
||||
// delay construction until we either load it or copy construct it
|
||||
var gram: grammer
|
||||
@@ -190,10 +195,40 @@ fun main(argc: int, argv: **char): int {
|
||||
), false, false))), vec<*binding<type>>()))))
|
||||
}
|
||||
|
||||
passes[str("translation_unit_generative")] = fun(item: *tree<ast>) {
|
||||
println("Running translation_unit_generative")
|
||||
if !is_translation_unit(item) {
|
||||
error("Running translation_unit_generative on not a translation unit");
|
||||
}
|
||||
for (var i = 0; i < item->children.size; i++;) {
|
||||
var child = item->children[i]
|
||||
if is_type_def(child)
|
||||
match (child->data) {
|
||||
ast::_type_def(name) {
|
||||
println("Found a type_def! - " + name)
|
||||
for (var j = 0; j < child->children.size; j++;) {
|
||||
var grandchild = child->children[j];
|
||||
if is_declaration(grandchild) {
|
||||
var ident = grandchild->children[0]
|
||||
var type_def_binding = make_ast_binding(name)
|
||||
set_ast_binding(type_def_binding, child)
|
||||
item->add_child(_compiler_intrinsic(ident->data._identifier.first, binding_p(type::_fun(make_triple(make_pair(vec(
|
||||
binding_p(type::_obj(type_def_binding))
|
||||
),
|
||||
ident->data._identifier.second
|
||||
), false, false))), vec<*binding<type>>()))
|
||||
println("adding compiler intrinsic to do " + name + "." + ident->data._identifier.first)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// resolves all binding possibilities for one top level item
|
||||
passes[str("name_possibility_resolve")] = fun(item: *tree<ast>) {
|
||||
println("Running name possibility resolver?")
|
||||
var scope_lookup: fun(*tree<ast>, str, bool): vec<*tree<ast>> = fun(scope: *tree<ast>, name: str, is_type: bool): vec<*tree<ast>> {
|
||||
var scope_lookup: fun(*tree<ast>, str, bool): OptionVecAst = fun(scope: *tree<ast>, name: str, is_type: bool): OptionVecAst {
|
||||
var to_ret = vec<*tree<ast>>()
|
||||
for (var i = 0; i < scope->children.size; i++;) {
|
||||
match(scope->children[i]->data) {
|
||||
@@ -211,7 +246,17 @@ fun main(argc: int, argv: **char): int {
|
||||
}
|
||||
set_ast_binding(b.first, name_ast_map[file_path])
|
||||
}
|
||||
to_ret += scope_lookup(get_ast_binding(b.first), name, is_type)
|
||||
var other_top_level = get_ast_binding(b.first)
|
||||
if !pass_poset.done(make_pair(other_top_level, str("translation_unit_generative"))) {
|
||||
pass_poset.add_open_dep(make_pair(item, str("name_possibility_resolve")), make_pair(other_top_level, str("translation_unit_generative")))
|
||||
return OptionVecAst::None()
|
||||
}
|
||||
match (scope_lookup(other_top_level, name, is_type)) {
|
||||
OptionVecAst::None() return OptionVecAst::None()
|
||||
OptionVecAst::Some(v) {
|
||||
to_ret += v
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::_type_def(b) if (is_type && b == name)
|
||||
to_ret += scope->children[i]
|
||||
@@ -219,6 +264,8 @@ fun main(argc: int, argv: **char): int {
|
||||
to_ret += scope->children[i]
|
||||
ast::_function(b) if (!is_type && b.first == name)
|
||||
to_ret += scope->children[i]
|
||||
ast::_compiler_intrinsic(b) if (!is_type && b.first == name)
|
||||
to_ret += scope->children[i]
|
||||
ast::_template(b) if (!is_type && b.first == name)
|
||||
to_ret += scope->children[i]
|
||||
ast::_identifier(b) if (!is_type && b.first == name)
|
||||
@@ -227,15 +274,21 @@ fun main(argc: int, argv: **char): int {
|
||||
to_ret += scope->children[i]->children[0]
|
||||
}
|
||||
}
|
||||
if (scope->parent != null<tree<ast>>())
|
||||
return to_ret + scope_lookup(scope->parent, name, is_type)
|
||||
if (scope->parent != null<tree<ast>>()) {
|
||||
match (scope_lookup(scope->parent, name, is_type)) {
|
||||
OptionVecAst::None() return OptionVecAst::None()
|
||||
OptionVecAst::Some(v) return OptionVecAst::Some(to_ret + v)
|
||||
}
|
||||
}
|
||||
else if (primitive_ops.contains_key(name))
|
||||
to_ret += primitive_ops[name]
|
||||
return to_ret
|
||||
return OptionVecAst::Some(to_ret)
|
||||
}
|
||||
var try_binding = fun(binding: *tree<ast>, start_scope: *tree<ast>, type_binding: bool) {
|
||||
if !ast_bound(binding) {
|
||||
var options = scope_lookup(start_scope, ast_binding_str(binding), type_binding)
|
||||
if !ast_bound(binding) && !multiple_binding_options.contains_key(binding) {
|
||||
match (scope_lookup(start_scope, ast_binding_str(binding), type_binding)) {
|
||||
OptionVecAst::None() return;
|
||||
OptionVecAst::Some(options) {
|
||||
if (options.size == 0)
|
||||
error("Could not find any options for scope lookup of " + ast_binding_str(binding))
|
||||
else if (options.size == 1)
|
||||
@@ -244,6 +297,8 @@ fun main(argc: int, argv: **char): int {
|
||||
multiple_binding_options[binding] = options
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var handle_type: fun(*binding<type>, *tree<ast>): void = fun(t: *binding<type>, n: *tree<ast>) {
|
||||
match(*t->bound_to) {
|
||||
type::_obj(b) try_binding(b, n, true)
|
||||
@@ -761,9 +816,16 @@ fun main(argc: int, argv: **char): int {
|
||||
ast::_call() {
|
||||
if (is_compiler_intrinsic(get_ast_binding(t->children[0]))) {
|
||||
if (t->children.size == 2) {
|
||||
C_str += idt + "(" + get_ast_binding(t->children[0])->data._compiler_intrinsic.first + "("
|
||||
var intrinsic_name = get_ast_binding(t->children[0])->data._compiler_intrinsic.first
|
||||
if (intrinsic_name == "&" || intrinsic_name == "*") {
|
||||
C_str += idt + "(" + intrinsic_name + "("
|
||||
emit_C(t->children[1], 0)
|
||||
C_str += "))"
|
||||
} else {
|
||||
C_str += "("
|
||||
emit_C(t->children[1], 0)
|
||||
C_str += ")." + intrinsic_name
|
||||
}
|
||||
} else if (t->children.size == 3) {
|
||||
C_str += idt + "(("
|
||||
emit_C(t->children[1], 0)
|
||||
@@ -1036,8 +1098,7 @@ fun syntax_to_ast(file_name: str, syntax: *tree<symbol>, import_paths: ref vec<s
|
||||
syntax->data.name == "shiftand" ||
|
||||
syntax->data.name == "term" ||
|
||||
syntax->data.name == "factor" ||
|
||||
syntax->data.name == "unarad" ||
|
||||
syntax->data.name == "access_operation") {
|
||||
syntax->data.name == "unarad") {
|
||||
if (syntax->children.size == 1) {
|
||||
return syntax_to_ast_helper(syntax->children[0], declared_template_types)
|
||||
} else if (syntax->children.size == 2) {
|
||||
@@ -1060,6 +1121,10 @@ fun syntax_to_ast(file_name: str, syntax: *tree<symbol>, import_paths: ref vec<s
|
||||
syntax_to_ast_helper(syntax->children[0], declared_template_types),
|
||||
syntax_to_ast_helper(syntax->children[2], declared_template_types)))
|
||||
}
|
||||
} else if (syntax->data.name == "access_operation") {
|
||||
// somehow note / do the crazier scope lookup
|
||||
// also handle . vs ->
|
||||
return _call(vec(make_ast_binding(concat(syntax->children[2])), syntax_to_ast_helper(syntax->children[0], declared_template_types)))
|
||||
} else if (syntax->data.name == "cast_expression") {
|
||||
return _cast(parse_type(get_node("type", syntax), declared_template_types), vec(syntax_to_ast_helper(syntax->children[0], declared_template_types)))
|
||||
} else if (syntax->data.name == "number") {
|
||||
|
||||
@@ -152,7 +152,7 @@ fun adt_lower(name_ast_map: *map<str, pair<*tree<symbol>,*ast_node>>, ast_to_syn
|
||||
backing.cases.for_each(fun(case_stmt: *ast_node) {
|
||||
var option = case_stmt->case_statement.option
|
||||
if (!get_ast_scope(get_ast_type(value)->type_def)->contains_key(str("flag")))
|
||||
error("trying to get flag from struct without it - are you matching on not an adt? - ")
|
||||
error("trying to get flag from struct without it - are you matching on not an adt? - " + get_ast_type(value)->to_string())
|
||||
var flag = get_from_scope(get_ast_type(value)->type_def, "flag")
|
||||
var data = get_from_scope(get_ast_type(value)->type_def, "data")
|
||||
var option_num = -7
|
||||
|
||||
@@ -119,6 +119,9 @@ fun shallow_equality(a: *type, b: *type):bool {
|
||||
type::_fun(x) {
|
||||
return is_fun(b) && a->_fun.third == b->_fun.third
|
||||
}
|
||||
type::_obj(x) {
|
||||
return is_obj(b) && get_ast_binding(x) == get_ast_binding(b->_obj)
|
||||
}
|
||||
}
|
||||
return *a == *b
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user