import tree:* import type2:* import vec:* import set:* import util:* import str:* import mem:* adt ast { _translation_unit: str, _import: pair<*tree, set>, _identifier: pair>, _binding: pair>>, _type_def: str, _adt_def: str, _function: triple, bool>, _template: pair>, _declaration, _assignment, _block, _if, _match, _case, _while, _for, _return, _break, _continue, _defer, _call, _compiler_intrinsic: pair>>, _cast: *binding, _value: pair> } fun to_string(a: ref ast): str { match(a) { 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::_identifier(b) return str("_identifier(") + b.first + ": " + deref_to_string(b.second->bound_to) + ")" ast::_binding(b) return str("_binding(") + b.first + "->" + to_string(b.second->bound_to) + ")" ast::_type_def(b) return str("_type_def(") + b + ")" ast::_adt_def(b) return str("_adt_def(") + b + ")" ast::_function(b) return str("_function(") + b.first + ": " + deref_to_string(b.second->bound_to) + ", ext?:" + to_string(b.third) + ")" ast::_template(b) return str("_template(") + b.first + "[" + str(",").join(b.second.data) + "])" ast::_declaration() return str("_declaration") ast::_assignment() return str("_assignment") ast::_block() return str("_block") ast::_if() return str("_if") ast::_match() return str("_match") ast::_case() return str("_case") ast::_while() return str("_while") ast::_for() return str("_for") ast::_return() return str("_return") ast::_break() return str("_break") ast::_continue() return str("_continue") ast::_defer() return str("_defer") ast::_call() return str("_call") ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ")" ast::_cast(b) return str("_cast") ast::_value(b) return str("_value(") + b.first + ": " + deref_to_string(b.second->bound_to) + ")" } } fun _translation_unit(p: str): *tree { return new>()->construct(ast::_translation_unit(p)) } fun _import(p1: *tree, p2: set): *tree { return new>()->construct(ast::_import(make_pair(p1,p2))) } fun _type_def(p: str): *tree { return new>()->construct(ast::_type_def(p)) } fun _adt_def(p: str): *tree { return new>()->construct(ast::_adt_def(p)) } fun _cast(p: *binding): *tree { return new>()->construct(ast::_cast(p)) } fun _identifier(p1: str, p2: *binding): *tree { return new>()->construct(ast::_identifier(make_pair(p1, p2))) } fun _binding(p1: str, p2: *binding>): *tree { return new>()->construct(ast::_binding(make_pair(p1, p2))) } fun _function(p1: str, p2: *binding, p3: bool): *tree { return new>()->construct(ast::_function(make_triple(p1, p2, p3))) } fun _template(p1: str, p2: set): *tree { return new>()->construct(ast::_template(make_pair(p1, p2))) } fun _compiler_intrinsic(p1: str, p2: vec<*binding>): *tree { return new>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2))) } fun _value(p1: str, p2: *binding): *tree { return new>()->construct(ast::_value(make_pair(p1, p2))) } fun _declaration(): *tree { return new>()->construct(ast::_declaration()) } fun _assignment(): *tree { return new>()->construct(ast::_assignment()) } fun _block(): *tree { return new>()->construct(ast::_block()) } fun _if(): *tree { return new>()->construct(ast::_if()) } fun _match(): *tree { return new>()->construct(ast::_match()) } fun _case(): *tree { return new>()->construct(ast::_case()) } fun _while(): *tree { return new>()->construct(ast::_while()) } fun _for(): *tree { return new>()->construct(ast::_for()) } fun _return(): *tree { return new>()->construct(ast::_return()) } fun _break(): *tree { return new>()->construct(ast::_break()) } fun _continue(): *tree { return new>()->construct(ast::_continue()) } fun _defer(): *tree { return new>()->construct(ast::_defer()) } fun _call(): *tree { return new>()->construct(ast::_call()) } fun _translation_unit(p: str, c: ref vec<*tree>): *tree { return new>()->construct(ast::_translation_unit(p), c) } fun _import(p1: *tree, p2: set, c: ref vec<*tree>): *tree { return new>()->construct(ast::_import(make_pair(p1,p2)), c) } fun _type_def(p: str, c: ref vec<*tree>): *tree { return new>()->construct(ast::_type_def(p), c) } fun _adt_def(p: str, c: ref vec<*tree>): *tree { return new>()->construct(ast::_adt_def(p), c) } fun _cast(p: *binding, c: ref vec<*tree>): *tree { return new>()->construct(ast::_cast(p), c) } fun _identifier(p1: str, p2: *binding, c: ref vec<*tree>): *tree { return new>()->construct(ast::_identifier(make_pair(p1, p2)), c) } fun _binding(p1: str, p2: *binding>, c: ref vec<*tree>): *tree { return new>()->construct(ast::_binding(make_pair(p1, p2)), c) } fun _function(p1: str, p2: *binding, p3: bool, c: ref vec<*tree>): *tree { return new>()->construct(ast::_function(make_triple(p1, p2, p3)), c) } fun _template(p1: str, p2: set, c: ref vec<*tree>): *tree { return new>()->construct(ast::_template(make_pair(p1, p2)), c) } fun _compiler_intrinsic(p1: str, p2: vec<*binding>, c: ref vec<*tree>): *tree { return new>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)), c) } fun _value(p1: str, p2: *binding, c: ref vec<*tree>): *tree { return new>()->construct(ast::_value(make_pair(p1, p2)), c) } fun _declaration(c: ref vec<*tree>): *tree { return new>()->construct(ast::_declaration(), c) } fun _assignment(c: ref vec<*tree>): *tree { return new>()->construct(ast::_assignment(), c) } fun _block(c: ref vec<*tree>): *tree { return new>()->construct(ast::_block(), c) } fun _if(c: ref vec<*tree>): *tree { return new>()->construct(ast::_if(), c) } fun _match(c: ref vec<*tree>): *tree { return new>()->construct(ast::_match(), c) } fun _case(c: ref vec<*tree>): *tree { return new>()->construct(ast::_case(), c) } fun _while(c: ref vec<*tree>): *tree { return new>()->construct(ast::_while(), c) } fun _for(c: ref vec<*tree>): *tree { return new>()->construct(ast::_for(), c) } fun _return(c: ref vec<*tree>): *tree { return new>()->construct(ast::_return(), c) } fun _break(c: ref vec<*tree>): *tree { return new>()->construct(ast::_break(), c) } fun _continue(c: ref vec<*tree>): *tree { return new>()->construct(ast::_continue(), c) } fun _defer(c: ref vec<*tree>): *tree { return new>()->construct(ast::_defer(), c) } fun _call(c: ref vec<*tree>): *tree { return new>()->construct(ast::_call(), c) } fun is_translation_unit(i: *tree): bool { match(i->data) { ast::_translation_unit(b) return true; } return false; } fun is_import(i: *tree): bool { match(i->data) { ast::_import(b) return true; } return false; } fun is_identifier(i: *tree): bool { match(i->data) { ast::_identifier(b) return true; } return false; } fun is_binding(i: *tree): bool { match(i->data) { ast::_binding(b) return true; } return false; } fun is_type_def(i: *tree): bool { match(i->data) { ast::_type_def(b) return true; } return false; } fun is_adt_def(i: *tree): bool { match(i->data) { ast::_adt_def(b) return true; } return false; } fun is_function(i: *tree): bool { match(i->data) { ast::_function(b) return true; } return false; } fun is_template(i: *tree): bool { match(i->data) { ast::_template(b) return true; } return false; } fun is_declaration(i: *tree): bool { match(i->data) { ast::_declaration() return true; } return false; } fun is_assignment(i: *tree): bool { match(i->data) { ast::_assignment() return true; } return false; } fun is_block(i: *tree): bool { match(i->data) { ast::_block() return true; } return false; } fun is_if(i: *tree): bool { match(i->data) { ast::_if() return true; } return false; } fun is_match(i: *tree): bool { match(i->data) { ast::_match() return true; } return false; } fun is_case(i: *tree): bool { match(i->data) { ast::_case() return true; } return false; } fun is_while(i: *tree): bool { match(i->data) { ast::_while() return true; } return false; } fun is_for(i: *tree): bool { match(i->data) { ast::_for() return true; } return false; } fun is_return(i: *tree): bool { match(i->data) { ast::_return() return true; } return false; } fun is_break(i: *tree): bool { match(i->data) { ast::_break() return true; } return false; } fun is_continue(i: *tree): bool { match(i->data) { ast::_continue() return true; } return false; } fun is_defer(i: *tree): bool { match(i->data) { ast::_defer() return true; } return false; } fun is_call(i: *tree): bool { match(i->data) { ast::_call() return true; } return false; } fun is_compiler_intrinsic(i: *tree): bool { match(i->data) { ast::_compiler_intrinsic(b) return true; } return false; } fun is_cast(i: *tree): bool { match(i->data) { ast::_cast(b) return true; } return false; } fun is_value(i: *tree): bool { match(i->data) { ast::_value(b) return true; } return false; } fun is_top_level_item(i: *tree): bool { return i->parent != null>() && is_translation_unit(i->parent); } fun get_ancestor_satisfying(t: *tree, p: fun(*tree): bool): *tree { t = t->parent while (t != null>() && !p(t)) t = t->parent return t } var bindings: *vec<*void> fun binding(): *binding { return binding(null()) } fun binding(it: *T): *binding { var to_ret = new>()->construct(it) if (bindings == null>()) bindings = new>()->construct() bindings->add( (to_ret) cast *void ) return to_ret } obj binding (Object) { var bound_to: *T fun construct(): *binding { bound_to = null() return this } fun construct(it: *T): *binding { bound_to = it return this } fun copy_construct(old: *binding): void { bound_to = old->bound_to } fun destruct() { bound_to = null() } fun bound(): bool { return bound_to != null() } fun set(to: *T) { // don't set null, that will set all unbound ones if (bound_to == null()) { bound_to = to return } var from = bound_to for (var i = 0; i < bindings->size; i++;) if ( ((bindings->get(i)) cast *binding)->bound_to == from) ((bindings->get(i)) cast *binding)->bound_to = to } fun to_string(): str { return "binding(" + to_string(bound_to) + ")" /*return "binding(" + deref_to_string(bound_to) + ")"*/ } } fun make_ast_binding(s: *char): *tree { return make_ast_binding(str(s)) } fun make_ast_binding(s: str): *tree { return _binding(s, binding>()) } fun get_ast_binding(binding: *tree): *tree { match(binding->data) { ast::_binding(b) { return b.second->bound_to } } error("trying to get binding on not a binding") } fun set_ast_binding(binding: *tree, to: *tree) { match(binding->data) { ast::_binding(b) { b.second->set(to) return } } error("trying to set binding on not a binding") } fun ast_bound(binding: *tree): bool { match(binding->data) { ast::_binding(b) return b.second->bound() } error("Trying to check bound for not a binding") } fun ast_binding_str(binding: *tree): str { match(binding->data) { ast::_binding(b) return b.first } error("Trying to get name for not a binding") }