import tree:* import symbol:* import vector:* import vector_literals:* import set:* import stack:* import map:* import util:* import string:* import mem:* import io:* import type:* adt ast_node { translation_unit: translation_unit, import: import, identifier: identifier, type_def: type_def, adt_def: adt_def, function: function, template: template, code_block: code_block, statement: statement, if_statement: if_statement, match_statement: match_statement, case_statement: case_statement, while_loop: while_loop, for_loop: for_loop, return_statement: return_statement, branching_statement: branching_statement, defer_statement: defer_statement, assignment_statement: assignment_statement, declaration_statement: declaration_statement, if_comp: if_comp, simple_passthrough: simple_passthrough, function_call: function_call, compiler_intrinsic: compiler_intrinsic, cast: cast, value: value } /* total: ASTType type; Type* valueType; Symbol symbol; std::map*>> scope; std::set*> closedVariables; */ fun ast_node_ptr(node: ast_node): *ast_node { var to_ret = new() to_ret->copy_construct(&node) return to_ret } fun ast_translation_unit_ptr(name: string): *ast_node { var obj_var.construct(name): translation_unit var ptr = new() ptr->copy_construct(&ast_node::translation_unit(obj_var)) return ptr } fun is_translation_unit(node: *ast_node): bool { match(*node) { ast_node::translation_unit(backing) return true } return false } obj translation_unit (Object) { var scope: map> var children: vector<*ast_node> var lambdas: vector<*ast_node> var name: string fun construct(nameIn: string): *translation_unit { scope.construct() children.construct() lambdas.construct() name.copy_construct(&nameIn) return this } fun copy_construct(old: *translation_unit) { scope.copy_construct(&old->scope) children.copy_construct(&old->children) lambdas.copy_construct(&old->lambdas) name.copy_construct(&old->name) } fun destruct() { scope.destruct() children.destruct() lambdas.destruct() name.destruct() } fun operator=(other: ref translation_unit) { destruct() copy_construct(&other) } fun operator==(other: ref translation_unit): bool { return children == other.children && name == other.name && lambdas == other.lambdas } } fun ast_import_ptr(name: string, translation_unit: *ast_node): *ast_node { var to_ret.construct(name, translation_unit): import var ptr = new() ptr->copy_construct(&ast_node::import(to_ret)) return ptr } fun is_import(node: *ast_node): bool { match(*node) { ast_node::import(backing) return true } return false } obj import (Object) { var scope: map> var imported: set var translation_unit: *ast_node var name: string var starred: bool fun construct(nameIn: string, translation_unit_in: *ast_node): *import { scope.construct() imported.construct() name.copy_construct(&nameIn) translation_unit = translation_unit_in starred = false return this } fun copy_construct(old: *import) { scope.copy_construct(&old->scope) imported.copy_construct(&old->imported) name.copy_construct(&old->name) translation_unit = old->translation_unit starred = old->starred } fun destruct() { scope.destruct() imported.destruct() name.destruct() } fun operator=(other: ref import) { destruct() copy_construct(&other) } fun operator==(other: ref import): bool { return imported == other.imported && name == other.name && translation_unit == other.translation_unit && starred == other.starred } } fun ast_identifier_ptr(name: *char, type: *type, enclosing_scope: *ast_node): *ast_node { return ast_identifier_ptr(string(name), type, enclosing_scope) } fun ast_identifier_ptr(name: string, type: *type, enclosing_scope: *ast_node): *ast_node { var to_ret.construct(name, type, enclosing_scope): identifier var ptr = new() ptr->copy_construct(&ast_node::identifier(to_ret)) return ptr } fun is_identifier(node: *ast_node): bool { match(*node) { ast_node::identifier(backing) return true } return false } obj identifier (Object) { var name: string var scope: map> var type: *type var enclosing_scope: *ast_node fun construct(name_in: string, type_in: *type, enclosing_scope: *ast_node): *identifier { name.copy_construct(&name_in) scope.construct() type = type_in identifier::enclosing_scope = enclosing_scope return this } fun copy_construct(old: *identifier) { name.copy_construct(&old->name) scope.copy_construct(&old->scope) type = old->type enclosing_scope = old->enclosing_scope } fun destruct() { name.destruct() scope.destruct() } fun operator=(other: ref identifier) { destruct() copy_construct(&other) } fun operator==(other: ref identifier): bool { return name == other.name && type == other.type && enclosing_scope == other.enclosing_scope } } fun ast_type_def_ptr(name: string): *ast_node { var to_ret.construct(name): type_def var ptr = new() ptr->copy_construct(&ast_node::type_def(to_ret)) return ptr } fun is_type_def(node: *ast_node): bool { match(*node) { ast_node::type_def(backing) return true } return false } obj type_def (Object) { var scope: map> var name: string var self_type: *type var variables: vector<*ast_node> var methods: vector<*ast_node> fun construct(nameIn: string): *type_def { scope.construct() name.copy_construct(&nameIn) self_type = null() variables.construct() methods.construct() return this } fun copy_construct(old: *type_def) { self_type = old->self_type scope.copy_construct(&old->scope) name.copy_construct(&old->name) variables.copy_construct(&old->variables) methods.copy_construct(&old->methods) } fun destruct() { scope.destruct() name.destruct() variables.destruct() methods.destruct() } fun operator=(other: ref type_def) { destruct() copy_construct(&other) } fun operator==(other: ref type_def): bool { return name == other.name && self_type == other.self_type && variables == other.variables && methods == other.methods } } fun ast_adt_def_ptr(name: string): *ast_node { var to_ret.construct(name): adt_def var ptr = new() ptr->copy_construct(&ast_node::adt_def(to_ret)) return ptr } fun is_adt_def(node: *ast_node): bool { match(*node) { ast_node::adt_def(backing) return true } return false } obj adt_def (Object) { var scope: map> var name: string var self_type: *type var options: vector<*ast_node> var option_funcs: vector<*ast_node> var regular_funcs: vector<*ast_node> fun construct(nameIn: string): *adt_def { scope.construct() name.copy_construct(&nameIn) self_type = null() options.construct() option_funcs.construct() regular_funcs.construct() return this } fun copy_construct(old: *adt_def) { scope.copy_construct(&old->scope) name.copy_construct(&old->name) self_type = old->self_type options.copy_construct(&old->options) option_funcs.copy_construct(&old->option_funcs) regular_funcs.copy_construct(&old->regular_funcs) } fun destruct() { scope.destruct() name.destruct() options.destruct() option_funcs.destruct() regular_funcs.destruct() } fun operator=(other: ref adt_def) { destruct() copy_construct(&other) } fun operator==(other: ref adt_def): bool { return name == other.name && self_type == other.self_type && options == other.options && option_funcs == other.option_funcs && regular_funcs == other.regular_funcs } } fun ast_function_ptr(name: string, type: *type, parameters: vector<*ast_node>, is_extern: bool): *ast_node { var to_ret.construct(name, type, parameters, is_extern): function var ptr = new() ptr->copy_construct(&ast_node::function(to_ret)) return ptr } fun is_function(node: *ast_node): bool { match(*node) { ast_node::function(backing) return true } return false } obj function (Object) { var name: string var type: *type var parameters: vector<*ast_node> var closed_variables: set<*ast_node> var body_statement: *ast_node var scope: map> var is_extern: bool fun construct(name_in: string, type_in: *type, parameters_in: vector<*ast_node>, is_extern_in: bool): *function { name.copy_construct(&name_in) parameters.copy_construct(¶meters_in) closed_variables.construct() scope.construct() type = type_in body_statement = null() is_extern = is_extern_in return this } fun copy_construct(old: *function) { name.copy_construct(&old->name) type = old->type body_statement = old->body_statement parameters.copy_construct(&old->parameters) closed_variables.copy_construct(&old->closed_variables) scope.copy_construct(&old->scope) is_extern = old->is_extern } fun destruct() { name.destruct() parameters.destruct() closed_variables.destruct() scope.destruct() } fun operator=(other: ref function) { destruct() copy_construct(&other) } fun operator==(other: ref function): bool { return name == name && type == other.type && parameters == other.parameters && body_statement == other.body_statement && closed_variables == other.closed_variables && is_extern == other.is_extern } } fun ast_template_ptr(name: string, syntax_node: *tree, template_types: vector, template_type_replacements: map, is_function: bool): *ast_node { var to_ret.construct(name, syntax_node, template_types, template_type_replacements, is_function): template var ptr = new() ptr->copy_construct(&ast_node::template(to_ret)) return ptr } fun is_template(node: *ast_node): bool { match(*node) { ast_node::template(backing) return true } return false } obj template (Object) { var name: string var syntax_node: *tree var instantiated: vector<*ast_node> var template_types: vector var template_type_replacements: map var instantiated_map: map, *ast_node> var scope: map> var is_function: bool fun construct(name_in: string, syntax_node_in: *tree, template_types_in: vector, template_type_replacements_in: map, is_function: bool): *template { name.copy_construct(&name_in) syntax_node = syntax_node_in instantiated.construct() template_types.copy_construct(&template_types_in) template_type_replacements.copy_construct(&template_type_replacements_in) instantiated_map.construct() scope.construct() template::is_function = is_function return this } fun copy_construct(old: *template) { name.copy_construct(&old->name) syntax_node = old->syntax_node instantiated.copy_construct(&old->instantiated) template_types.copy_construct(&old->template_types) template_type_replacements.copy_construct(&old->template_type_replacements) instantiated_map.copy_construct(&old->instantiated_map) scope.copy_construct(&old->scope) is_function = old->is_function } fun destruct() { name.destruct() instantiated.destruct() template_types.destruct() template_type_replacements.destruct() instantiated_map.destruct() scope.destruct() } fun operator=(other: ref template) { destruct() copy_construct(&other) } fun operator==(other: ref template): bool { return name == name && syntax_node == other.syntax_node && instantiated == other.instantiated && scope == other.scope && template_types == other.template_types && template_type_replacements == other.template_type_replacements && instantiated_map == other.instantiated_map && is_function == other.is_function } } fun ast_code_block_ptr(): *ast_node { var to_ret.construct(): code_block var ptr = new() ptr->copy_construct(&ast_node::code_block(to_ret)) return ptr } fun is_code_block(node: *ast_node): bool { match(*node) { ast_node::code_block(backing) return true } return false } obj code_block (Object) { var scope: map> var children: vector<*ast_node> fun construct(): *code_block { scope.construct() children.construct() return this } fun copy_construct(old: *code_block) { scope.copy_construct(&old->scope) children.copy_construct(&old->children) } fun destruct() { scope.destruct() children.destruct() } fun operator=(other: ref code_block) { destruct() copy_construct(&other) } fun operator==(other: ref code_block): bool { return children == other.children && scope == other.scope } } fun ast_statement_ptr(child: *ast_node): *ast_node { var to_ret.construct(child): statement var ptr = new() ptr->copy_construct(&ast_node::statement(to_ret)) return ptr } fun is_statement(node: *ast_node): bool { match(*node) { ast_node::statement(backing) return true } return false } obj statement (Object) { var scope: map> var child: *ast_node fun construct(child_in: *ast_node): *statement { child = null() scope.construct() child = child_in return this } fun copy_construct(old: *statement) { scope.copy_construct(&old->scope) child = old->child } fun destruct() { scope.destruct() } fun operator=(other: ref statement) { destruct() copy_construct(&other) } fun operator==(other: ref statement): bool { return child == other.child } } fun ast_if_statement_ptr(condition: *ast_node): *ast_node { var to_ret.construct(condition): if_statement var ptr = new() ptr->copy_construct(&ast_node::if_statement(to_ret)) return ptr } fun is_if_statement(node: *ast_node): bool { match(*node) { ast_node::if_statement(backing) return true } return false } obj if_statement (Object) { var condition: *ast_node // these are not a part of the constructor because they have to be trnasformed with this as its scope var then_part: *ast_node var else_part: *ast_node var scope: map> fun construct(condition_in: *ast_node): *if_statement { condition = condition_in then_part = null() else_part = null() scope.construct() return this } fun copy_construct(old: *if_statement) { condition = old->condition then_part = old->then_part else_part = old->else_part scope.copy_construct(&old->scope) } fun destruct() { scope.destruct() } fun operator=(other: ref if_statement) { destruct() copy_construct(&other) } fun operator==(other: ref if_statement): bool { return condition == other.condition && then_part == other.then_part && else_part == other.else_part } } fun ast_match_statement_ptr(value: *ast_node): *ast_node { var to_ret.construct(value): match_statement var ptr = new() ptr->copy_construct(&ast_node::match_statement(to_ret)) return ptr } fun is_match_statement(node: *ast_node): bool { match(*node) { ast_node::match_statement(backing) return true } return false } obj match_statement (Object) { var scope: map> var value: *ast_node var cases: vector<*ast_node> fun construct(value_in: *ast_node): *match_statement { scope.construct() value = value_in cases.construct() return this } fun copy_construct(old: *match_statement) { scope.copy_construct(&old->scope) value = old->value cases.copy_construct(&old->cases) } fun destruct() { scope.destruct() cases.destruct() } fun operator=(other: ref match_statement) { destruct() copy_construct(&other) } fun operator==(other: ref match_statement): bool { return value == other.value && cases == other.cases && scope == other.scope } } fun ast_case_statement_ptr(): *ast_node { var to_ret.construct(): case_statement var ptr = new() ptr->copy_construct(&ast_node::case_statement(to_ret)) return ptr } fun is_case_statement(node: *ast_node): bool { match(*node) { ast_node::case_statement(backing) return true } return false } obj case_statement (Object) { var scope: map> var option: *ast_node var unpack_ident: *ast_node var statement: *ast_node fun construct(): *case_statement { scope.construct() option = null() unpack_ident = null() statement = null() return this } fun copy_construct(old: *case_statement) { scope.copy_construct(&old->scope) option = old->option unpack_ident = old->unpack_ident statement = old->statement } fun destruct() { scope.destruct() } fun operator=(other: ref case_statement) { destruct() copy_construct(&other) } fun operator==(other: ref case_statement): bool { return option == other.option && unpack_ident == other.unpack_ident && statement == other.statement } } fun ast_while_loop_ptr(condition: *ast_node): *ast_node { var to_ret.construct(condition): while_loop var ptr = new() ptr->copy_construct(&ast_node::while_loop(to_ret)) return ptr } fun is_while_loop(node: *ast_node): bool { match(*node) { ast_node::while_loop(backing) return true } return false } obj while_loop (Object) { var condition: *ast_node var statement: *ast_node var scope: map> fun construct(condition_in: *ast_node): *while_loop { condition = condition_in statement = null() scope.construct() return this } fun copy_construct(old: *while_loop) { condition = old->condition statement = old->statement scope.copy_construct(&old->scope) } fun destruct() { scope.destruct() } fun operator=(other: ref while_loop) { destruct() copy_construct(&other) } fun operator==(other: ref while_loop): bool { return condition == other.condition && statement == other.statement } } fun ast_for_loop_ptr(): *ast_node { var to_ret.construct(): for_loop var ptr = new() ptr->copy_construct(&ast_node::for_loop(to_ret)) return ptr } fun is_for_loop(node: *ast_node): bool { match(*node) { ast_node::for_loop(backing) return true } return false } obj for_loop (Object) { var init: *ast_node var condition: *ast_node var update: *ast_node var body: *ast_node var scope: map> fun construct(): *for_loop { scope.construct() init = null() condition = null() update = null() body = null() return this } fun copy_construct(old: *for_loop) { init = old->init condition = old->condition update = old->update body = old->body scope.copy_construct(&old->scope) } fun destruct() { scope.destruct() } fun operator=(other: ref for_loop) { destruct() copy_construct(&other) } fun operator==(other: ref for_loop): bool { return init == other.init && condition == other.condition && update == other.update && body == other.body } } fun ast_return_statement_ptr(return_value: *ast_node): *ast_node { var to_ret.construct(return_value): return_statement var ptr = new() ptr->copy_construct(&ast_node::return_statement(to_ret)) return ptr } fun is_return_statement(node: *ast_node): bool { match(*node) { ast_node::return_statement(backing) return true } return false } obj return_statement (Object) { var return_value: *ast_node var scope: map> fun construct(return_value_in: *ast_node): *return_statement { return_value = return_value_in scope.construct() return this } fun copy_construct(old: *return_statement) { return_value = old->return_value scope.copy_construct(&old->scope) } fun destruct() { scope.destruct() } fun operator=(other: ref return_statement) { destruct() copy_construct(&other) } fun operator==(other: ref return_statement): bool { return return_value == other.return_value } } adt branching_type { break_stmt, continue_stmt } fun ast_branching_statement_ptr(b_type: branching_type): *ast_node { var to_ret.construct(b_type): branching_statement var ptr = new() ptr->copy_construct(&ast_node::branching_statement(to_ret)) return ptr } fun is_branching_statement(node: *ast_node): bool { match(*node) { ast_node::branching_statement(backing) return true } return false } obj branching_statement (Object) { var b_type: branching_type fun construct(b_type_in: branching_type): *branching_statement { b_type.copy_construct(&b_type_in) return this } fun copy_construct(old: *branching_statement) { b_type.copy_construct(&old->b_type) } fun destruct() { b_type.destruct() } fun operator=(other: ref branching_statement) { destruct() copy_construct(&other) } fun operator==(other: ref branching_statement): bool { return true } } fun ast_defer_statement_ptr(statement_in: *ast_node): *ast_node { var to_ret.construct(statement_in): defer_statement var ptr = new() ptr->copy_construct(&ast_node::defer_statement(to_ret)) return ptr } fun is_defer_statement(node: *ast_node): bool { match(*node) { ast_node::defer_statement(backing) return true } return false } obj defer_statement (Object) { var statement: *ast_node fun construct(statement_in: *ast_node): *defer_statement { statement = statement_in return this } fun copy_construct(old: *defer_statement) { statement = old->statement } fun destruct() { } fun operator=(other: ref defer_statement) { destruct() copy_construct(&other) } fun operator==(other: ref defer_statement): bool { return true } } fun ast_assignment_statement_ptr(to: *ast_node, from: *ast_node): *ast_node { var to_ret.construct(to, from): assignment_statement var ptr = new() ptr->copy_construct(&ast_node::assignment_statement(to_ret)) return ptr } fun is_assignment_statement(node: *ast_node): bool { match(*node) { ast_node::assignment_statement(backing) return true } return false } obj assignment_statement (Object) { var to: *ast_node var from: *ast_node fun construct(to_in: *ast_node, from_in: *ast_node): *assignment_statement { to = to_in from = from_in return this } fun copy_construct(old: *assignment_statement) { to = old->to from = old->from } fun destruct() { } fun operator=(other: ref assignment_statement) { destruct() copy_construct(&other) } fun operator==(other: ref assignment_statement): bool { return to == other.to && from == other.from } } fun ast_declaration_statement_ptr(ident: *ast_node, expression: *ast_node): *ast_node { var to_ret.construct(ident, expression): declaration_statement var ptr = new() ptr->copy_construct(&ast_node::declaration_statement(to_ret)) return ptr } fun is_declaration_statement(node: *ast_node): bool { match(*node) { ast_node::declaration_statement(backing) return true } return false } obj declaration_statement (Object) { var identifier: *ast_node var expression: *ast_node var init_method_call: *ast_node fun construct(identifier_in: *ast_node, expression_in: *ast_node): *declaration_statement { identifier = identifier_in expression = expression_in init_method_call = null() return this } fun copy_construct(old: *declaration_statement) { identifier = old->identifier expression = old->expression init_method_call = old->init_method_call } fun destruct() { } fun operator=(other: ref declaration_statement) { destruct() copy_construct(&other) } fun operator==(other: ref declaration_statement): bool { return identifier == other.identifier && expression == other.expression && init_method_call == other.init_method_call } } fun ast_if_comp_ptr(): *ast_node { var to_ret.construct(): if_comp var ptr = new() ptr->copy_construct(&ast_node::if_comp(to_ret)) return ptr } fun is_if_comp(node: *ast_node): bool { match(*node) { ast_node::if_comp(backing) return true } return false } obj if_comp (Object) { var wanted_generator: string var statement: *ast_node fun construct(): *if_comp { wanted_generator.construct() return this } fun copy_construct(old: *if_comp) { wanted_generator.copy_construct(&old->wanted_generator) statement = old->statement } fun destruct() { wanted_generator.destruct() } fun operator=(other: if_comp) { destruct() copy_construct(&other) } fun operator==(other: if_comp): bool { return wanted_generator == other.wanted_generator && statement == other.statement } } fun ast_simple_passthrough_ptr(): *ast_node { var to_ret.construct(): simple_passthrough var ptr = new() ptr->copy_construct(&ast_node::simple_passthrough(to_ret)) return ptr } fun is_simple_passthrough(node: *ast_node): bool { match(*node) { ast_node::simple_passthrough(backing) return true } return false } obj simple_passthrough (Object) { var scope: map> var passthrough_str: string var in_params: vector> var out_params: vector> var linker_str: string fun construct(): *simple_passthrough { scope.construct() passthrough_str.construct() in_params.construct() out_params.construct() linker_str.construct() return this } fun copy_construct(old: *simple_passthrough) { scope.copy_construct(&old->scope) passthrough_str.copy_construct(&old->passthrough_str) in_params.copy_construct(&old->in_params) out_params.copy_construct(&old->out_params) linker_str.copy_construct(&old->linker_str) } fun destruct() { scope.destruct() passthrough_str.destruct() in_params.destruct() out_params.destruct() linker_str.destruct() } fun operator=(other: ref simple_passthrough) { destruct() copy_construct(&other) } fun operator==(other: ref simple_passthrough): bool { return scope == other.scope && passthrough_str == other.passthrough_str && in_params == other.in_params && out_params == other.out_params && linker_str == other.linker_str } } fun ast_function_call_ptr(func: *ast_node, parameters: vector<*ast_node>): *ast_node { var to_ret.construct(func, parameters): function_call var ptr = new() ptr->copy_construct(&ast_node::function_call(to_ret)) return ptr } fun is_function_call(node: *ast_node): bool { match(*node) { ast_node::function_call(backing) return true } return false } obj function_call (Object) { var func: *ast_node var parameters: vector<*ast_node> fun construct(func_in: *ast_node, parameters_in: vector<*ast_node>): *function_call { func = func_in parameters.copy_construct(¶meters_in) return this } fun copy_construct(old: *function_call) { func = old->func parameters.copy_construct(&old->parameters) } fun destruct() { parameters.destruct() } fun operator=(other: ref function_call) { destruct() copy_construct(&other) } fun operator==(other: ref function_call): bool { return func == func && parameters == other.parameters } } fun ast_compiler_intrinsic_ptr(intrinsic: string, parameters: vector, type_parameters: vector<*type>, return_type: *type): *ast_node { var to_ret.construct(intrinsic, parameters, type_parameters, return_type): compiler_intrinsic var ptr = new() ptr->copy_construct(&ast_node::compiler_intrinsic(to_ret)) return ptr } fun is_compiler_intrinsic(node: *ast_node): bool { match(*node) { ast_node::compiler_intrinsic(backing) return true } return false } obj compiler_intrinsic (Object) { var intrinsic: string var parameters: vector var type_parameters: vector<*type> var return_type: *type fun construct(intrinsic_in: string, parameters_in: vector, type_parameters_in: vector<*type>, return_type_in: *type): *compiler_intrinsic { intrinsic.copy_construct(&intrinsic_in) parameters.copy_construct(¶meters_in) type_parameters.copy_construct(&type_parameters_in) return_type = return_type_in return this } /*fun copy_construct(old: *function_call) {*/ fun copy_construct(old: *compiler_intrinsic) { intrinsic.copy_construct(&old->intrinsic) parameters.copy_construct(&old->parameters) type_parameters.copy_construct(&old->type_parameters) return_type = old->return_type } fun destruct() { intrinsic.destruct() parameters.destruct() type_parameters.destruct() } fun operator=(other: ref compiler_intrinsic) { destruct() copy_construct(&other) } fun operator==(other: ref compiler_intrinsic): bool { return intrinsic == intrinsic && parameters == other.parameters && type_parameters == other.type_parameters && return_type == other.return_type } } fun ast_cast_ptr(value: *ast_node, to_type: *type): *ast_node { var to_ret.construct(value, to_type): cast var ptr = new() ptr->copy_construct(&ast_node::cast(to_ret)) return ptr } fun is_cast(node: *ast_node): bool { match(*node) { ast_node::cast(backing) return true } return false } obj cast (Object) { var value: *ast_node var to_type: *type fun construct(value_in: *ast_node, to_type_in: *type): *cast { value = value_in to_type = to_type_in return this } fun copy_construct(old: *cast) { value = old->value to_type = old->to_type } fun destruct() { } fun operator=(other: cast) { destruct() copy_construct(&other) } fun operator==(other: cast): bool { return value == other.value && to_type == other.to_type } } fun ast_value_ptr(string_value: string, value_type: *type): *ast_node { var to_ret.construct(string_value, value_type): value var ptr = new() ptr->copy_construct(&ast_node::value(to_ret)) return ptr } fun is_value(node: *ast_node): bool { match(*node) { ast_node::value(backing) return true } return false } obj value (Object) { var string_value: string var value_type: *type var scope: map> fun construct(string_value_in: string, value_type_in: *type): *value { scope.construct() string_value.copy_construct(&string_value_in) value_type = value_type_in return this } fun copy_construct(old: *value) { scope.copy_construct(&old->scope) string_value.copy_construct(&old->string_value) value_type = old->value_type } fun destruct() { scope.destruct() string_value.destruct() } fun operator=(other: ref value) { destruct() copy_construct(&other) } fun operator==(other: ref value): bool { return string_value == other.string_value && value_type == other.value_type } } fun get_ast_children(node: *ast_node): vector<*ast_node> { match (*node) { ast_node::translation_unit(backing) return backing.children + backing.lambdas ast_node::import(backing) return vector<*ast_node>() ast_node::identifier(backing) return vector<*ast_node>() ast_node::type_def(backing) return backing.variables + backing.methods ast_node::adt_def(backing) return backing.options + backing.option_funcs ast_node::function(backing) return backing.parameters + backing.body_statement ast_node::template(backing) return backing.instantiated ast_node::code_block(backing) return backing.children ast_node::statement(backing) return vector<*ast_node>(backing.child) ast_node::if_statement(backing) return vector(backing.condition, backing.then_part, backing.else_part) ast_node::match_statement(backing) return vector(backing.value) + backing.cases ast_node::case_statement(backing) return vector(backing.option, backing.unpack_ident, backing.statement) ast_node::while_loop(backing) return vector(backing.condition, backing.statement) ast_node::for_loop(backing) return vector(backing.init, backing.condition, backing.update, backing.body) ast_node::return_statement(backing) return vector(backing.return_value) ast_node::branching_statement(backing) return vector<*ast_node>() ast_node::defer_statement(backing) return vector(backing.statement) ast_node::assignment_statement(backing) return vector(backing.to, backing.from) ast_node::declaration_statement(backing) return vector(backing.identifier, backing.expression, backing.init_method_call) ast_node::if_comp(backing) return vector<*ast_node>(backing.statement) ast_node::simple_passthrough(backing) return vector<*ast_node>() ast_node::function_call(backing) return vector(backing.func) + backing.parameters ast_node::compiler_intrinsic(backing) return vector<*ast_node>() ast_node::cast(backing) return vector<*ast_node>(backing.value) ast_node::value(backing) return vector<*ast_node>() } } fun get_ast_name(node: *ast_node): string { match (*node) { ast_node::translation_unit(backing) return string("translation_unit: ") + backing.name ast_node::import(backing) return string("import: ") + backing.name + "; [" + backing.imported.reduce(fun(name: string, acc: string): string return acc + " " + name;, string()) + " ]" ast_node::identifier(backing) return string("identifier: ") + backing.name + ": " + backing.type->to_string() ast_node::type_def(backing) return string("type_def: ") + backing.name ast_node::adt_def(backing) return string("adt_def: ") + backing.name ast_node::function(backing) { if (backing.is_extern) return string("extern function: ") + backing.name + ": " + backing.type->to_string() else return string("function: ") + backing.name + ": " + backing.type->to_string() } ast_node::template(backing) return string("template: ") + backing.name ast_node::code_block(backing) return string("code_block") ast_node::statement(backing) return string("statement") ast_node::if_statement(backing) return string("if_statement") ast_node::match_statement(backing) return string("match_statement") ast_node::case_statement(backing) return string("case_statement") ast_node::while_loop(backing) return string("while_loop") ast_node::for_loop(backing) return string("for_loop") ast_node::return_statement(backing) return string("return_statement") ast_node::branching_statement(backing) return string("branching_statement") ast_node::defer_statement(backing) return string("defer_statement") ast_node::assignment_statement(backing) return string("assignment_statement") ast_node::declaration_statement(backing) return string("declaration_statement") ast_node::if_comp(backing) return string("if_comp: ") + backing.wanted_generator ast_node::simple_passthrough(backing) return string("simple_passthrough: , string:") + backing.passthrough_str ast_node::function_call(backing) return string("function_call:") + get_ast_name(backing.func) + "(" + backing.parameters.size + ")" ast_node::compiler_intrinsic(backing) return string("compiler_intrinsic:") + backing.intrinsic + "(" + backing.parameters.size + "," + backing.type_parameters.size + "):" + backing.return_type->to_string() ast_node::cast(backing) return string("cast: ") + get_ast_name(backing.value) + ": " + backing.to_type->to_string() ast_node::value(backing) return string("value: ") + backing.string_value + ": " + backing.value_type->to_string() } return string("impossible adt type") } fun get_ast_scope(node: *ast_node): *map> { match (*node) { ast_node::translation_unit() return &node->translation_unit.scope ast_node::import() return &node->import.scope ast_node::identifier() return &node->identifier.scope ast_node::type_def() return &node->type_def.scope ast_node::adt_def() return &node->adt_def.scope ast_node::function() return &node->function.scope ast_node::template() return &node->template.scope ast_node::code_block() return &node->code_block.scope ast_node::statement() return &node->statement.scope ast_node::if_statement() return &node->if_statement.scope ast_node::match_statement() return &node->match_statement.scope ast_node::case_statement() return &node->case_statement.scope ast_node::while_loop() return &node->while_loop.scope ast_node::for_loop() return &node->for_loop.scope ast_node::return_statement() return &node->return_statement.scope ast_node::simple_passthrough() return &node->simple_passthrough.scope ast_node::value() return &node->value.scope } return null>>() } fun get_ast_type(node: *ast_node): *type { match (*node) { ast_node::identifier(backing) return backing.type ast_node::function(backing) return backing.type ast_node::function_call(backing) return get_ast_type(backing.func)->return_type ast_node::compiler_intrinsic(backing) return backing.return_type ast_node::cast(backing) return backing.to_type ast_node::value(backing) return backing.value_type } } fun ast_to_dot(root: *ast_node): string { var ret = string("digraph Kaken {\n") var counter = 0 var node_name_map = map<*ast_node, string>() var get_name = fun(node: *ast_node): string { if (node_name_map.contains_key(node)) return node_name_map[node] var escaped = string("") get_ast_name(node).data.for_each(fun(c: char) { if (c != '"') escaped += c else escaped += "\\\"" }) escaped += to_string(counter++) node_name_map.set(node, escaped) return escaped } var done_set = set<*ast_node>() var helper: fun(*ast_node):void = fun(node: *ast_node) { done_set.add(node) get_ast_children(node).for_each(fun(child: *ast_node) { if (!child || done_set.contains(child)) return; // where on earth does the null come from ret += string("\"") + get_name(node) + "\" -> \"" + get_name(child) + "\"\n"; helper(child) }) } if (root) helper(root) return ret + "}" }