Pull binding out into it's own templated object so we can use it for types for unification
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,6 +7,7 @@ stats
|
|||||||
*.swm
|
*.swm
|
||||||
*.swn
|
*.swn
|
||||||
*.swo
|
*.swo
|
||||||
|
*.swl
|
||||||
*.png
|
*.png
|
||||||
*krakout*
|
*krakout*
|
||||||
kraklist.txt
|
kraklist.txt
|
||||||
|
|||||||
45
k.krak
45
k.krak
@@ -95,9 +95,9 @@ fun main(argc: int, argv: **char): int {
|
|||||||
for (var i = 0; i < scope->children.size; i++;) {
|
for (var i = 0; i < scope->children.size; i++;) {
|
||||||
match(scope->children[i]->data) {
|
match(scope->children[i]->data) {
|
||||||
ast::_import(b) if b.second.contains(name) || b.second.contains(str("*")) {
|
ast::_import(b) if b.second.contains(name) || b.second.contains(str("*")) {
|
||||||
if !bound(b.first) {
|
if !ast_bound(b.first) {
|
||||||
// Import / parse file if not already
|
// Import / parse file if not already
|
||||||
var file_path = binding_str(b.first)
|
var file_path = ast_binding_str(b.first)
|
||||||
if (!name_ast_map.contains_key(file_path)) {
|
if (!name_ast_map.contains_key(file_path)) {
|
||||||
printerr(file_path + ", ")
|
printerr(file_path + ", ")
|
||||||
var parse_tree = parse.parse_input(read_file(file_path), file_path)
|
var parse_tree = parse.parse_input(read_file(file_path), file_path)
|
||||||
@@ -106,9 +106,9 @@ fun main(argc: int, argv: **char): int {
|
|||||||
printlnerr("syntax_to_ast " + file_path + ":")
|
printlnerr("syntax_to_ast " + file_path + ":")
|
||||||
print_tree(name_ast_map[file_path], 1)
|
print_tree(name_ast_map[file_path], 1)
|
||||||
}
|
}
|
||||||
set_binding(b.first, name_ast_map[file_path])
|
set_ast_binding(b.first, name_ast_map[file_path])
|
||||||
}
|
}
|
||||||
to_ret += scope_lookup(get_binding(b.first), name, is_type)
|
to_ret += scope_lookup(get_ast_binding(b.first), name, is_type)
|
||||||
}
|
}
|
||||||
ast::_type_def(b) if (is_type && b == name)
|
ast::_type_def(b) if (is_type && b == name)
|
||||||
to_ret += scope->children[i]
|
to_ret += scope->children[i]
|
||||||
@@ -129,11 +129,11 @@ fun main(argc: int, argv: **char): int {
|
|||||||
return to_ret
|
return to_ret
|
||||||
}
|
}
|
||||||
var try_binding = fun(binding: *tree<ast>, start_scope: *tree<ast>, type_binding: bool) {
|
var try_binding = fun(binding: *tree<ast>, start_scope: *tree<ast>, type_binding: bool) {
|
||||||
if !bound(binding) {
|
if !ast_bound(binding) {
|
||||||
var options = scope_lookup(start_scope, binding->data._binding.first, type_binding)
|
var options = scope_lookup(start_scope, binding->data._binding.first, type_binding)
|
||||||
if (options.size < 1)
|
if (options.size < 1)
|
||||||
error("Could not find any options for scope lookup of " + binding->data._binding.first)
|
error("Could not find any options for scope lookup of " + binding->data._binding.first)
|
||||||
set_binding(binding, options[0])
|
set_ast_binding(binding, options[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var handle_type: fun(*type, *tree<ast>): void = fun(t: *type, n: *tree<ast>) {
|
var handle_type: fun(*type, *tree<ast>): void = fun(t: *type, n: *tree<ast>) {
|
||||||
@@ -227,11 +227,12 @@ fun main(argc: int, argv: **char): int {
|
|||||||
ast::_import(b) { }
|
ast::_import(b) { }
|
||||||
ast::_identifier(b) { C_str += idt + b.first; }
|
ast::_identifier(b) { C_str += idt + b.first; }
|
||||||
ast::_binding(b) {
|
ast::_binding(b) {
|
||||||
if (is_top_level_item(b.third))
|
var bound_to = b.second->bound_to
|
||||||
pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(b.third, str("emit_C")))
|
if (is_top_level_item(bound_to))
|
||||||
else if (is_identifier(b.third) && is_declaration(b.third->parent) && is_top_level_item(b.third->parent))
|
pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(bound_to, str("emit_C")))
|
||||||
pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(b.third->parent, str("emit_C")))
|
else if (is_identifier(bound_to) && is_declaration(bound_to->parent) && is_top_level_item(bound_to->parent))
|
||||||
C_str += idt + get_c_name(b.third)
|
pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(bound_to->parent, str("emit_C")))
|
||||||
|
C_str += get_c_name(bound_to)
|
||||||
}
|
}
|
||||||
ast::_type_def(b) { error("type_def gen unimplemented"); }
|
ast::_type_def(b) { error("type_def gen unimplemented"); }
|
||||||
ast::_adt_def(b) { error("no adt_def should remain at C emit"); }
|
ast::_adt_def(b) { error("no adt_def should remain at C emit"); }
|
||||||
@@ -350,11 +351,11 @@ fun main(argc: int, argv: **char): int {
|
|||||||
true, vec(
|
true, vec(
|
||||||
_identifier(str("argc"), type(base_type::_int(), 0, false)),
|
_identifier(str("argc"), type(base_type::_int(), 0, false)),
|
||||||
_identifier(str("argv"), type(base_type::_char(), 2, false)),
|
_identifier(str("argv"), type(base_type::_char(), 2, false)),
|
||||||
_return(vec(_call(vec(make_binding("fmain"), make_binding("argc"), make_binding("argv")))))
|
_return(vec(_call(vec(make_ast_binding("fmain"), make_ast_binding("argc"), make_ast_binding("argv")))))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
var top_unit = _translation_unit(str(), vec(
|
var top_unit = _translation_unit(str(), vec(
|
||||||
_import(make_binding(kraken_file_name), set(str("*")), vec(
|
_import(make_ast_binding(kraken_file_name), set(str("*")), vec(
|
||||||
_identifier(kraken_file_name, type(base_type::_void(), 0, false))
|
_identifier(kraken_file_name, type(base_type::_void(), 0, false))
|
||||||
)),
|
)),
|
||||||
real_main
|
real_main
|
||||||
@@ -406,9 +407,9 @@ fun parse_type(syntax: *tree<symbol>): *type {
|
|||||||
if (ident != null<tree<symbol>>()) {
|
if (ident != null<tree<symbol>>()) {
|
||||||
var template_inst = get_node("template_inst", syntax)
|
var template_inst = get_node("template_inst", syntax)
|
||||||
if (template_inst != null<tree<symbol>>()) {
|
if (template_inst != null<tree<symbol>>()) {
|
||||||
return type(base_type::_obj(make_binding(concat(ident) + "<somin>")), indr, is_ref)
|
return type(base_type::_obj(make_ast_binding(concat(ident) + "<somin>")), indr, is_ref)
|
||||||
} else {
|
} else {
|
||||||
return type(base_type::_obj(make_binding(concat(ident))), indr, is_ref)
|
return type(base_type::_obj(make_ast_binding(concat(ident))), indr, is_ref)
|
||||||
}
|
}
|
||||||
} else if (func != null<tree<symbol>>()) {
|
} else if (func != null<tree<symbol>>()) {
|
||||||
var param_types = vec<*type>()
|
var param_types = vec<*type>()
|
||||||
@@ -460,7 +461,7 @@ fun syntax_to_ast(file_name: str, syntax: *tree<symbol>, import_paths: ref vec<s
|
|||||||
|
|
||||||
var syntax_to_ast_helper: fun(*tree<symbol>): *tree<ast> = fun(syntax: *tree<symbol>): *tree<ast> {
|
var syntax_to_ast_helper: fun(*tree<symbol>): *tree<ast> = fun(syntax: *tree<symbol>): *tree<ast> {
|
||||||
if (syntax->data.name == "import") {
|
if (syntax->data.name == "import") {
|
||||||
return _import(make_binding(resolve_import_file(concat(syntax->children[1]) + ".krak")), from_vector(syntax->children.slice(2,-1).filter(fun(s:*tree<symbol>):bool {
|
return _import(make_ast_binding(resolve_import_file(concat(syntax->children[1]) + ".krak")), from_vector(syntax->children.slice(2,-1).filter(fun(s:*tree<symbol>):bool {
|
||||||
return s->data.name == "identifier" || s->data.data == "*"
|
return s->data.name == "identifier" || s->data.data == "*"
|
||||||
}).map(concat)), vec(syntax_to_ast_helper(syntax->children[1])))
|
}).map(concat)), vec(syntax_to_ast_helper(syntax->children[1])))
|
||||||
} else if (syntax->data.name == "function") {
|
} else if (syntax->data.name == "function") {
|
||||||
@@ -530,7 +531,7 @@ fun syntax_to_ast(file_name: str, syntax: *tree<symbol>, import_paths: ref vec<s
|
|||||||
children += get_nodes("boolean_expression", syntax).map(syntax_to_ast_helper)
|
children += get_nodes("boolean_expression", syntax).map(syntax_to_ast_helper)
|
||||||
return _declaration(children)
|
return _declaration(children)
|
||||||
} else if (syntax->data.name == "assignment_statement")
|
} else if (syntax->data.name == "assignment_statement")
|
||||||
return _assignment(vec(make_binding(concat(syntax->children[1])),
|
return _assignment(vec(make_ast_binding(concat(syntax->children[1])),
|
||||||
syntax_to_ast_helper(syntax->children[0]),
|
syntax_to_ast_helper(syntax->children[0]),
|
||||||
syntax_to_ast_helper(syntax->children[2])))
|
syntax_to_ast_helper(syntax->children[2])))
|
||||||
else if (syntax->data.name == "function_call")
|
else if (syntax->data.name == "function_call")
|
||||||
@@ -556,16 +557,16 @@ fun syntax_to_ast(file_name: str, syntax: *tree<symbol>, import_paths: ref vec<s
|
|||||||
if (template_inst != null<tree<symbol>>()) {
|
if (template_inst != null<tree<symbol>>()) {
|
||||||
if (syntax->children[0]->data.name != "scoped_identifier")
|
if (syntax->children[0]->data.name != "scoped_identifier")
|
||||||
error(syntax, "Unexpected template instantiation (not on an identifier)")
|
error(syntax, "Unexpected template instantiation (not on an identifier)")
|
||||||
return make_binding(concat(syntax->children[0]) + "<somin>")
|
return make_ast_binding(concat(syntax->children[0]) + "<somin>")
|
||||||
} else if (syntax->children[0]->data.terminal) {
|
} else if (syntax->children[0]->data.terminal) {
|
||||||
return _call(vec(make_binding(concat(syntax->children[0])),
|
return _call(vec(make_ast_binding(concat(syntax->children[0])),
|
||||||
syntax_to_ast_helper(syntax->children[1])))
|
syntax_to_ast_helper(syntax->children[1])))
|
||||||
} else {
|
} else {
|
||||||
return _call(vec(make_binding(concat(syntax->children[1])),
|
return _call(vec(make_ast_binding(concat(syntax->children[1])),
|
||||||
syntax_to_ast_helper(syntax->children[0])))
|
syntax_to_ast_helper(syntax->children[0])))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return _call(vec(make_binding(concat(syntax->children[1])),
|
return _call(vec(make_ast_binding(concat(syntax->children[1])),
|
||||||
syntax_to_ast_helper(syntax->children[0]),
|
syntax_to_ast_helper(syntax->children[0]),
|
||||||
syntax_to_ast_helper(syntax->children[2])))
|
syntax_to_ast_helper(syntax->children[2])))
|
||||||
}
|
}
|
||||||
@@ -574,7 +575,7 @@ fun syntax_to_ast(file_name: str, syntax: *tree<symbol>, import_paths: ref vec<s
|
|||||||
else if (syntax->data.name == "bool")
|
else if (syntax->data.name == "bool")
|
||||||
return _value(concat(syntax), type(base_type::_bool(), 0, false))
|
return _value(concat(syntax), type(base_type::_bool(), 0, false))
|
||||||
else if (syntax->data.name == "scoped_identifier" || syntax->data.name == "identifier")
|
else if (syntax->data.name == "scoped_identifier" || syntax->data.name == "identifier")
|
||||||
return make_binding(concat(syntax))
|
return make_ast_binding(concat(syntax))
|
||||||
else {
|
else {
|
||||||
error(syntax, "Cannot transform")
|
error(syntax, "Cannot transform")
|
||||||
return null<tree<ast>>()
|
return null<tree<ast>>()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ adt ast {
|
|||||||
_translation_unit: str,
|
_translation_unit: str,
|
||||||
_import: pair<*tree<ast>, set<str>>,
|
_import: pair<*tree<ast>, set<str>>,
|
||||||
_identifier: pair<str, *type>,
|
_identifier: pair<str, *type>,
|
||||||
_binding: triple<str, vec<*type>, *tree<ast>>,
|
_binding: pair<str, *binding<tree<ast>>>,
|
||||||
_type_def: str,
|
_type_def: str,
|
||||||
_adt_def: str,
|
_adt_def: str,
|
||||||
_function: triple<str, *type, bool>,
|
_function: triple<str, *type, bool>,
|
||||||
@@ -37,7 +37,7 @@ fun to_string(a: ref ast): str {
|
|||||||
ast::_translation_unit(b) return str("_translation_unit(") + b + ")"
|
ast::_translation_unit(b) return str("_translation_unit(") + b + ")"
|
||||||
ast::_import(b) return str("_import(") + to_string(b.first->data) + ")[" + str(",").join(b.second.data) + "]"
|
ast::_import(b) return str("_import(") + to_string(b.first->data) + ")[" + str(",").join(b.second.data) + "]"
|
||||||
ast::_identifier(b) return str("_identifier(") + b.first + ": " + deref_to_string(b.second) + ")"
|
ast::_identifier(b) return str("_identifier(") + b.first + ": " + deref_to_string(b.second) + ")"
|
||||||
ast::_binding(b) return str("_binding(") + b.first + "->" + to_string(b.third) + ")"
|
ast::_binding(b) return str("_binding(") + b.first + "->" + to_string(b.second->bound_to) + ")"
|
||||||
ast::_type_def(b) return str("_type_def(") + b + ")"
|
ast::_type_def(b) return str("_type_def(") + b + ")"
|
||||||
ast::_adt_def(b) return str("_adt_def(") + b + ")"
|
ast::_adt_def(b) return str("_adt_def(") + b + ")"
|
||||||
ast::_function(b) return str("_function(") + b.first + ": " + deref_to_string(b.second) + ", ext?:" + to_string(b.third) + ")"
|
ast::_function(b) return str("_function(") + b.first + ": " + deref_to_string(b.second) + ", ext?:" + to_string(b.third) + ")"
|
||||||
@@ -78,8 +78,8 @@ fun _cast(p: *type): *tree<ast> {
|
|||||||
fun _identifier(p1: str, p2: *type): *tree<ast> {
|
fun _identifier(p1: str, p2: *type): *tree<ast> {
|
||||||
return new<tree<ast>>()->construct(ast::_identifier(make_pair(p1, p2)))
|
return new<tree<ast>>()->construct(ast::_identifier(make_pair(p1, p2)))
|
||||||
}
|
}
|
||||||
fun _binding(p1: str, p2: vec<*type>, p3: *tree<ast>): *tree<ast> {
|
fun _binding(p1: str, p2: *binding<tree<ast>>): *tree<ast> {
|
||||||
return new<tree<ast>>()->construct(ast::_binding(make_triple(p1, p2, p3)))
|
return new<tree<ast>>()->construct(ast::_binding(make_pair(p1, p2)))
|
||||||
}
|
}
|
||||||
fun _function(p1: str, p2: *type, p3: bool): *tree<ast> {
|
fun _function(p1: str, p2: *type, p3: bool): *tree<ast> {
|
||||||
return new<tree<ast>>()->construct(ast::_function(make_triple(p1, p2, p3)))
|
return new<tree<ast>>()->construct(ast::_function(make_triple(p1, p2, p3)))
|
||||||
@@ -153,8 +153,8 @@ fun _cast(p: *type, c: ref vec<*tree<ast>>): *tree<ast> {
|
|||||||
fun _identifier(p1: str, p2: *type, c: ref vec<*tree<ast>>): *tree<ast> {
|
fun _identifier(p1: str, p2: *type, c: ref vec<*tree<ast>>): *tree<ast> {
|
||||||
return new<tree<ast>>()->construct(ast::_identifier(make_pair(p1, p2)), c)
|
return new<tree<ast>>()->construct(ast::_identifier(make_pair(p1, p2)), c)
|
||||||
}
|
}
|
||||||
fun _binding(p1: str, p2: vec<*type>, p3: *tree<ast>, c: ref vec<*tree<ast>>): *tree<ast> {
|
fun _binding(p1: str, p2: *binding<tree<ast>>, c: ref vec<*tree<ast>>): *tree<ast> {
|
||||||
return new<tree<ast>>()->construct(ast::_binding(make_triple(p1, p2, p3)), c)
|
return new<tree<ast>>()->construct(ast::_binding(make_pair(p1, p2)), c)
|
||||||
}
|
}
|
||||||
fun _function(p1: str, p2: *type, p3: bool, c: ref vec<*tree<ast>>): *tree<ast> {
|
fun _function(p1: str, p2: *type, p3: bool, c: ref vec<*tree<ast>>): *tree<ast> {
|
||||||
return new<tree<ast>>()->construct(ast::_function(make_triple(p1, p2, p3)), c)
|
return new<tree<ast>>()->construct(ast::_function(make_triple(p1, p2, p3)), c)
|
||||||
@@ -237,49 +237,78 @@ fun is_value(i: *tree<ast>): bool { match(i->data) { ast::_value(b) return true;
|
|||||||
|
|
||||||
fun is_top_level_item(i: *tree<ast>): bool { return i->parent != null<tree<ast>>() && is_translation_unit(i->parent); }
|
fun is_top_level_item(i: *tree<ast>): bool { return i->parent != null<tree<ast>>() && is_translation_unit(i->parent); }
|
||||||
|
|
||||||
var bindings: *vec<*tree<ast>>
|
|
||||||
fun make_binding(s: *char): *tree<ast> {
|
var bindings: *vec<*void>
|
||||||
return make_binding(str(s))
|
|
||||||
|
fun binding<T>(): *binding<T> {
|
||||||
|
var to_ret = new<binding<T>>()->construct()
|
||||||
|
if (bindings == null<vec<*void>>())
|
||||||
|
bindings = new<vec<*void>>()->construct()
|
||||||
|
bindings->add( (to_ret) cast *void )
|
||||||
|
return to_ret
|
||||||
}
|
}
|
||||||
fun make_binding(s: str): *tree<ast> {
|
|
||||||
var binding = _binding(s, vec<*type>(), null<tree<ast>>())
|
obj binding<T> (Object) {
|
||||||
if (bindings == null<vec<*tree<ast>>>())
|
var bound_to: *T
|
||||||
bindings = new<vec<*tree<ast>>>()->construct()
|
fun construct(): *binding<T> {
|
||||||
bindings->add(binding)
|
bound_to = null<T>()
|
||||||
return binding
|
return this
|
||||||
|
}
|
||||||
|
fun copy_construct(old: *binding<T>): void {
|
||||||
|
bound_to = old->bound_to
|
||||||
|
}
|
||||||
|
fun destruct() {
|
||||||
|
bound_to = null<T>()
|
||||||
|
}
|
||||||
|
fun bound(): bool {
|
||||||
|
return bound_to != null<T>()
|
||||||
|
}
|
||||||
|
fun set(to: *T) {
|
||||||
|
// don't set null, that will set all unbound ones
|
||||||
|
if (bound_to == null<tree<ast>>()) {
|
||||||
|
bound_to = to
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var from = bound_to
|
||||||
|
for (var i = 0; i < bindings->size; i++;)
|
||||||
|
if ( ((bindings->get(i)) cast *binding<T>)->bound_to == from)
|
||||||
|
((bindings->get(i)) cast *binding<T>)->bound_to = to
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fun get_binding(binding: *tree<ast>): *tree<ast> {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun make_ast_binding(s: *char): *tree<ast> {
|
||||||
|
return make_ast_binding(str(s))
|
||||||
|
}
|
||||||
|
fun make_ast_binding(s: str): *tree<ast> {
|
||||||
|
return _binding(s, binding<tree<ast>>())
|
||||||
|
}
|
||||||
|
fun get_ast_binding(binding: *tree<ast>): *tree<ast> {
|
||||||
match(binding->data) {
|
match(binding->data) {
|
||||||
ast::_binding(b) {
|
ast::_binding(b) {
|
||||||
return b.third
|
return b.second->bound_to
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
error("trying to get binding on not a binding")
|
error("trying to get binding on not a binding")
|
||||||
}
|
}
|
||||||
fun set_binding(binding: *tree<ast>, to: *tree<ast>) {
|
fun set_ast_binding(binding: *tree<ast>, to: *tree<ast>) {
|
||||||
match(binding->data) {
|
match(binding->data) {
|
||||||
ast::_binding(b) {
|
ast::_binding(b) {
|
||||||
var from = b.third
|
b.second->set(to)
|
||||||
// don't set null, that will set all unbound ones
|
|
||||||
if (from == null<tree<ast>>()) {
|
|
||||||
b.third = to
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for (var i = 0; i < bindings->size; i++;)
|
|
||||||
if (bindings->get(i)->data._binding.third == from)
|
|
||||||
bindings->get(i)->data._binding.third = to
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
error("trying to set binding on not a binding")
|
error("trying to set binding on not a binding")
|
||||||
}
|
}
|
||||||
fun bound(binding: *tree<ast>): bool {
|
fun ast_bound(binding: *tree<ast>): bool {
|
||||||
match(binding->data) {
|
match(binding->data) {
|
||||||
ast::_binding(b) return b.third != null<tree<ast>>()
|
ast::_binding(b) return b.second->bound()
|
||||||
}
|
}
|
||||||
error("Trying to check bound for not a binding")
|
error("Trying to check bound for not a binding")
|
||||||
}
|
}
|
||||||
fun binding_str(binding: *tree<ast>): str {
|
fun ast_binding_str(binding: *tree<ast>): str {
|
||||||
match(binding->data) {
|
match(binding->data) {
|
||||||
ast::_binding(b) return b.first
|
ast::_binding(b) return b.first
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user