Files
kraken/stdlib/ast_nodes.krak

1217 lines
41 KiB
Plaintext
Raw Normal View History

2015-12-05 07:13:32 -05:00
import tree:*
2016-03-24 21:32:28 -04:00
import symbol:*
2015-12-05 07:13:32 -05:00
import vector:*
2016-01-16 22:14:59 -05:00
import vector_literals:*
2015-12-28 03:34:40 -05:00
import set:*
2015-12-05 07:13:32 -05:00
import stack:*
import map:*
import util:*
import string:*
import mem:*
import io:*
import type:*
2015-12-05 07:13:32 -05:00
adt ast_node {
translation_unit: translation_unit,
import: import,
identifier: identifier,
type_def: type_def,
adt_def: adt_def,
function: function,
template: template,
2015-12-05 07:13:32 -05:00
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,
2016-01-24 17:31:41 -05:00
branching_statement: branching_statement,
2015-12-05 07:13:32 -05:00
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,
2015-12-05 07:13:32 -05:00
value: value
}
/*
total:
ASTType type;
Type* valueType;
Symbol symbol;
std::map<std::string, std::vector<NodeTree<ASTData>*>> scope;
std::set<NodeTree<ASTData>*> closedVariables;
*/
fun ast_node_ptr(node: ast_node): *ast_node {
var to_ret = new<ast_node>()
to_ret->copy_construct(&node)
return to_ret
}
2015-12-06 18:44:04 -05:00
fun ast_translation_unit_ptr(name: string): *ast_node {
2015-12-28 03:34:40 -05:00
var obj_var.construct(name): translation_unit
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj translation_unit (Object) {
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
2015-12-05 07:13:32 -05:00
var children: vector<*ast_node>
var lambdas: vector<*ast_node>
2015-12-06 18:44:04 -05:00
var name: string
fun construct(nameIn: string): *translation_unit {
2015-12-07 13:43:22 -05:00
scope.construct()
2015-12-05 07:13:32 -05:00
children.construct()
lambdas.construct()
2015-12-06 18:44:04 -05:00
name.copy_construct(&nameIn)
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *translation_unit) {
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2015-12-05 07:13:32 -05:00
children.copy_construct(&old->children)
lambdas.copy_construct(&old->lambdas)
2015-12-06 18:44:04 -05:00
name.copy_construct(&old->name)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-05 07:13:32 -05:00
children.destruct()
lambdas.destruct()
2015-12-06 18:44:04 -05:00
name.destruct()
2015-12-05 07:13:32 -05:00
}
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
2015-12-05 07:13:32 -05:00
}
}
fun ast_import_ptr(name: string, translation_unit: *ast_node): *ast_node {
var to_ret.construct(name, translation_unit): import
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj import (Object) {
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
2015-12-28 03:34:40 -05:00
var imported: set<string>
var translation_unit: *ast_node
2015-12-06 18:44:04 -05:00
var name: string
var starred: bool
fun construct(nameIn: string, translation_unit_in: *ast_node): *import {
2015-12-07 13:43:22 -05:00
scope.construct()
2015-12-28 03:34:40 -05:00
imported.construct()
2015-12-06 18:44:04 -05:00
name.copy_construct(&nameIn)
translation_unit = translation_unit_in
starred = false
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *import) {
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2015-12-28 03:34:40 -05:00
imported.copy_construct(&old->imported)
2015-12-06 18:44:04 -05:00
name.copy_construct(&old->name)
translation_unit = old->translation_unit
starred = old->starred
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-28 03:34:40 -05:00
imported.destruct()
2015-12-06 18:44:04 -05:00
name.destruct()
2015-12-05 07:13:32 -05:00
}
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
2015-12-05 07:13:32 -05:00
}
}
fun ast_identifier_ptr(name: *char, type: *type, enclosing_scope: *ast_node): *ast_node {
return ast_identifier_ptr(string(name), type, enclosing_scope)
2015-12-28 03:34:40 -05:00
}
fun ast_identifier_ptr(name: string, type: *type, enclosing_scope: *ast_node): *ast_node {
var to_ret.construct(name, type, enclosing_scope): identifier
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj identifier (Object) {
2015-12-28 03:34:40 -05:00
var name: string
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
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)
2015-12-07 13:43:22 -05:00
scope.construct()
type = type_in
identifier::enclosing_scope = enclosing_scope
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *identifier) {
2015-12-28 03:34:40 -05:00
name.copy_construct(&old->name)
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
type = old->type
enclosing_scope = old->enclosing_scope
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-28 03:34:40 -05:00
name.destruct()
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-05 07:13:32 -05:00
}
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
2015-12-05 07:13:32 -05:00
}
}
2015-12-06 18:44:04 -05:00
fun ast_type_def_ptr(name: string): *ast_node {
2015-12-28 03:34:40 -05:00
var to_ret.construct(name): type_def
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj type_def (Object) {
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
2015-12-06 18:44:04 -05:00
var name: string
var self_type: *type
var variables: vector<*ast_node>
var methods: vector<*ast_node>
2015-12-06 18:44:04 -05:00
fun construct(nameIn: string): *type_def {
2015-12-07 13:43:22 -05:00
scope.construct()
2015-12-06 18:44:04 -05:00
name.copy_construct(&nameIn)
self_type = null<type>()
variables.construct()
methods.construct()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *type_def) {
self_type = old->self_type
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2015-12-06 18:44:04 -05:00
name.copy_construct(&old->name)
variables.copy_construct(&old->variables)
methods.copy_construct(&old->methods)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-06 18:44:04 -05:00
name.destruct()
variables.destruct()
methods.destruct()
2015-12-05 07:13:32 -05:00
}
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
2015-12-05 07:13:32 -05:00
}
}
2015-12-06 18:44:04 -05:00
fun ast_adt_def_ptr(name: string): *ast_node {
2015-12-28 03:34:40 -05:00
var to_ret.construct(name): adt_def
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj adt_def (Object) {
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
2015-12-06 18:44:04 -05:00
var name: string
var self_type: *type
var options: vector<*ast_node>
var option_funcs: vector<*ast_node>
var regular_funcs: vector<*ast_node>
2015-12-06 18:44:04 -05:00
fun construct(nameIn: string): *adt_def {
2015-12-07 13:43:22 -05:00
scope.construct()
2015-12-06 18:44:04 -05:00
name.copy_construct(&nameIn)
self_type = null<type>()
options.construct()
option_funcs.construct()
regular_funcs.construct()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *adt_def) {
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2015-12-06 18:44:04 -05:00
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)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-06 18:44:04 -05:00
name.destruct()
options.destruct()
option_funcs.destruct()
regular_funcs.destruct()
2015-12-05 07:13:32 -05:00
}
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
2015-12-05 07:13:32 -05:00
}
}
2016-04-29 01:14:26 -04:00
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
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
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
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
2016-04-29 01:14:26 -04:00
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(&parameters_in)
closed_variables.construct()
2015-12-07 13:43:22 -05:00
scope.construct()
type = type_in
body_statement = null<ast_node>()
2016-04-29 01:14:26 -04:00
is_extern = is_extern_in
2015-12-05 07:13:32 -05:00
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)
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2016-04-29 01:14:26 -04:00
is_extern = old->is_extern
2015-12-05 07:13:32 -05:00
}
fun destruct() {
name.destruct()
parameters.destruct()
closed_variables.destruct()
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: ref function) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref function): bool {
2016-04-29 01:14:26 -04:00
return name == name && type == other.type && parameters == other.parameters && body_statement == other.body_statement && closed_variables == other.closed_variables && is_extern == other.is_extern
2015-12-05 07:13:32 -05:00
}
}
fun ast_template_ptr(name: string, syntax_node: *tree<symbol>, template_types: vector<string>, template_type_replacements: map<string, *type>, is_function: bool): *ast_node {
var to_ret.construct(name, syntax_node, template_types, template_type_replacements, is_function): template
var ptr = new<ast_node>()
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<symbol>
var instantiated: vector<*ast_node>
var template_types: vector<string>
var template_type_replacements: map<string, *type>
var instantiated_map: map<vector<type>, *ast_node>
var scope: map<string, vector<*ast_node>>
var is_function: bool
fun construct(name_in: string, syntax_node_in: *tree<symbol>, template_types_in: vector<string>, template_type_replacements_in: map<string, *type>, 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
}
}
2015-12-06 15:15:33 -05:00
fun ast_code_block_ptr(): *ast_node {
2015-12-28 03:34:40 -05:00
var to_ret.construct(): code_block
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj code_block (Object) {
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
2015-12-28 03:34:40 -05:00
var children: vector<*ast_node>
2015-12-05 07:13:32 -05:00
fun construct(): *code_block {
2015-12-07 13:43:22 -05:00
scope.construct()
2015-12-28 03:34:40 -05:00
children.construct()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *code_block) {
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2015-12-28 03:34:40 -05:00
children.copy_construct(&old->children)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-28 03:34:40 -05:00
children.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: ref code_block) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref code_block): bool {
2015-12-28 03:34:40 -05:00
return children == other.children && scope == other.scope
2015-12-05 07:13:32 -05:00
}
}
fun ast_statement_ptr(child: *ast_node): *ast_node {
var to_ret.construct(child): statement
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj statement (Object) {
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
var child: *ast_node
fun construct(child_in: *ast_node): *statement {
child = null<ast_node>()
2015-12-07 13:43:22 -05:00
scope.construct()
child = child_in
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *statement) {
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
child = old->child
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: ref statement) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref statement): bool {
return child == other.child
2015-12-05 07:13:32 -05:00
}
}
2016-01-19 02:06:30 -05:00
fun ast_if_statement_ptr(condition: *ast_node): *ast_node {
var to_ret.construct(condition): if_statement
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj if_statement (Object) {
2016-01-19 02:06:30 -05:00
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
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
2016-01-19 02:06:30 -05:00
fun construct(condition_in: *ast_node): *if_statement {
condition = condition_in
then_part = null<ast_node>()
else_part = null<ast_node>()
2015-12-07 13:43:22 -05:00
scope.construct()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *if_statement) {
2016-01-19 02:06:30 -05:00
condition = old->condition
then_part = old->then_part
else_part = old->else_part
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: ref if_statement) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref if_statement): bool {
2016-01-19 02:06:30 -05:00
return condition == other.condition && then_part == other.then_part && else_part == other.else_part
2015-12-05 07:13:32 -05:00
}
}
fun ast_match_statement_ptr(value: *ast_node): *ast_node {
var to_ret.construct(value): match_statement
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj match_statement (Object) {
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
var value: *ast_node
var cases: vector<*ast_node>
fun construct(value_in: *ast_node): *match_statement {
2015-12-07 13:43:22 -05:00
scope.construct()
value = value_in
cases.construct()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *match_statement) {
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
value = old->value
cases.copy_construct(&old->cases)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
cases.destruct()
2015-12-05 07:13:32 -05:00
}
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
2015-12-05 07:13:32 -05:00
}
}
2015-12-06 15:15:33 -05:00
fun ast_case_statement_ptr(): *ast_node {
2015-12-28 03:34:40 -05:00
var to_ret.construct(): case_statement
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj case_statement (Object) {
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
var option: *ast_node
var unpack_ident: *ast_node
var statement: *ast_node
2015-12-05 07:13:32 -05:00
fun construct(): *case_statement {
2015-12-07 13:43:22 -05:00
scope.construct()
option = null<ast_node>()
unpack_ident = null<ast_node>()
statement = null<ast_node>()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *case_statement) {
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
option = old->option
unpack_ident = old->unpack_ident
statement = old->statement
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-05 07:13:32 -05:00
}
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
2015-12-05 07:13:32 -05:00
}
}
fun ast_while_loop_ptr(condition: *ast_node): *ast_node {
var to_ret.construct(condition): while_loop
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj while_loop (Object) {
var condition: *ast_node
var statement: *ast_node
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
fun construct(condition_in: *ast_node): *while_loop {
condition = condition_in
statement = null<ast_node>()
2015-12-07 13:43:22 -05:00
scope.construct()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *while_loop) {
condition = old->condition
statement = old->statement
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: ref while_loop) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref while_loop): bool {
return condition == other.condition && statement == other.statement
2015-12-05 07:13:32 -05:00
}
}
2015-12-06 15:15:33 -05:00
fun ast_for_loop_ptr(): *ast_node {
2015-12-28 03:34:40 -05:00
var to_ret.construct(): for_loop
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj for_loop (Object) {
2016-01-19 11:47:09 -05:00
var init: *ast_node
var condition: *ast_node
var update: *ast_node
var body: *ast_node
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
2015-12-05 07:13:32 -05:00
fun construct(): *for_loop {
2015-12-07 13:43:22 -05:00
scope.construct()
2016-01-19 11:47:09 -05:00
init = null<ast_node>()
condition = null<ast_node>()
update = null<ast_node>()
body = null<ast_node>()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *for_loop) {
2016-01-19 11:47:09 -05:00
init = old->init
condition = old->condition
update = old->update
body = old->body
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: ref for_loop) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref for_loop): bool {
2016-01-19 11:47:09 -05:00
return init == other.init && condition == other.condition && update == other.update && body == other.body
2015-12-05 07:13:32 -05:00
}
}
fun ast_return_statement_ptr(return_value: *ast_node): *ast_node {
var to_ret.construct(return_value): return_statement
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj return_statement (Object) {
var return_value: *ast_node
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
fun construct(return_value_in: *ast_node): *return_statement {
return_value = return_value_in
2015-12-07 13:43:22 -05:00
scope.construct()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *return_statement) {
return_value = old->return_value
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: ref return_statement) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref return_statement): bool {
return return_value == other.return_value
2015-12-05 07:13:32 -05:00
}
}
2016-01-24 17:31:41 -05:00
adt branching_type {
break_stmt,
continue_stmt
2015-12-05 07:13:32 -05:00
}
2016-01-24 17:31:41 -05:00
fun ast_branching_statement_ptr(b_type: branching_type): *ast_node {
var to_ret.construct(b_type): branching_statement
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
2016-01-24 17:31:41 -05:00
ptr->copy_construct(&ast_node::branching_statement(to_ret))
2015-12-05 07:13:32 -05:00
return ptr
}
2016-01-24 17:31:41 -05:00
fun is_branching_statement(node: *ast_node): bool {
match(*node) {
2016-01-24 17:31:41 -05:00
ast_node::branching_statement(backing) return true
}
return false
}
2016-01-24 17:31:41 -05:00
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)
2015-12-05 07:13:32 -05:00
return this
}
2016-01-24 17:31:41 -05:00
fun copy_construct(old: *branching_statement) {
b_type.copy_construct(&old->b_type)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2016-01-24 17:31:41 -05:00
b_type.destruct()
2015-12-05 07:13:32 -05:00
}
2016-01-24 17:31:41 -05:00
fun operator=(other: ref branching_statement) {
2015-12-05 07:13:32 -05:00
destruct()
copy_construct(&other)
}
2016-01-24 17:31:41 -05:00
fun operator==(other: ref branching_statement): bool {
2015-12-05 07:13:32 -05:00
return true
}
}
fun ast_defer_statement_ptr(statement_in: *ast_node): *ast_node {
var to_ret.construct(statement_in): defer_statement
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj defer_statement (Object) {
var statement: *ast_node
fun construct(statement_in: *ast_node): *defer_statement {
statement = statement_in
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *defer_statement) {
statement = old->statement
2015-12-05 07:13:32 -05:00
}
fun destruct() {
}
fun operator=(other: ref defer_statement) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref defer_statement): bool {
return true
}
}
2016-01-16 22:14:59 -05:00
fun ast_assignment_statement_ptr(to: *ast_node, from: *ast_node): *ast_node {
var to_ret.construct(to, from): assignment_statement
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj assignment_statement (Object) {
2016-01-16 22:14:59 -05:00
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
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *assignment_statement) {
2016-01-16 22:14:59 -05:00
to = old->to
from = old->from
2015-12-05 07:13:32 -05:00
}
fun destruct() {
}
fun operator=(other: ref assignment_statement) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref assignment_statement): bool {
2016-01-16 22:14:59 -05:00
return to == other.to && from == other.from
2015-12-05 07:13:32 -05:00
}
}
fun ast_declaration_statement_ptr(ident: *ast_node, expression: *ast_node): *ast_node {
var to_ret.construct(ident, expression): declaration_statement
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj declaration_statement (Object) {
2016-01-15 19:10:52 -05:00
var identifier: *ast_node
var expression: *ast_node
2016-01-28 20:51:40 -05:00
var init_method_call: *ast_node
fun construct(identifier_in: *ast_node, expression_in: *ast_node): *declaration_statement {
2016-01-15 19:10:52 -05:00
identifier = identifier_in
expression = expression_in
2016-01-28 20:51:40 -05:00
init_method_call = null<ast_node>()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *declaration_statement) {
2016-01-15 19:10:52 -05:00
identifier = old->identifier
expression = old->expression
2016-01-28 20:51:40 -05:00
init_method_call = old->init_method_call
2015-12-05 07:13:32 -05:00
}
fun destruct() {
}
fun operator=(other: ref declaration_statement) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref declaration_statement): bool {
2016-01-28 20:51:40 -05:00
return identifier == other.identifier && expression == other.expression && init_method_call == other.init_method_call
2015-12-05 07:13:32 -05:00
}
}
2015-12-06 15:15:33 -05:00
fun ast_if_comp_ptr(): *ast_node {
2015-12-28 03:34:40 -05:00
var to_ret.construct(): if_comp
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj if_comp (Object) {
var wanted_generator: string
var statement: *ast_node
2015-12-05 07:13:32 -05:00
fun construct(): *if_comp {
wanted_generator.construct()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *if_comp) {
wanted_generator.copy_construct(&old->wanted_generator)
statement = old->statement
2015-12-05 07:13:32 -05:00
}
fun destruct() {
wanted_generator.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: if_comp) {
2015-12-05 07:13:32 -05:00
destruct()
copy_construct(&other)
}
fun operator==(other: if_comp): bool {
return wanted_generator == other.wanted_generator && statement == other.statement
2015-12-05 07:13:32 -05:00
}
}
2015-12-06 15:15:33 -05:00
fun ast_simple_passthrough_ptr(): *ast_node {
2015-12-28 03:34:40 -05:00
var to_ret.construct(): simple_passthrough
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj simple_passthrough (Object) {
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
var passthrough_str: string
var in_params: vector<pair<*ast_node,string>>
var out_params: vector<pair<*ast_node,string>>
var linker_str: string
2015-12-05 07:13:32 -05:00
fun construct(): *simple_passthrough {
2015-12-07 13:43:22 -05:00
scope.construct()
passthrough_str.construct()
in_params.construct()
out_params.construct()
linker_str.construct()
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *simple_passthrough) {
2015-12-07 13:43:22 -05:00
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)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
passthrough_str.destruct()
in_params.destruct()
out_params.destruct()
linker_str.destruct()
2015-12-05 07:13:32 -05:00
}
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
2015-12-05 07:13:32 -05:00
}
}
fun ast_function_call_ptr(func: *ast_node, parameters: vector<*ast_node>): *ast_node {
var to_ret.construct(func, parameters): function_call
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
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(&parameters_in)
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *function_call) {
func = old->func
parameters.copy_construct(&old->parameters)
2015-12-05 07:13:32 -05:00
}
fun destruct() {
parameters.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: ref function_call) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref function_call): bool {
return func == func && parameters == other.parameters
2015-12-05 07:13:32 -05:00
}
}
fun ast_compiler_intrinsic_ptr(intrinsic: string, parameters: vector<string>, type_parameters: vector<*type>, return_type: *type): *ast_node {
var to_ret.construct(intrinsic, parameters, type_parameters, return_type): compiler_intrinsic
var ptr = new<ast_node>()
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<string>
var type_parameters: vector<*type>
var return_type: *type
fun construct(intrinsic_in: string, parameters_in: vector<string>, type_parameters_in: vector<*type>, return_type_in: *type): *compiler_intrinsic {
intrinsic.copy_construct(&intrinsic_in)
parameters.copy_construct(&parameters_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<ast_node>()
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
}
}
2016-01-09 22:37:43 -05:00
fun ast_value_ptr(string_value: string, value_type: *type): *ast_node {
var to_ret.construct(string_value, value_type): value
2015-12-05 07:13:32 -05:00
var ptr = new<ast_node>()
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
}
2015-12-05 07:13:32 -05:00
obj value (Object) {
var string_value: string
2016-01-09 22:37:43 -05:00
var value_type: *type
2015-12-07 13:43:22 -05:00
var scope: map<string, vector<*ast_node>>
2016-01-09 22:37:43 -05:00
fun construct(string_value_in: string, value_type_in: *type): *value {
2015-12-07 13:43:22 -05:00
scope.construct()
string_value.copy_construct(&string_value_in)
2016-01-09 22:37:43 -05:00
value_type = value_type_in
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *value) {
2015-12-07 13:43:22 -05:00
scope.copy_construct(&old->scope)
string_value.copy_construct(&old->string_value)
2016-01-09 22:37:43 -05:00
value_type = old->value_type
2015-12-05 07:13:32 -05:00
}
fun destruct() {
2015-12-07 13:43:22 -05:00
scope.destruct()
string_value.destruct()
2015-12-05 07:13:32 -05:00
}
fun operator=(other: ref value) {
destruct()
copy_construct(&other)
}
fun operator==(other: ref value): bool {
2016-01-09 22:37:43 -05:00
return string_value == other.string_value && value_type == other.value_type
2015-12-05 07:13:32 -05:00
}
}
fun get_ast_children(node: *ast_node): vector<*ast_node> {
2015-12-06 15:15:33 -05:00
match (*node) {
ast_node::translation_unit(backing) return backing.children + backing.lambdas
2015-12-28 03:34:40 -05:00
ast_node::import(backing) return vector<*ast_node>()
2015-12-06 15:15:33 -05:00
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
2015-12-28 03:34:40 -05:00
ast_node::code_block(backing) return backing.children
ast_node::statement(backing) return vector<*ast_node>(backing.child)
2016-01-19 02:06:30 -05:00
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)
2016-01-19 11:47:09 -05:00
ast_node::for_loop(backing) return vector(backing.init, backing.condition, backing.update, backing.body)
2016-01-09 22:37:43 -05:00
ast_node::return_statement(backing) return vector(backing.return_value)
2016-01-24 17:31:41 -05:00
ast_node::branching_statement(backing) return vector<*ast_node>()
ast_node::defer_statement(backing) return vector(backing.statement)
2016-01-16 22:14:59 -05:00
ast_node::assignment_statement(backing) return vector(backing.to, backing.from)
2016-01-28 20:51:40 -05:00
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)
2015-12-06 15:15:33 -05:00
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)
2015-12-06 15:15:33 -05:00
ast_node::value(backing) return vector<*ast_node>()
}
2015-12-05 07:13:32 -05:00
}
fun get_ast_name(node: *ast_node): string {
2015-12-06 15:15:33 -05:00
match (*node) {
2015-12-06 18:44:04 -05:00
ast_node::translation_unit(backing) return string("translation_unit: ") + backing.name
2015-12-28 03:34:40 -05:00
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()
2015-12-06 18:44:04 -05:00
ast_node::type_def(backing) return string("type_def: ") + backing.name
ast_node::adt_def(backing) return string("adt_def: ") + backing.name
2016-04-29 01:14:26 -04:00
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
2015-12-06 15:15:33 -05:00
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")
2016-01-24 17:31:41 -05:00
ast_node::branching_statement(backing) return string("branching_statement")
2015-12-06 15:15:33 -05:00
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()
2016-01-09 22:37:43 -05:00
ast_node::value(backing) return string("value: ") + backing.string_value + ": " + backing.value_type->to_string()
2015-12-06 15:15:33 -05:00
}
return string("impossible adt type")
2015-12-05 07:13:32 -05:00
}
2015-12-07 13:43:22 -05:00
fun get_ast_scope(node: *ast_node): *map<string,vector<*ast_node>> {
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
2015-12-07 13:43:22 -05:00
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<map<string,vector<*ast_node>>>()
2015-12-07 13:43:22 -05:00
}
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
}
return null<type>()
}
2015-12-05 07:13:32 -05:00
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>()
2015-12-05 07:13:32 -05:00
var helper: fun(*ast_node):void = fun(node: *ast_node) {
done_set.add(node)
2015-12-05 07:13:32 -05:00
get_ast_children(node).for_each(fun(child: *ast_node) {
if (!child || done_set.contains(child))
2015-12-05 07:13:32 -05:00
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 + "}"
}