2018-06-18 19:04:24 -04:00
|
|
|
import tree:*
|
2018-06-22 20:58:47 -04:00
|
|
|
import type2:*
|
2018-06-18 19:04:24 -04:00
|
|
|
import vec:*
|
|
|
|
|
import set:*
|
|
|
|
|
import util:*
|
|
|
|
|
import str:*
|
|
|
|
|
import mem:*
|
|
|
|
|
|
|
|
|
|
adt ast {
|
|
|
|
|
_translation_unit: str,
|
2018-06-22 23:13:08 -04:00
|
|
|
_import: pair<*tree<ast>, set<str>>,
|
2018-06-18 19:04:24 -04:00
|
|
|
_identifier: pair<str, *type>,
|
2018-09-22 10:44:02 -04:00
|
|
|
_binding: pair<str, *binding<tree<ast>>>,
|
2018-06-18 19:04:24 -04:00
|
|
|
_type_def: str,
|
|
|
|
|
_adt_def: str,
|
2018-09-17 23:36:26 -04:00
|
|
|
_function: triple<str, *type, bool>,
|
2018-06-18 19:04:24 -04:00
|
|
|
_template: pair<str, set<str>>,
|
|
|
|
|
_declaration,
|
|
|
|
|
_assignment,
|
|
|
|
|
_block,
|
|
|
|
|
_if,
|
|
|
|
|
_match,
|
|
|
|
|
_case,
|
|
|
|
|
_while,
|
|
|
|
|
_for,
|
|
|
|
|
_return,
|
|
|
|
|
_break,
|
|
|
|
|
_continue,
|
|
|
|
|
_defer,
|
|
|
|
|
_call,
|
|
|
|
|
_compiler_intrinsic: pair<str, vec<*type>>,
|
|
|
|
|
_cast: *type,
|
|
|
|
|
_value: pair<str, *type>
|
|
|
|
|
}
|
|
|
|
|
fun to_string(a: ref ast): str {
|
|
|
|
|
match(a) {
|
2018-06-20 00:49:49 -04:00
|
|
|
ast::_translation_unit(b) return str("_translation_unit(") + b + ")"
|
2018-06-22 23:13:08 -04:00
|
|
|
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) + ")"
|
2018-09-22 10:44:02 -04:00
|
|
|
ast::_binding(b) return str("_binding(") + b.first + "->" + to_string(b.second->bound_to) + ")"
|
2018-06-20 00:49:49 -04:00
|
|
|
ast::_type_def(b) return str("_type_def(") + b + ")"
|
|
|
|
|
ast::_adt_def(b) return str("_adt_def(") + b + ")"
|
2018-09-17 23:36:26 -04:00
|
|
|
ast::_function(b) return str("_function(") + b.first + ": " + deref_to_string(b.second) + ", ext?:" + to_string(b.third) + ")"
|
2018-06-22 09:02:30 -04:00
|
|
|
ast::_template(b) return str("_template(") + b.first + "[" + str(",").join(b.second.data) + "])"
|
2018-06-18 19:04:24 -04:00
|
|
|
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")
|
2018-06-20 00:49:49 -04:00
|
|
|
ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ")"
|
|
|
|
|
ast::_cast(b) return str("_cast")
|
2018-06-22 23:13:08 -04:00
|
|
|
ast::_value(b) return str("_value(") + b.first + ": " + deref_to_string(b.second) + ")"
|
2018-06-18 19:04:24 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fun _translation_unit(p: str): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_translation_unit(p))
|
|
|
|
|
}
|
2018-06-22 23:13:08 -04:00
|
|
|
fun _import(p1: *tree<ast>, p2: set<str>): *tree<ast> {
|
2018-06-22 20:58:47 -04:00
|
|
|
return new<tree<ast>>()->construct(ast::_import(make_pair(p1,p2)))
|
2018-06-18 19:04:24 -04:00
|
|
|
}
|
|
|
|
|
fun _type_def(p: str): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_type_def(p))
|
|
|
|
|
}
|
|
|
|
|
fun _adt_def(p: str): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_adt_def(p))
|
|
|
|
|
}
|
|
|
|
|
fun _cast(p: *type): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_cast(p))
|
|
|
|
|
}
|
|
|
|
|
fun _identifier(p1: str, p2: *type): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_identifier(make_pair(p1, p2)))
|
|
|
|
|
}
|
2018-09-22 10:44:02 -04:00
|
|
|
fun _binding(p1: str, p2: *binding<tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_binding(make_pair(p1, p2)))
|
2018-06-18 19:04:24 -04:00
|
|
|
}
|
2018-09-17 23:36:26 -04:00
|
|
|
fun _function(p1: str, p2: *type, p3: bool): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_function(make_triple(p1, p2, p3)))
|
2018-06-18 19:04:24 -04:00
|
|
|
}
|
|
|
|
|
fun _template(p1: str, p2: set<str>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_template(make_pair(p1, p2)))
|
|
|
|
|
}
|
|
|
|
|
fun _compiler_intrinsic(p1: str, p2: vec<*type>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)))
|
|
|
|
|
}
|
|
|
|
|
fun _value(p1: str, p2: *type): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_value(make_pair(p1, p2)))
|
|
|
|
|
}
|
|
|
|
|
fun _declaration(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_declaration())
|
|
|
|
|
}
|
|
|
|
|
fun _assignment(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_assignment())
|
|
|
|
|
}
|
|
|
|
|
fun _block(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_block())
|
|
|
|
|
}
|
|
|
|
|
fun _if(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_if())
|
|
|
|
|
}
|
|
|
|
|
fun _match(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_match())
|
|
|
|
|
}
|
|
|
|
|
fun _case(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_case())
|
|
|
|
|
}
|
|
|
|
|
fun _while(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_while())
|
|
|
|
|
}
|
|
|
|
|
fun _for(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_for())
|
|
|
|
|
}
|
|
|
|
|
fun _return(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_return())
|
|
|
|
|
}
|
|
|
|
|
fun _break(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_break())
|
|
|
|
|
}
|
|
|
|
|
fun _continue(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_continue())
|
|
|
|
|
}
|
|
|
|
|
fun _defer(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_defer())
|
|
|
|
|
}
|
|
|
|
|
fun _call(): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_call())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun _translation_unit(p: str, c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_translation_unit(p), c)
|
|
|
|
|
}
|
2018-06-22 23:13:08 -04:00
|
|
|
fun _import(p1: *tree<ast>, p2: set<str>, c: ref vec<*tree<ast>>): *tree<ast> {
|
2018-06-22 20:58:47 -04:00
|
|
|
return new<tree<ast>>()->construct(ast::_import(make_pair(p1,p2)), c)
|
2018-06-18 19:04:24 -04:00
|
|
|
}
|
|
|
|
|
fun _type_def(p: str, c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_type_def(p), c)
|
|
|
|
|
}
|
|
|
|
|
fun _adt_def(p: str, c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_adt_def(p), c)
|
|
|
|
|
}
|
|
|
|
|
fun _cast(p: *type, c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_cast(p), c)
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
}
|
2018-09-22 10:44:02 -04:00
|
|
|
fun _binding(p1: str, p2: *binding<tree<ast>>, c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_binding(make_pair(p1, p2)), c)
|
2018-06-18 19:04:24 -04:00
|
|
|
}
|
2018-09-17 23:36:26 -04:00
|
|
|
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)
|
2018-06-18 19:04:24 -04:00
|
|
|
}
|
|
|
|
|
fun _template(p1: str, p2: set<str>, c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_template(make_pair(p1, p2)), c)
|
|
|
|
|
}
|
|
|
|
|
fun _compiler_intrinsic(p1: str, p2: vec<*type>, c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)), c)
|
|
|
|
|
}
|
|
|
|
|
fun _value(p1: str, p2: *type, c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_value(make_pair(p1, p2)), c)
|
|
|
|
|
}
|
|
|
|
|
fun _declaration(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_declaration(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _assignment(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_assignment(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _block(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_block(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _if(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_if(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _match(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_match(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _case(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_case(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _while(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_while(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _for(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_for(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _return(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_return(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _break(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_break(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _continue(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_continue(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _defer(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_defer(), c)
|
|
|
|
|
}
|
|
|
|
|
fun _call(c: ref vec<*tree<ast>>): *tree<ast> {
|
|
|
|
|
return new<tree<ast>>()->construct(ast::_call(), c)
|
|
|
|
|
}
|
2018-09-17 23:36:26 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun is_translation_unit(i: *tree<ast>): bool { match(i->data) { ast::_translation_unit(b) return true; } return false; }
|
|
|
|
|
fun is_import(i: *tree<ast>): bool { match(i->data) { ast::_import(b) return true; } return false; }
|
|
|
|
|
fun is_identifier(i: *tree<ast>): bool { match(i->data) { ast::_identifier(b) return true; } return false; }
|
|
|
|
|
fun is_binding(i: *tree<ast>): bool { match(i->data) { ast::_binding(b) return true; } return false; }
|
|
|
|
|
fun is_type_def(i: *tree<ast>): bool { match(i->data) { ast::_type_def(b) return true; } return false; }
|
|
|
|
|
fun is_adt_def(i: *tree<ast>): bool { match(i->data) { ast::_adt_def(b) return true; } return false; }
|
|
|
|
|
fun is_function(i: *tree<ast>): bool { match(i->data) { ast::_function(b) return true; } return false; }
|
|
|
|
|
fun is_template(i: *tree<ast>): bool { match(i->data) { ast::_template(b) return true; } return false; }
|
|
|
|
|
fun is_declaration(i: *tree<ast>): bool { match(i->data) { ast::_declaration() return true; } return false; }
|
|
|
|
|
fun is_assignment(i: *tree<ast>): bool { match(i->data) { ast::_assignment() return true; } return false; }
|
|
|
|
|
fun is_block(i: *tree<ast>): bool { match(i->data) { ast::_block() return true; } return false; }
|
|
|
|
|
fun is_if(i: *tree<ast>): bool { match(i->data) { ast::_if() return true; } return false; }
|
|
|
|
|
fun is_match(i: *tree<ast>): bool { match(i->data) { ast::_match() return true; } return false; }
|
|
|
|
|
fun is_case(i: *tree<ast>): bool { match(i->data) { ast::_case() return true; } return false; }
|
|
|
|
|
fun is_while(i: *tree<ast>): bool { match(i->data) { ast::_while() return true; } return false; }
|
|
|
|
|
fun is_for(i: *tree<ast>): bool { match(i->data) { ast::_for() return true; } return false; }
|
|
|
|
|
fun is_return(i: *tree<ast>): bool { match(i->data) { ast::_return() return true; } return false; }
|
|
|
|
|
fun is_break(i: *tree<ast>): bool { match(i->data) { ast::_break() return true; } return false; }
|
|
|
|
|
fun is_continue(i: *tree<ast>): bool { match(i->data) { ast::_continue() return true; } return false; }
|
|
|
|
|
fun is_defer(i: *tree<ast>): bool { match(i->data) { ast::_defer() return true; } return false; }
|
|
|
|
|
fun is_call(i: *tree<ast>): bool { match(i->data) { ast::_call() return true; } return false; }
|
|
|
|
|
fun is_compiler_intrinsic(i: *tree<ast>): bool { match(i->data) { ast::_compiler_intrinsic(b) return true; } return false; }
|
|
|
|
|
fun is_cast(i: *tree<ast>): bool { match(i->data) { ast::_cast(b) return true; } return false; }
|
|
|
|
|
fun is_value(i: *tree<ast>): bool { match(i->data) { ast::_value(b) return true; } return false; }
|
|
|
|
|
|
|
|
|
|
fun is_top_level_item(i: *tree<ast>): bool { return i->parent != null<tree<ast>>() && is_translation_unit(i->parent); }
|
|
|
|
|
|
2018-09-22 10:44:02 -04:00
|
|
|
|
|
|
|
|
var bindings: *vec<*void>
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
obj binding<T> (Object) {
|
|
|
|
|
var bound_to: *T
|
|
|
|
|
fun construct(): *binding<T> {
|
|
|
|
|
bound_to = null<T>()
|
|
|
|
|
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 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> {
|
2018-09-17 23:36:26 -04:00
|
|
|
match(binding->data) {
|
|
|
|
|
ast::_binding(b) {
|
2018-09-22 10:44:02 -04:00
|
|
|
return b.second->bound_to
|
2018-09-17 23:36:26 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
error("trying to get binding on not a binding")
|
|
|
|
|
}
|
2018-09-22 10:44:02 -04:00
|
|
|
fun set_ast_binding(binding: *tree<ast>, to: *tree<ast>) {
|
2018-09-17 23:36:26 -04:00
|
|
|
match(binding->data) {
|
|
|
|
|
ast::_binding(b) {
|
2018-09-22 10:44:02 -04:00
|
|
|
b.second->set(to)
|
2018-09-17 23:36:26 -04:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
error("trying to set binding on not a binding")
|
|
|
|
|
}
|
2018-09-22 10:44:02 -04:00
|
|
|
fun ast_bound(binding: *tree<ast>): bool {
|
2018-09-17 23:36:26 -04:00
|
|
|
match(binding->data) {
|
2018-09-22 10:44:02 -04:00
|
|
|
ast::_binding(b) return b.second->bound()
|
2018-09-17 23:36:26 -04:00
|
|
|
}
|
|
|
|
|
error("Trying to check bound for not a binding")
|
|
|
|
|
}
|
2018-09-22 10:44:02 -04:00
|
|
|
fun ast_binding_str(binding: *tree<ast>): str {
|
2018-09-17 23:36:26 -04:00
|
|
|
match(binding->data) {
|
|
|
|
|
ast::_binding(b) return b.first
|
|
|
|
|
}
|
|
|
|
|
error("Trying to get name for not a binding")
|
|
|
|
|
}
|