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: triple, *tree>, _type_def: str, _adt_def: str, _function: triple, _template: pair>, _declaration, _assignment, _block, _if, _match, _case, _while, _for, _return, _break, _continue, _defer, _call, _compiler_intrinsic: pair>, _cast: *type, _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) + ")" ast::_binding(b) return str("_binding(") + b.first + "->" + to_string(b.third) + ")" 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) + ", 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) + ")" } } 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: *type): *tree { return new>()->construct(ast::_cast(p)) } fun _identifier(p1: str, p2: *type): *tree { return new>()->construct(ast::_identifier(make_pair(p1, p2))) } fun _binding(p1: str, p2: vec<*type>, p3: *tree): *tree { return new>()->construct(ast::_binding(make_triple(p1, p2, p3))) } fun _function(p1: str, p2: *type, 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<*type>): *tree { return new>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2))) } fun _value(p1: str, p2: *type): *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: *type, c: ref vec<*tree>): *tree { return new>()->construct(ast::_cast(p), c) } fun _identifier(p1: str, p2: *type, c: ref vec<*tree>): *tree { return new>()->construct(ast::_identifier(make_pair(p1, p2)), c) } fun _binding(p1: str, p2: vec<*type>, p3: *tree, c: ref vec<*tree>): *tree { return new>()->construct(ast::_binding(make_triple(p1, p2, p3)), c) } fun _function(p1: str, p2: *type, 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<*type>, c: ref vec<*tree>): *tree { return new>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)), c) } fun _value(p1: str, p2: *type, 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); } var bindings: *vec<*tree> fun make_binding(s: *char): *tree { return make_binding(str(s)) } fun make_binding(s: str): *tree { var binding = _binding(s, vec<*type>(), null>()) if (bindings == null>>()) bindings = new>>()->construct() bindings->add(binding) return binding } fun get_binding(binding: *tree): *tree { match(binding->data) { ast::_binding(b) { return b.third } } error("trying to get binding on not a binding") } fun set_binding(binding: *tree, to: *tree) { match(binding->data) { ast::_binding(b) { var from = b.third // don't set null, that will set all unbound ones if (from == null>()) { 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 } } error("trying to set binding on not a binding") } fun bound(binding: *tree): bool { match(binding->data) { ast::_binding(b) return b.third != null>() } error("Trying to check bound for not a binding") } fun binding_str(binding: *tree): str { match(binding->data) { ast::_binding(b) return b.first } error("Trying to get name for not a binding") }