Now using adt_lower, which also makes the backing deconstruct a reference, which makes sense

This commit is contained in:
Nathan Braswell
2016-06-20 01:52:28 -07:00
parent 4a33a94b15
commit 26e7ee249a
10 changed files with 292 additions and 210 deletions

View File

@@ -9,7 +9,7 @@ import serialize:*
import interpreter:* import interpreter:*
import os:* import os:*
import ast_transformation:* import ast_transformation:*
/*import adt_lower:**/ import adt_lower:*
import defer_lower:* import defer_lower:*
import c_line_control:* import c_line_control:*
import c_generator:* import c_generator:*
@@ -100,8 +100,8 @@ fun main(argc: int, argv: **char):int {
var importer.construct(parsers, ast_pass, vector(string(), base_dir + "/stdlib/")): importer var importer.construct(parsers, ast_pass, vector(string(), base_dir + "/stdlib/")): importer
importer.import(kraken_file_name) importer.import(kraken_file_name)
// Passes // Passes
/*printlnerr("Lowering ADTs")*/ printlnerr("Lowering ADTs")
/*adt_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/ adt_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
printlnerr("Lowering Defer") printlnerr("Lowering Defer")
defer_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) defer_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
if (interpret_instead) { if (interpret_instead) {

View File

@@ -12,22 +12,199 @@ import ast_transformation:*
import pass_common:* import pass_common:*
fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) { fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
var type_def_option_map = map<*ast_node, vector<*ast_node>>()
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) { name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) { var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
match(*node) { match(*node) {
ast_node::adt_def(backing) { ast_node::adt_def(backing) {
println(backing.name + ": entered!") /*println(backing.name + ": transforming!")*/
type_def_option_map[node] = vector<*ast_node>()
var replacement = ast_type_def_ptr(backing.name, false);
// we're going to be replacing adt_def in the same ptr, so this works
replacement->type_def.self_type = node->adt_def.self_type
var replacement_this = make_this_noncached(replacement)
var option_union = ast_type_def_ptr(backing.name + "_union", true);
node->adt_def.options.for_each(fun(opt: *ast_node) {
// want to keep them around
/*if (opt->identifier.type->is_empty_adt_option())*/
/*opt->identifier.type = type_ptr(base_type::character())*/
if (!opt->identifier.type->is_empty_adt_option())
option_union->type_def.variables.add(ast_declaration_statement_ptr(opt, null<ast_node>(), false))
type_def_option_map[node].add(opt)
})
var option_union_type = type_ptr(option_union)
option_union->type_def.self_type = option_union_type
var option_union_ident = ast_identifier_ptr(string("data"), option_union_type, replacement)
replacement->type_def.variables.add(ast_declaration_statement_ptr(option_union_ident, null<ast_node>(), false))
add_to_scope("data", option_union_ident, replacement)
var flag = ast_identifier_ptr(string("flag"), type_ptr(base_type::integer()), replacement)
replacement->type_def.variables.add(ast_declaration_statement_ptr(flag, null<ast_node>(), false))
add_to_scope("flag", flag, replacement)
add_before_in(option_union, node, parent_chain)
var enclosing_scope = node->adt_def.scope[string("~enclosing_scope")][0]
var idx = 0
node->adt_def.option_funcs.for_each(fun(func: *ast_node) {
var adt_type = replacement->type_def.self_type
var block = ast_code_block_ptr()
func->function.body_statement = ast_statement_ptr(block)
var to_ret = ast_identifier_ptr(string("to_ret"), adt_type, block)
block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(to_ret, null<ast_node>(), false)))
var value = ast_value_ptr(to_string(idx), type_ptr(base_type::integer()))
block->code_block.children.add(ast_statement_ptr(ast_assignment_statement_ptr(make_operator_call(".", vector(to_ret, flag)), value)))
/*var opt = option_union->type_def.variables[idx]->declaration_statement.identifier*/
var opt = type_def_option_map[node][idx]
var lvalue = make_operator_call(".", vector(make_operator_call(".", vector(to_ret, option_union_ident)), opt))
if (func->function.parameters.size) {
// do copy_construct if it should
block->code_block.children.add(ast_statement_ptr(assign_or_copy_construct_statement(lvalue, func->function.parameters[0])))
}
/*} else {*/
/*// init our placeholders with 0 for equality, etc*/
/*block->code_block.children.add(ast_statement_ptr(ast_assignment_statement_ptr(lvalue, ast_value_ptr(string("0"), type_ptr(base_type::character())))))*/
/*}*/
block->code_block.children.add(ast_statement_ptr(ast_return_statement_ptr(to_ret)))
add_before_in(func, node, parent_chain)
add_to_scope(func->function.name, func, enclosing_scope)
add_to_scope("~enclosing_scope", enclosing_scope, func)
idx++
})
node->adt_def.regular_funcs.for_each(fun(func: *ast_node) {
var block = ast_code_block_ptr()
func->function.body_statement = ast_statement_ptr(block)
if (func->function.name == "operator==") {
var other = func->function.parameters[0]
var if_stmt = ast_if_statement_ptr(make_operator_call("!=", vector(make_operator_call("->", vector(replacement_this, flag)), make_operator_call(".", vector(other, flag)))))
if_stmt->if_statement.then_part = ast_statement_ptr(ast_return_statement_ptr(ast_value_ptr(string("false"), type_ptr(base_type::boolean()))))
block->code_block.children.add(if_stmt)
/*for (var i = 0; i < option_union->type_def.variables.size; i++;) {*/
for (var i = 0; i < type_def_option_map[node].size; i++;) {
if (get_ast_type(type_def_option_map[node][i])->is_empty_adt_option())
continue
var if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(replacement_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
/*var option = option_union->type_def.variables[i]->declaration_statement.identifier*/
var option = type_def_option_map[node][i]
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
var their_option = make_operator_call(".", vector(make_operator_call(".", vector(other, option_union_ident)), option))
if_stmt_inner->if_statement.then_part = ast_statement_ptr(ast_return_statement_ptr(possible_object_equality(our_option, their_option)))
block->code_block.children.add(if_stmt_inner)
}
block->code_block.children.add(ast_statement_ptr(ast_return_statement_ptr(ast_value_ptr(string("true"), type_ptr(base_type::boolean())))))
} else if (func->function.name == "operator!=") {
var other = func->function.parameters[0]
block->code_block.children.add(ast_statement_ptr(ast_return_statement_ptr(make_operator_call("!", vector(make_method_call(replacement_this, "operator==", vector(other)))))))
} else if (func->function.name == "construct") {
var value = ast_value_ptr(string("-1"), type_ptr(base_type::integer()))
block->code_block.children.add(ast_statement_ptr(ast_assignment_statement_ptr(make_operator_call("->", vector(replacement_this, flag)), value)))
block->code_block.children.add(ast_statement_ptr(ast_return_statement_ptr(replacement_this)))
} else if (func->function.name == "copy_construct") {
var other = func->function.parameters[0]
block->code_block.children.add(ast_statement_ptr(ast_assignment_statement_ptr(make_operator_call("->", vector(replacement_this, flag)), make_operator_call("->", vector(other, flag)))))
/*for (var i = 0; i < option_union->type_def.variables.size; i++;) {*/
for (var i = 0; i < type_def_option_map[node].size; i++;) {
if (get_ast_type(type_def_option_map[node][i])->is_empty_adt_option())
continue
var if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(replacement_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
/*var option = option_union->type_def.variables[i]->declaration_statement.identifier*/
var option = type_def_option_map[node][i]
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
var their_option = make_operator_call(".", vector(make_operator_call("->", vector(other, option_union_ident)), option))
if_stmt_inner->if_statement.then_part = ast_statement_ptr(assign_or_copy_construct_statement(our_option, their_option))
block->code_block.children.add(if_stmt_inner)
}
} else if (func->function.name == "operator=") {
var other = func->function.parameters[0]
block->code_block.children.add(ast_statement_ptr(make_method_call(replacement_this, "destruct", vector<*ast_node>())))
block->code_block.children.add(ast_statement_ptr(make_method_call(replacement_this, "copy_construct", vector(make_operator_call("&", vector(other))))))
} else if (func->function.name == "destruct") {
for (var i = 0; i < type_def_option_map[node].size; i++;) {
var option = type_def_option_map[node][i]
var option_type = get_ast_type(option)
if (option_type->is_empty_adt_option())
continue
if (option_type->indirection == 0 && option_type->is_object() && has_method(option_type->type_def, "destruct", vector<*type>())) {
var if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(replacement_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
if_stmt_inner->if_statement.then_part = ast_statement_ptr(make_method_call(our_option, "destruct", vector<*ast_node>()))
block->code_block.children.add(if_stmt_inner)
}
}
} else error("impossible adt method")
replacement->type_def.methods.add(func)
add_to_scope(func->function.name, func, replacement)
add_to_scope("~enclosing_scope", replacement, func)
})
add_to_scope("~enclosing_scope", enclosing_scope, option_union)
add_to_scope("~enclosing_scope", enclosing_scope, replacement)
*node = *replacement
} }
} }
} }
var helper_after = fun(node: *ast_node, parent_chain: *stack<*ast_node>) { run_on_tree(helper_before, empty_pass_half, syntax_ast_pair.second)
})
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
var second_helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
match(*node) { match(*node) {
ast_node::adt_def(backing) { ast_node::match_statement(backing) {
println(backing.name + ": exited!") /*println("Match statement!")*/
var block = ast_code_block_ptr()
var value = backing.value
/*var holder = ast_identifier_ptr(string("holder"), get_ast_type(value), block)*/
var holder = ast_identifier_ptr(string("holder"), get_ast_type(value)->clone_with_increased_indirection(), block)
block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(holder, null<ast_node>(), false)))
// dirty hack
var if_hack = ast_if_statement_ptr(ast_assignment_statement_ptr(holder, make_operator_call("&", vector(value))))
block->code_block.children.add(if_hack)
var if_block = ast_code_block_ptr()
if_hack->if_statement.then_part = if_block
/*block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(holder, make_operator_call("&", vector(value)), false)))*/
backing.cases.for_each(fun(case_stmt: *ast_node) {
var option = case_stmt->case_statement.option
/*println(string("case: ") + get_ast_name(option))*/
var flag = get_from_scope(get_ast_type(value)->type_def, "flag")
var data = get_from_scope(get_ast_type(value)->type_def, "data")
var option_num = -7
if (!type_def_option_map.contains_key(get_ast_type(value)->type_def))
error("trying to match on non-adt")
for (var i = 0; i < type_def_option_map[get_ast_type(value)->type_def].size; i++;)
if (type_def_option_map[get_ast_type(value)->type_def][i] == option)
option_num = i;
/*var condition = make_operator_call("==", vector(make_operator_call(".", vector(holder, flag)), ast_value_ptr(to_string(option_num), type_ptr(base_type::integer()))))*/
var condition = make_operator_call("==", vector(make_operator_call("->", vector(holder, flag)), ast_value_ptr(to_string(option_num), type_ptr(base_type::integer()))))
var if_stmt = ast_if_statement_ptr(condition)
var inner_block = ast_code_block_ptr()
var unpack_ident = case_stmt->case_statement.unpack_ident
if (unpack_ident) {
/*var get_option = make_operator_call(".", vector(make_operator_call(".", vector(holder, data)), option))*/
var get_option = make_operator_call(".", vector(make_operator_call("->", vector(holder, data)), option))
get_option = make_operator_call("&", vector(get_option))
unpack_ident->identifier.type = unpack_ident->identifier.type->clone_with_ref()
inner_block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(unpack_ident, get_option, false)))
}
inner_block->code_block.children.add(case_stmt->case_statement.statement)
if_stmt->if_statement.then_part = inner_block
if_block->code_block.children.add(if_stmt)
})
*node = *block
}
ast_node::function_call(backing) {
if (is_function(backing.func) && (backing.func->function.name == "." || backing.func->function.name == "->")) {
var left_type = get_ast_type(backing.parameters[0])
if (left_type->is_object() && is_identifier(backing.parameters[1])) {
for (var i = 0; i < left_type->type_def->type_def.variables.size; i++;)
if (left_type->type_def->type_def.variables[i]->declaration_statement.identifier == backing.parameters[1])
return;
/*println(backing.parameters[1]->identifier.name + " getting, adt . or -> call!")*/
var object = node->function_call.parameters[0]
node->function_call.parameters[0] = make_operator_call(backing.func->function.name, vector(object, get_from_scope(left_type->type_def, "data")))
node->function_call.func = get_builtin_function(".", vector(get_ast_type(get_from_scope(left_type->type_def, "data")), get_ast_type(backing.parameters[1])))
}
}
} }
} }
} }
run_on_tree(helper_before, helper_after, syntax_ast_pair.second) run_on_tree(second_helper, empty_pass_half, syntax_ast_pair.second)
}) })
} }

View File

@@ -983,7 +983,7 @@ obj ast_transformation (Object) {
fun find_and_make_any_operator_overload_call(func_name: string, parameters: vector<*ast_node>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node { fun find_and_make_any_operator_overload_call(func_name: string, parameters: vector<*ast_node>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
var parameter_types = parameters.map(fun(param: *ast_node): *type return get_ast_type(param);) var parameter_types = parameters.map(fun(param: *ast_node): *type return get_ast_type(param);)
var possible_overload = null<ast_node>() var possible_overload = null<ast_node>()
if ((parameter_types[0]->is_adt() || parameter_types[0]->is_object()) && parameter_types[0]->indirection == 0) { if (parameter_types[0]->is_object() && parameter_types[0]->indirection == 0) {
possible_overload = function_lookup(string("operator")+func_name, parameter_types.first()->type_def, parameter_types.slice(1,-1)) possible_overload = function_lookup(string("operator")+func_name, parameter_types.first()->type_def, parameter_types.slice(1,-1))
if (!possible_overload) { if (!possible_overload) {
var inherited_replacements = map<string, *type>() var inherited_replacements = map<string, *type>()
@@ -1112,6 +1112,10 @@ obj ast_transformation (Object) {
return fitting_functions.max(fun(a: pair<*ast_node, int>, b: pair<*ast_node, int>): bool return a.second < b.second;).first return fitting_functions.max(fun(a: pair<*ast_node, int>, b: pair<*ast_node, int>): bool return a.second < b.second;).first
} }
} }
fun get_from_scope(node: *ast_node, member: *char): *ast_node
return get_from_scope(node, string(member))
fun get_from_scope(node: *ast_node, member: string): *ast_node
return get_ast_scope(node)->get(member).first()
fun has_method(object: *ast_node, name: *char, parameter_types: vector<*type>): bool return has_method(object, string(name), parameter_types); fun has_method(object: *ast_node, name: *char, parameter_types: vector<*type>): bool return has_method(object, string(name), parameter_types);
fun has_method(object: *ast_node, name: string, parameter_types: vector<*type>): bool { fun has_method(object: *ast_node, name: string, parameter_types: vector<*type>): bool {
/*println("HAS METHOD:")*/ /*println("HAS METHOD:")*/
@@ -1131,13 +1135,18 @@ fun make_method_call(object_ident: *ast_node, name: string, parameters: vector<*
} }
fun make_method_call(object_ident: *ast_node, method: *ast_node, parameters: vector<*ast_node>): *ast_node { fun make_method_call(object_ident: *ast_node, method: *ast_node, parameters: vector<*ast_node>): *ast_node {
/*println("MAKE METHOD CALL IN:")*/ /*println("MAKE METHOD CALL IN:")*/
var method_access = ast_function_call_ptr(get_builtin_function(string("."), vector(get_ast_type(object_ident), get_ast_type(method))), vector(object_ident, method)) var access_op = "."
if (get_ast_type(object_ident)->indirection)
access_op = "->"
var method_access = ast_function_call_ptr(get_builtin_function(string(access_op), vector(get_ast_type(object_ident), get_ast_type(method))), vector(object_ident, method))
return ast_function_call_ptr(method_access, parameters) return ast_function_call_ptr(method_access, parameters)
} }
fun make_operator_call(func: *char, params: vector<*ast_node>): *ast_node return make_operator_call(string(func), params); fun make_operator_call(func: *char, params: vector<*ast_node>): *ast_node return make_operator_call(string(func), params);
fun make_operator_call(func: string, params: vector<*ast_node>): *ast_node { fun make_operator_call(func: string, params: vector<*ast_node>): *ast_node {
return ast_function_call_ptr(get_builtin_function(func, params.map(fun(p:*ast_node): *type return get_ast_type(p);)), params) return ast_function_call_ptr(get_builtin_function(func, params.map(fun(p:*ast_node): *type return get_ast_type(p);)), params)
} }
fun get_builtin_function(name: *char, param_types: vector<*type>): *ast_node
return get_builtin_function(string(name), param_types, null<tree<symbol>>())
fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node
return get_builtin_function(name, param_types, null<tree<symbol>>()) return get_builtin_function(name, param_types, null<tree<symbol>>())
fun get_builtin_function(name: string, param_types: vector<*type>, syntax: *tree<symbol>): *ast_node { fun get_builtin_function(name: string, param_types: vector<*type>, syntax: *tree<symbol>): *ast_node {

View File

@@ -223,7 +223,7 @@ obj c_generator (Object) {
// add parameters to destructor thingy (for returns)? Or should that be a different pass? // add parameters to destructor thingy (for returns)? Or should that be a different pass?
var parameter_type = parameter->identifier.type var parameter_type = parameter->identifier.type
if (!parameter_type->is_ref && parameter_type->indirection == 0 && (parameter_type->is_adt() || (parameter_type->is_object() && has_method(parameter_type->type_def, "destruct", vector<*type>())))) if (!parameter_type->is_ref && parameter_type->indirection == 0 && (parameter_type->is_object() && has_method(parameter_type->type_def, "destruct", vector<*type>())))
defer_stack->top().second.push(ast_statement_ptr(make_method_call(parameter, "destruct", vector<*ast_node>()))) defer_stack->top().second.push(ast_statement_ptr(make_method_call(parameter, "destruct", vector<*ast_node>())))
}) })
if (backing.is_variadic) { if (backing.is_variadic) {
@@ -261,119 +261,7 @@ obj c_generator (Object) {
function_definitions += generate_from_defer_stack(&defer_stack, -1, enclosing_object, child).one_string() function_definitions += generate_from_defer_stack(&defer_stack, -1, enclosing_object, child).one_string()
function_definitions += "}\n" function_definitions += "}\n"
} else if (!backing.is_extern) { } else if (!backing.is_extern) {
// adt constructor if no body and not extern error("Empty function statement and not extern - no ADTs anymore!")
// wow. no pass in for no this
enclosing_object = get_ast_scope(child)->get(string("~enclosing_scope"))[0]
// if this is an option constructor
if (enclosing_object->adt_def.options.any_true(fun(opt: *ast_node): bool return opt->identifier.name == backing.name;)) {
var option_ident = enclosing_object->adt_def.options.find_first_satisfying(fun(opt: *ast_node): bool return opt->identifier.name == backing.name;)
var option_type = option_ident->identifier.type
function_definitions += " { \n"
var to_ret_ident = ast_identifier_ptr("to_ret", enclosing_object->type_def.self_type, enclosing_object)
function_definitions += type_to_c(enclosing_object->adt_def.self_type) + " "+ get_name(to_ret_ident) + ";\n"
function_definitions += get_name(to_ret_ident) + ".flag = " + string("enum_opt_") + get_name(option_ident) + ";\n"
if (option_type->is_empty_adt_option())
function_definitions += "/*no inner data*/\n"
else {
var param = backing.parameters[0]
if (option_type->indirection == 0 && (option_type->is_adt() || (option_type->is_object() && has_method(option_type->type_def, "copy_construct", vector(option_type->clone_with_increased_indirection()))))) {
function_definitions += generate(ast_statement_ptr(make_method_call(make_operator_call(".", vector(to_ret_ident, option_ident)), "copy_construct", vector(make_operator_call("&", vector(param))))), null<ast_node>(), null<ast_node>(), &defer_stack, false).one_string()
function_definitions += generate_from_defer_stack(&defer_stack, -1, enclosing_object, child).one_string()
} else {
function_definitions += get_name(to_ret_ident) +".data." + get_name(option_ident) + " = " + get_name(param) + ";\n"
}
}
function_definitions += "return " + get_name(to_ret_ident) + ";\n"
function_definitions += "}\n"
} else {
// this is one of the other functions instead
var adt_this = ast_identifier_ptr("this", enclosing_object->type_def.self_type->clone_with_indirection(1), enclosing_object)
function_definitions += "{\n"
if (backing.name == "operator==") {
var param = backing.parameters[0]
function_definitions += "/*operator==*/"
function_definitions += string("if (this->flag != ") + generate_identifier(param, null<ast_node>(), null<ast_node>()).one_string() + ".flag) return false;\n"
enclosing_object->adt_def.options.for_each(fun(option: *ast_node) {
var option_type = option->identifier.type
function_definitions += string("if (this->flag == ") + string("enum_opt_") + generate_identifier(option, null<ast_node>(), null<ast_node>()).one_string() + ") {\n"
if (option_type->is_empty_adt_option()) {
function_definitions += "return true;"
} else {
if (option_type->indirection == 0 && (option_type->is_adt() || (option_type->is_object() && has_method(option_type->type_def, "operator==", vector(option_type))))) {
defer_stack.push(make_pair(false, stack<*ast_node>()))
var equals_res = generate(ast_statement_ptr(make_method_call(make_operator_call("->", vector(adt_this, option)), "operator==", vector(make_operator_call(".", vector(param, option))))), null<ast_node>(), null<ast_node>(), &defer_stack, false)
equals_res.value = string("bool result = ") + equals_res.value + ";\n"
equals_res.post += generate_from_defer_stack(&defer_stack, -1, enclosing_object, child).one_string()
defer_stack.pop()
function_definitions += equals_res.one_string() + "return result;\n"
} else if (option_type->is_object()) {
// if we are an object but don't define an operator== function (or it is templated)
// always return false.
function_definitions += "return false;\n"
} else {
var option_name = generate_identifier(option, null<ast_node>(), null<ast_node>()).one_string()
var param_name = generate_identifier(param, null<ast_node>(), null<ast_node>()).one_string()
function_definitions += string("return this->data.") + option_name + " == " + param_name + ".data." + option_name + ";\n"
}
}
function_definitions += "}\n"
})
} else if (backing.name == "operator!=") {
var param = backing.parameters[0]
function_definitions += "/*operator!=*/"
defer_stack.push(make_pair(false, stack<*ast_node>()))
var equals_res = generate(ast_statement_ptr(make_method_call(make_operator_call("*", vector(adt_this)), "operator==", vector(param))), null<ast_node>(), null<ast_node>(), &defer_stack, false)
equals_res.value = string("bool result = !") + equals_res.value + ";\n"
equals_res.post += generate_from_defer_stack(&defer_stack, -1, enclosing_object, child).one_string()
defer_stack.pop()
function_definitions += equals_res.one_string() + "return result;\n"
} else if (backing.name == "construct") {
function_definitions += "/*construct*/"
function_definitions += "this->flag = -1;\n"
function_definitions += "return this;\n"
} else if (backing.name == "copy_construct") {
var param = backing.parameters[0]
function_definitions += "/*copy_construct*/"
function_definitions += string("this->flag = ") + generate_identifier(param, null<ast_node>(), null<ast_node>()).one_string() + "->flag;\n"
enclosing_object->adt_def.options.for_each(fun(option: *ast_node) {
var option_type = option->identifier.type
function_definitions += string("if (this->flag == ") + string("enum_opt_") + generate_identifier(option, null<ast_node>(), null<ast_node>()).one_string() + ") {\n"
if (option_type->is_empty_adt_option()) {
function_definitions += "/*no data to copy*/;"
} else {
if (option_type->indirection == 0 && (option_type->is_adt() || (option_type->is_object() && has_method(option_type->type_def, "copy_construct", vector(option_type->clone_with_increased_indirection()))))) {
// don't really need the defer_stack
function_definitions += generate(ast_statement_ptr(make_method_call(make_operator_call("->", vector(adt_this, option)), "copy_construct", vector(make_operator_call("&", vector(make_operator_call("->", vector(param, option))))))), null<ast_node>(), null<ast_node>(), &defer_stack, false).one_string()
} else {
var option_name = generate_identifier(option, null<ast_node>(), null<ast_node>()).one_string()
var param_name = generate_identifier(param, null<ast_node>(), null<ast_node>()).one_string()
function_definitions += string("this->data.") + option_name + " = " + param_name + "->data." + option_name + ";\n"
}
}
function_definitions += "}\n"
})
} else if (backing.name == "operator=") {
var param = backing.parameters[0]
function_definitions += "/*operator=*/"
defer_stack.push(make_pair(false, stack<*ast_node>()))
function_definitions += generate(ast_statement_ptr(make_method_call(make_operator_call("*", vector(adt_this)), "destruct", vector<*ast_node>())), null<ast_node>(), null<ast_node>(), &defer_stack, false).one_string()
function_definitions += generate(ast_statement_ptr(make_method_call(make_operator_call("*", vector(adt_this)), "copy_construct", vector(make_operator_call("&", vector(param))))), null<ast_node>(), null<ast_node>(), &defer_stack, false).one_string()
function_definitions += generate_from_defer_stack(&defer_stack, -1, enclosing_object, child).one_string()
defer_stack.pop()
} else if (backing.name == "destruct") {
function_definitions += "/*destruct*/"
enclosing_object->adt_def.options.for_each(fun(option: *ast_node) {
var option_type = option->identifier.type
function_definitions += string("if (this->flag == ") + string("enum_opt_") + generate_identifier(option, null<ast_node>(), null<ast_node>()).one_string() + ") {\n"
if (option_type->indirection == 0 && (option_type->is_adt() || (option_type->is_object() && has_method(option_type->type_def, "destruct", vector<*type>())))) {
// don't really need the defer_stack
function_definitions += generate(ast_statement_ptr(make_method_call(make_operator_call("->", vector(adt_this, option)), "destruct", vector<*ast_node>())), null<ast_node>(), null<ast_node>(), &defer_stack, false).one_string()
}
function_definitions += "}\n"
})
}
function_definitions += "}\n"
}
} }
} }
@@ -432,12 +320,7 @@ obj c_generator (Object) {
}) })
} }
ast_node::adt_def(backing) { ast_node::adt_def(backing) {
type_poset.add_vertex(child) error("ADT remaining!")
backing.options.for_each(fun(i: *ast_node) {
var var_type = get_ast_type(i)
if (!var_type->indirection && var_type->type_def)
type_poset.add_relationship(child, var_type->type_def)
})
} }
} }
}) })
@@ -464,25 +347,7 @@ obj c_generator (Object) {
generate_function_definition(method, vert, false); generate_function_definition(method, vert, false);
}) })
} else { } else {
// adt error("no adt, but how did we get this far?")
var add_to_structs = string()
var add_to_enum = string()
vert->adt_def.options.for_each(fun(option: *ast_node) {
add_to_enum += string("enum_opt_") + get_name(option) + ","
if (!option->identifier.type->is_empty_adt_option())
add_to_structs += generate_declaration_statement(ast_declaration_statement_ptr(option, null<ast_node>(), false), null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n"
})
structs += string("enum { ") + add_to_enum + " } flag;\n"
structs += string("union { ") + add_to_structs + " } data;\n"
// now do methods and generation functions
vert->adt_def.option_funcs.for_each(fun(option_func: *ast_node) {
// no vert so no this
generate_function_definition(option_func, null<ast_node>(), false);
})
vert->adt_def.regular_funcs.for_each(fun(regular_func: *ast_node) {
// want the this this time
generate_function_definition(regular_func, vert, false);
})
} }
structs += "};\n" structs += "};\n"
}) })
@@ -545,7 +410,7 @@ obj c_generator (Object) {
pre_stuff = string("extern ") + pre_stuff pre_stuff = string("extern ") + pre_stuff
var to_ret = code_triple(pre_stuff, string(), string()) var to_ret = code_triple(pre_stuff, string(), string())
if (node->declaration_statement.expression) { if (node->declaration_statement.expression) {
if (ident_type->indirection == 0 && (ident_type->is_adt() || (ident_type->is_object() && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(node->declaration_statement.expression)->clone_with_increased_indirection()))))) { if (ident_type->indirection == 0 && (ident_type->is_object() && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(node->declaration_statement.expression)->clone_with_increased_indirection())))) {
to_ret.pre += ";\n" to_ret.pre += ";\n"
to_ret += generate(ast_statement_ptr(make_method_call(identifier, "copy_construct", vector(make_operator_call("&", vector(node->declaration_statement.expression))))), enclosing_object, enclosing_func, defer_stack, false) to_ret += generate(ast_statement_ptr(make_method_call(identifier, "copy_construct", vector(make_operator_call("&", vector(node->declaration_statement.expression))))), enclosing_object, enclosing_func, defer_stack, false)
} else { } else {
@@ -565,7 +430,8 @@ obj c_generator (Object) {
to_ret.pre += ";\n" to_ret.pre += ";\n"
to_ret += code_triple() + generate(node->declaration_statement.init_method_call, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) to_ret += code_triple() + generate(node->declaration_statement.init_method_call, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false)
} }
if (add_to_defer && ident_type->indirection == 0 && (ident_type->is_adt() || (ident_type->is_object() && has_method(ident_type->type_def, "destruct", vector<*type>())))) // reference can happen because some passes generate them (adt_lower right now)
if (add_to_defer && !ident_type->is_ref && ident_type->indirection == 0 && (ident_type->is_object() && has_method(ident_type->type_def, "destruct", vector<*type>())))
defer_stack->top().second.push(ast_statement_ptr(make_method_call(identifier, "destruct", vector<*ast_node>()))) defer_stack->top().second.push(ast_statement_ptr(make_method_call(identifier, "destruct", vector<*ast_node>())))
return to_ret return to_ret
} }
@@ -593,7 +459,8 @@ obj c_generator (Object) {
// stick another stack on // stick another stack on
defer_stack->push(make_pair(true, stack<*ast_node>())) defer_stack->push(make_pair(true, stack<*ast_node>()))
// gotta take off last semicolon // gotta take off last semicolon
var init = generate(node->for_loop.init, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) /*var init = generate(node->for_loop.init, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false)*/
var init = generate(node->for_loop.init, enclosing_object, enclosing_func, defer_stack, false)
var cond = generate(node->for_loop.condition, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) var cond = generate(node->for_loop.condition, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false)
var update = generate(node->for_loop.update, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) var update = generate(node->for_loop.update, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false)
var do_update_name = string("do_update") + get_id() var do_update_name = string("do_update") + get_id()
@@ -645,7 +512,7 @@ obj c_generator (Object) {
if ((function_return_type->is_object() || return_value_type->is_object()) && !function_return_type->equality(return_value_type, false)) if ((function_return_type->is_object() || return_value_type->is_object()) && !function_return_type->equality(return_value_type, false))
// note the clone with decreased indirection because of the clone with increased indirection above // note the clone with decreased indirection because of the clone with increased indirection above
error(ast_to_syntax[node], string("return type does not match: ") + function_return_type->to_string() + ", " + return_value_type->to_string()); error(ast_to_syntax[node], string("return type does not match: ") + function_return_type->to_string() + ", " + return_value_type->to_string());
if (!function_return_type->is_ref && return_value_type->indirection == 0 && (return_value_type->is_adt() || (return_value_type->is_object() && has_method(return_value_type->type_def, "copy_construct", vector(return_value_type->clone_with_indirection(1)))))) { if (!function_return_type->is_ref && return_value_type->indirection == 0 && (return_value_type->is_object() && has_method(return_value_type->type_def, "copy_construct", vector(return_value_type->clone_with_indirection(1))))) {
to_ret.pre += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(return_value))))), enclosing_object, enclosing_func, defer_stack).one_string() to_ret.pre += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(return_value))))), enclosing_object, enclosing_func, defer_stack).one_string()
} else { } else {
var refamp = string() var refamp = string()
@@ -850,11 +717,7 @@ obj c_generator (Object) {
// don't propegate enclosing function down right of access // don't propegate enclosing function down right of access
// XXX what about enclosing object? should it be the thing on the left? // XXX what about enclosing object? should it be the thing on the left?
if (func_name == "." || func_name == "->") { if (func_name == "." || func_name == "->") {
// special case right hand side is an adt to access inside of adt return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) + func_name + generate(parameters[1], null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false) + string(")")
var in_between = string()
if (get_ast_type(parameters[0])->is_adt())
in_between = "data."
return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) + func_name + in_between + generate(parameters[1], null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false) + string(")")
} }
if (func_name == "[]") if (func_name == "[]")
return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) + "[" + generate(parameters[1], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) + string("])") return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) + "[" + generate(parameters[1], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false) + string("])")
@@ -886,7 +749,7 @@ obj c_generator (Object) {
call_string += "&" call_string += "&"
var param_type = get_ast_type(param) var param_type = get_ast_type(param)
if (!in_function_param_type->is_ref && param_type->indirection == 0 && (param_type->is_adt() || (param_type->is_object() && has_method(param_type->type_def, "copy_construct", vector(param_type->clone_with_indirection(1)))))) { if (!in_function_param_type->is_ref && param_type->indirection == 0 && (param_type->is_object() && has_method(param_type->type_def, "copy_construct", vector(param_type->clone_with_indirection(1))))) {
var temp_ident = ast_identifier_ptr(string("temporary_param")+get_id(), param_type->clone_without_ref(), null<ast_node>()) var temp_ident = ast_identifier_ptr(string("temporary_param")+get_id(), param_type->clone_without_ref(), null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false) var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
// have to pass false to the declaration generator, so can't do it through generate_statement // have to pass false to the declaration generator, so can't do it through generate_statement
@@ -899,7 +762,7 @@ obj c_generator (Object) {
} }
var pre_call = string() var pre_call = string()
// temporary returns if we're asked for them or we need them for destruct // temporary returns if we're asked for them or we need them for destruct
var needs_temp_for_destruct = func_return_type->indirection == 0 && (func_return_type->is_adt() || (func_return_type->is_object() && has_method(func_return_type->type_def, "destruct", vector<*type>()))) var needs_temp_for_destruct = func_return_type->indirection == 0 && (func_return_type->is_object() && has_method(func_return_type->type_def, "destruct", vector<*type>()))
if (!func_return_type->is_ref && (needs_temp_for_destruct || (!func_return_type->is_void() && need_variable)) ) { if (!func_return_type->is_ref && (needs_temp_for_destruct || (!func_return_type->is_void() && need_variable)) ) {
// kind of ugly combo here of // kind of ugly combo here of
var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), func_return_type, null<ast_node>()) var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), func_return_type, null<ast_node>())
@@ -971,7 +834,7 @@ obj c_generator (Object) {
return code_triple("sizeof(") + type_to_c(node->compiler_intrinsic.type_parameters[0]) + ")" return code_triple("sizeof(") + type_to_c(node->compiler_intrinsic.type_parameters[0]) + ")"
} else if (node->compiler_intrinsic.intrinsic == "link") { } else if (node->compiler_intrinsic.intrinsic == "link") {
node->compiler_intrinsic.parameters.for_each(fun(str: string) { node->compiler_intrinsic.parameters.for_each(fun(str: string) {
linker_string += string("-l") + str + " " linker_string += string("-l") + str + " "
}) })
return code_triple() return code_triple()
} }
@@ -1028,7 +891,6 @@ obj c_generator (Object) {
base_type::floating() return indirection + string("float") base_type::floating() return indirection + string("float")
base_type::double_precision() return indirection + string("double") base_type::double_precision() return indirection + string("double")
base_type::object() return cify_name(type->type_def->type_def.name) base_type::object() return cify_name(type->type_def->type_def.name)
base_type::adt() return type->type_def->adt_def.name
base_type::function() { base_type::function() {
var temp = indirection + string("function_") var temp = indirection + string("function_")
type->parameter_types.for_each(fun(parameter_type: *type) temp += type_decoration(parameter_type) + "_";) type->parameter_types.for_each(fun(parameter_type: *type) temp += type_decoration(parameter_type) + "_";)
@@ -1058,7 +920,6 @@ obj c_generator (Object) {
base_type::floating() return string("float") + indirection base_type::floating() return string("float") + indirection
base_type::double_precision() return string("double") + indirection base_type::double_precision() return string("double") + indirection
base_type::object() return get_name(type->type_def) + indirection base_type::object() return get_name(type->type_def) + indirection
base_type::adt() return get_name(type->type_def) + indirection
base_type::function() { base_type::function() {
// maybe disregard indirection in the future? // maybe disregard indirection in the future?
type = type->clone_with_indirection(0,false) type = type->clone_with_indirection(0,false)
@@ -1094,7 +955,7 @@ obj c_generator (Object) {
upper->template.instantiated_map.reverse_get(node).for_each(fun(t: ref type) result += string("_") + type_decoration(&t);) upper->template.instantiated_map.reverse_get(node).for_each(fun(t: ref type) result += string("_") + type_decoration(&t);)
} }
ast_node::adt_def(backing) { ast_node::adt_def(backing) {
result = backing.name error("shouldn't have adt")
} }
ast_node::function(backing) { ast_node::function(backing) {
// be careful, operators like . come through this, but so do adt constructor funcs // be careful, operators like . come through this, but so do adt constructor funcs

View File

@@ -20,7 +20,6 @@ fun get_line(node: *tree<symbol>, name: string): *ast_node {
fun c_line_control(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) { fun c_line_control(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
var first = true var first = true
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) { name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
var helper_after = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {}
var helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) { var helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
match(*node) { match(*node) {
ast_node::statement(backing) { ast_node::statement(backing) {
@@ -32,7 +31,7 @@ fun c_line_control(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, as
} }
} }
if (first) if (first)
run_on_tree(helper, helper_after, syntax_ast_pair.second) run_on_tree(helper, empty_pass_half, syntax_ast_pair.second)
first = false first = false
}) })
} }

View File

@@ -288,7 +288,6 @@ fun store_into_variable(to: value, from: value) {
// TODO - check to make sure that we don't have to cast pre assign (perhaps alwyas send through the cast?) // TODO - check to make sure that we don't have to cast pre assign (perhaps alwyas send through the cast?)
match (variable.second->base) { match (variable.second->base) {
base_type::object() { assert(is_object_like(from), "mismatching assignemnt types - from is not object"); memmove(variable.first, from.object_like.first, type_size(from.object_like.second)); } base_type::object() { assert(is_object_like(from), "mismatching assignemnt types - from is not object"); memmove(variable.first, from.object_like.first, type_size(from.object_like.second)); }
base_type::adt() error(string("trying to store into an adt: ") + variable.second->to_string())
base_type::function() { assert(is_function(from), "mismatching assignemnt types - from is not function"); *(variable.first) cast *pair<*ast_node, map<*ast_node,value>> = from.function; } base_type::function() { assert(is_function(from), "mismatching assignemnt types - from is not function"); *(variable.first) cast *pair<*ast_node, map<*ast_node,value>> = from.function; }
base_type::boolean() { assert(is_boolean(from), "mismatching assignemnt types - from is not boolean"); *(variable.first) cast *bool = from.boolean; } base_type::boolean() { assert(is_boolean(from), "mismatching assignemnt types - from is not boolean"); *(variable.first) cast *bool = from.boolean; }
base_type::character() { assert(is_character(from), "mismatching assignemnt types - from is not character"); *(variable.first) cast *char = from.character; } base_type::character() { assert(is_character(from), "mismatching assignemnt types - from is not character"); *(variable.first) cast *char = from.character; }
@@ -493,7 +492,7 @@ fun pop_and_free(var_stack: *stack<map<*ast_node, value>>) {
obj interpreter (Object) { obj interpreter (Object) {
var ast_to_syntax: map<*ast_node, *tree<symbol>> var ast_to_syntax: map<*ast_node, *tree<symbol>>
var name_ast_map: map<string, pair<*tree<symbol>,*ast_node>> var name_ast_map: map<string, pair<*tree<symbol>,*ast_node>>
var globals: map<*ast_node, value> var globals: map<*ast_node, value>
var id_counter: int var id_counter: int
fun get_id(): string return to_string(id_counter++); fun get_id(): string return to_string(id_counter++);
@@ -615,7 +614,7 @@ obj interpreter (Object) {
var parameters = vector<value>() var parameters = vector<value>()
var parameter_sources = vector<*ast_node>() var parameter_sources = vector<*ast_node>()
// if we don't have to copy_construct params (is an operator, or has no object params) // if we don't have to copy_construct params (is an operator, or has no object params)
if (func_name == "&" || !func_call_parameters.any_true(fun(p: *ast_node): bool return get_ast_type(p)->is_object_like() && get_ast_type(p)->indirection == 0;)) { if (func_name == "&" || !func_call_parameters.any_true(fun(p: *ast_node): bool return get_ast_type(p)->is_object() && get_ast_type(p)->indirection == 0;)) {
parameters = func_call_parameters.map(fun(p: *ast_node): value return interpret(p, var_stack, enclosing_object, enclosing_func, defer_stack).first;) parameters = func_call_parameters.map(fun(p: *ast_node): value return interpret(p, var_stack, enclosing_object, enclosing_func, defer_stack).first;)
if ( parameters.size == 2 && (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/" if ( parameters.size == 2 && (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/"
|| func_name == "<" || func_name == ">" || func_name == "<=" || func_name == ">=" || func_name == "<" || func_name == ">" || func_name == "<=" || func_name == ">="
@@ -694,7 +693,7 @@ obj interpreter (Object) {
else else
new_var_stack.top()[param_ident] = wrap_into_variable(parameters[i]) new_var_stack.top()[param_ident] = wrap_into_variable(parameters[i])
} else { } else {
new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type)) new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
//HERE //HERE
(new_var_stack.top()[param_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct() (new_var_stack.top()[param_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
store_into_variable(new_var_stack.top()[param_ident], get_real_value(parameters[i])) store_into_variable(new_var_stack.top()[param_ident], get_real_value(parameters[i]))
@@ -716,17 +715,17 @@ obj interpreter (Object) {
new_var_stack.top()[param_ident] = param new_var_stack.top()[param_ident] = param
else else
new_var_stack.top()[param_ident] = wrap_into_variable(param) new_var_stack.top()[param_ident] = wrap_into_variable(param)
} else if (param_type->indirection == 0 && (param_type->is_adt() || (param_type->is_object() && has_method(param_type->type_def, "copy_construct", vector(param_type->clone_with_increased_indirection()))))) { } else if (param_type->indirection == 0 && (param_type->is_object() && has_method(param_type->type_def, "copy_construct", vector(param_type->clone_with_increased_indirection())))) {
var temp_ident = ast_identifier_ptr(string("temporary_param") + get_id(), param_type, null<ast_node>()) var temp_ident = ast_identifier_ptr(string("temporary_param") + get_id(), param_type, null<ast_node>())
var_stack->top()[temp_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type)) var_stack->top()[temp_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
//HERE //HERE
(var_stack->top()[temp_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct() (var_stack->top()[temp_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
interpret(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(parameter_sources[i]))))), var_stack, enclosing_object, enclosing_func, &param_defer_stack) interpret(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(parameter_sources[i]))))), var_stack, enclosing_object, enclosing_func, &param_defer_stack)
new_var_stack.top()[param_ident] = var_stack->top()[temp_ident] new_var_stack.top()[param_ident] = var_stack->top()[temp_ident]
// note that we destruct the temp version because that's the one in the var_stack // note that we destruct the temp version because that's the one in the var_stack
param_defer_stack.push(ast_statement_ptr(make_method_call(temp_ident, "destruct", vector<*ast_node>()))) param_defer_stack.push(ast_statement_ptr(make_method_call(temp_ident, "destruct", vector<*ast_node>())))
} else { } else {
new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type)) new_var_stack.top()[param_ident] = value::variable(make_pair(malloc(type_size(param_type)), param_type))
//HERE //HERE
(new_var_stack.top()[param_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct() (new_var_stack.top()[param_ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
store_into_variable(new_var_stack.top()[param_ident], get_real_value(interpret(parameter_sources[i], var_stack, enclosing_object, enclosing_func, &param_defer_stack).first)) store_into_variable(new_var_stack.top()[param_ident], get_real_value(interpret(parameter_sources[i], var_stack, enclosing_object, enclosing_func, &param_defer_stack).first))
@@ -744,7 +743,7 @@ obj interpreter (Object) {
pop_and_free(var_stack) pop_and_free(var_stack)
} }
var return_type = func->function.type->return_type var return_type = func->function.type->return_type
if (!return_type->is_ref && return_type->indirection == 0 && (return_type->is_adt() || (return_type->is_object() && has_method(return_type->type_def, "destruct", vector<*type>())))) { if (!return_type->is_ref && return_type->indirection == 0 && (return_type->is_object() && has_method(return_type->type_def, "destruct", vector<*type>()))) {
var temp_ident = ast_identifier_ptr(string("temporary_return_to_be_destructed") + get_id(), return_type, null<ast_node>()) var temp_ident = ast_identifier_ptr(string("temporary_return_to_be_destructed") + get_id(), return_type, null<ast_node>())
var_stack->top()[temp_ident] = value::variable(make_pair(to_ret.object_like.first, to_ret.object_like.second)) var_stack->top()[temp_ident] = value::variable(make_pair(to_ret.object_like.first, to_ret.object_like.second))
defer_stack->push(ast_statement_ptr(make_method_call(temp_ident, "destruct", vector<*ast_node>()))) defer_stack->push(ast_statement_ptr(make_method_call(temp_ident, "destruct", vector<*ast_node>())))
@@ -829,7 +828,7 @@ obj interpreter (Object) {
fun interpret_if_statement(if_stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> { fun interpret_if_statement(if_stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
var_stack->push(map<*ast_node,value>()) var_stack->push(map<*ast_node,value>())
var inner_defer_stack = stack<*ast_node>() var inner_defer_stack = stack<*ast_node>()
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor()) var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
if (truthy(interpret(if_stmt->if_statement.condition, var_stack, enclosing_object, enclosing_func, &inner_defer_stack).first)) { if (truthy(interpret(if_stmt->if_statement.condition, var_stack, enclosing_object, enclosing_func, &inner_defer_stack).first)) {
value_from_inside = interpret(if_stmt->if_statement.then_part, var_stack, enclosing_object, enclosing_func, &inner_defer_stack) value_from_inside = interpret(if_stmt->if_statement.then_part, var_stack, enclosing_object, enclosing_func, &inner_defer_stack)
} else if (if_stmt->if_statement.else_part) { } else if (if_stmt->if_statement.else_part) {
@@ -842,7 +841,7 @@ obj interpreter (Object) {
fun interpret_while_loop(while_loop: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> { fun interpret_while_loop(while_loop: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
var_stack->push(map<*ast_node,value>()) var_stack->push(map<*ast_node,value>())
var inner_defer_stack = stack<*ast_node>() var inner_defer_stack = stack<*ast_node>()
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor()) var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
var going = true var going = true
while (going && truthy(interpret(while_loop->while_loop.condition, var_stack, enclosing_object, enclosing_func, &inner_defer_stack).first)) { while (going && truthy(interpret(while_loop->while_loop.condition, var_stack, enclosing_object, enclosing_func, &inner_defer_stack).first)) {
value_from_inside = interpret(while_loop->while_loop.statement, var_stack, enclosing_object, enclosing_func, &inner_defer_stack) value_from_inside = interpret(while_loop->while_loop.statement, var_stack, enclosing_object, enclosing_func, &inner_defer_stack)
@@ -851,7 +850,7 @@ obj interpreter (Object) {
if (value_from_inside.second == control_flow::ret() || value_from_inside.second == control_flow::bre()) if (value_from_inside.second == control_flow::ret() || value_from_inside.second == control_flow::bre())
going = false going = false
if (value_from_inside.second == control_flow::bre() || value_from_inside.second == control_flow::con()) if (value_from_inside.second == control_flow::bre() || value_from_inside.second == control_flow::con())
value_from_inside = make_pair(value::void_nothing(), control_flow::nor()) value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
} }
interpret_from_defer_stack(&inner_defer_stack, var_stack, value::void_nothing(), enclosing_func) interpret_from_defer_stack(&inner_defer_stack, var_stack, value::void_nothing(), enclosing_func)
pop_and_free(var_stack) pop_and_free(var_stack)
@@ -860,7 +859,7 @@ obj interpreter (Object) {
fun interpret_for_loop(for_loop: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> { fun interpret_for_loop(for_loop: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node): pair<value, control_flow> {
var defer_stack = stack<*ast_node>() var defer_stack = stack<*ast_node>()
var_stack->push(map<*ast_node,value>()) var_stack->push(map<*ast_node,value>())
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor()) var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
var going = true var going = true
interpret(for_loop->for_loop.init, var_stack, enclosing_object, enclosing_func, &defer_stack) interpret(for_loop->for_loop.init, var_stack, enclosing_object, enclosing_func, &defer_stack)
while (going && truthy(interpret(for_loop->for_loop.condition, var_stack, enclosing_object, enclosing_func, &defer_stack).first)) { while (going && truthy(interpret(for_loop->for_loop.condition, var_stack, enclosing_object, enclosing_func, &defer_stack).first)) {
@@ -868,7 +867,7 @@ obj interpreter (Object) {
if (value_from_inside.second == control_flow::ret() || value_from_inside.second == control_flow::bre()) if (value_from_inside.second == control_flow::ret() || value_from_inside.second == control_flow::bre())
going = false going = false
if (value_from_inside.second == control_flow::bre() || value_from_inside.second == control_flow::con()) if (value_from_inside.second == control_flow::bre() || value_from_inside.second == control_flow::con())
value_from_inside = make_pair(value::void_nothing(), control_flow::nor()) value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
// only run update if we're not breaking or continuing // only run update if we're not breaking or continuing
if (going) if (going)
@@ -931,11 +930,11 @@ obj interpreter (Object) {
var to_ret.construct(): value var to_ret.construct(): value
if (get_ast_type(enclosing_func)->return_type->is_ref) { if (get_ast_type(enclosing_func)->return_type->is_ref) {
to_ret = interpret(return_expression, var_stack, enclosing_object, enclosing_func, defer_stack).first to_ret = interpret(return_expression, var_stack, enclosing_object, enclosing_func, defer_stack).first
} else if (return_type->indirection == 0 && (return_type->is_adt() || (return_type->is_object() && has_method(return_type->type_def, "copy_construct", vector(return_type->clone_with_increased_indirection()))))) { } else if (return_type->indirection == 0 && (return_type->is_object() && has_method(return_type->type_def, "copy_construct", vector(return_type->clone_with_increased_indirection())))) {
var_stack->push(map<*ast_node,value>()) var_stack->push(map<*ast_node,value>())
var inner_defer_stack = stack<*ast_node>() var inner_defer_stack = stack<*ast_node>()
var temp_ident = ast_identifier_ptr(string("temporary_return"), return_type, null<ast_node>()) var temp_ident = ast_identifier_ptr(string("temporary_return"), return_type, null<ast_node>())
var_stack->top()[temp_ident] = value::variable(make_pair(malloc(type_size(return_type)), return_type)) var_stack->top()[temp_ident] = value::variable(make_pair(malloc(type_size(return_type)), return_type))
interpret(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(return_expression))))), var_stack, enclosing_object, enclosing_func, &inner_defer_stack) interpret(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(return_expression))))), var_stack, enclosing_object, enclosing_func, &inner_defer_stack)
to_ret = var_stack->top()[temp_ident] to_ret = var_stack->top()[temp_ident]
interpret_from_defer_stack(&inner_defer_stack, var_stack, enclosing_object, enclosing_func) interpret_from_defer_stack(&inner_defer_stack, var_stack, enclosing_object, enclosing_func)
@@ -943,7 +942,7 @@ obj interpreter (Object) {
var_stack->pop() var_stack->pop()
/*pop_and_free(var_stack)*/ /*pop_and_free(var_stack)*/
} else { } else {
to_ret = value::variable(make_pair(malloc(type_size(return_type)), return_type)) to_ret = value::variable(make_pair(malloc(type_size(return_type)), return_type))
//HERE //HERE
(to_ret.variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct() (to_ret.variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
var ret_val = interpret(return_expression, var_stack, enclosing_object, enclosing_func, defer_stack).first var ret_val = interpret(return_expression, var_stack, enclosing_object, enclosing_func, defer_stack).first
@@ -954,11 +953,11 @@ obj interpreter (Object) {
fun interpret_declaration_statement(stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> { fun interpret_declaration_statement(stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, defer_stack: *stack<*ast_node>): pair<value, control_flow> {
var ident = stmt->declaration_statement.identifier var ident = stmt->declaration_statement.identifier
var ident_type = ident->identifier.type var ident_type = ident->identifier.type
var_stack->top()[ident] = value::variable(make_pair(malloc(type_size(ident_type)),ident_type)) var_stack->top()[ident] = value::variable(make_pair(malloc(type_size(ident_type)),ident_type))
//HERE //HERE
(var_stack->top()[ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct() (var_stack->top()[ident].variable.first) cast *pair<*ast_node,map<*ast_node,value>> ->construct()
if (stmt->declaration_statement.expression) { if (stmt->declaration_statement.expression) {
if (ident_type->indirection == 0 && (ident_type->is_adt() || (ident_type->is_object() && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(stmt->declaration_statement.expression)->clone_with_increased_indirection()))))) if (ident_type->indirection == 0 && (ident_type->is_object() && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(stmt->declaration_statement.expression)->clone_with_increased_indirection()))))
interpret(ast_statement_ptr(make_method_call(ident, "copy_construct", vector(make_operator_call("&", vector(stmt->declaration_statement.expression))))), var_stack, enclosing_object, enclosing_func, defer_stack) interpret(ast_statement_ptr(make_method_call(ident, "copy_construct", vector(make_operator_call("&", vector(stmt->declaration_statement.expression))))), var_stack, enclosing_object, enclosing_func, defer_stack)
else else
store_into_variable(var_stack->top()[ident], get_real_value(interpret(stmt->declaration_statement.expression, var_stack, enclosing_object, enclosing_func, defer_stack).first)) store_into_variable(var_stack->top()[ident], get_real_value(interpret(stmt->declaration_statement.expression, var_stack, enclosing_object, enclosing_func, defer_stack).first))
@@ -966,7 +965,7 @@ obj interpreter (Object) {
interpret(stmt->declaration_statement.init_method_call, var_stack, enclosing_object, enclosing_func, defer_stack) interpret(stmt->declaration_statement.init_method_call, var_stack, enclosing_object, enclosing_func, defer_stack)
} }
// defering destructs // defering destructs
if (ident_type->indirection == 0 && (ident_type->is_adt() || (ident_type->is_object() && has_method(ident_type->type_def, "destruct", vector<*type>())))) if (ident_type->indirection == 0 && (ident_type->is_object() && has_method(ident_type->type_def, "destruct", vector<*type>())))
defer_stack->push(ast_statement_ptr(make_method_call(ident, "destruct", vector<*ast_node>()))) defer_stack->push(ast_statement_ptr(make_method_call(ident, "destruct", vector<*ast_node>())))
return make_pair(value::void_nothing(), control_flow::nor()) return make_pair(value::void_nothing(), control_flow::nor())
} }

View File

@@ -1,10 +1,33 @@
import ast_nodes:* import ast_nodes:*
import ast_transformation:*
import mem:* import mem:*
import util:* import util:*
import vector:* import vector:*
import stack:* import stack:*
import string:* import string:*
fun make_this_noncached(object: *ast_node): *ast_node {
return ast_identifier_ptr("this", object->type_def.self_type->clone_with_indirection(1), object)
}
fun possible_object_equality(lvalue: *ast_node, rvalue: *ast_node): *ast_node {
var ltype = get_ast_type(lvalue)
var rtype = get_ast_type(rvalue)
if (ltype->indirection == 0 && (ltype->is_object() && has_method(ltype->type_def, "operator==", vector(rtype)))) {
return make_method_call(lvalue, "operator==", vector(rvalue))
} else if (ltype->is_object())
// return false if object but no operator== (right now don't try for templated)
return ast_value_ptr(string("false"), type_ptr(base_type::boolean()))
return make_operator_call("==", vector(lvalue, rvalue))
}
// for now, needs source to already be in a variable for copy_constructing
fun assign_or_copy_construct_statement(lvalue: *ast_node, rvalue: *ast_node): *ast_node {
var ltype = get_ast_type(lvalue)
if (ltype->indirection == 0 && (ltype->is_object() && has_method(ltype->type_def, "copy_construct", vector(ltype->clone_with_increased_indirection()))))
return make_method_call(lvalue, "copy_construct", vector(make_operator_call("&", vector(rvalue))))
return ast_assignment_statement_ptr(lvalue, rvalue)
}
fun get_children_pointer(node: *ast_node): *vector<*ast_node> { fun get_children_pointer(node: *ast_node): *vector<*ast_node> {
var bc = null<vector<*ast_node>>() var bc = null<vector<*ast_node>>()
match(*node) { match(*node) {
@@ -54,6 +77,11 @@ fun replace_with_in(orig: *ast_node, new: *ast_node, in: *ast_node) {
} }
} }
fun add_before_in(to_add: ref vector<*ast_node>, before: *ast_node, in: *stack<*ast_node>)
to_add.for_each(fun(n: *ast_node) add_before_in(n, before, in);)
fun add_before_in(to_add: vector<*ast_node>, before: *ast_node, in: *ast_node)
to_add.for_each(fun(n: *ast_node) add_before_in(n, before, in);)
fun add_before_in(to_add: *ast_node, before: *ast_node, in: *stack<*ast_node>) fun add_before_in(to_add: *ast_node, before: *ast_node, in: *stack<*ast_node>)
add_before_in(to_add, before, in->top()) add_before_in(to_add, before, in->top())
fun add_before_in(to_add: *ast_node, before: *ast_node, in: *ast_node) { fun add_before_in(to_add: *ast_node, before: *ast_node, in: *ast_node) {
@@ -68,6 +96,7 @@ fun add_before_in(to_add: *ast_node, before: *ast_node, in: *ast_node) {
error(string("cannot add_before_in to ") + get_ast_name(in)) error(string("cannot add_before_in to ") + get_ast_name(in))
} }
fun empty_pass_half(node: *ast_node, parent_chain: *stack<*ast_node>) {}
fun run_on_tree(func_before: fun(*ast_node,*stack<*ast_node>):void, func_after: fun(*ast_node,*stack<*ast_node>):void, tree: *ast_node) { fun run_on_tree(func_before: fun(*ast_node,*stack<*ast_node>):void, func_after: fun(*ast_node,*stack<*ast_node>):void, tree: *ast_node) {
var parent_stack = stack<*ast_node>() var parent_stack = stack<*ast_node>()
run_on_tree_helper(func_before, func_after, tree, &parent_stack) run_on_tree_helper(func_before, func_after, tree, &parent_stack)
@@ -79,7 +108,9 @@ fun run_on_tree_helper(func_before: fun(*ast_node,*stack<*ast_node>):void, func_
match(*node) { match(*node) {
ast_node::translation_unit(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);) ast_node::translation_unit(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::type_def(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);) ast_node::type_def(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::adt_def(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::function(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);) ast_node::function(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::template(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::code_block(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);) ast_node::code_block(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);) ast_node::statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::if_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);) ast_node::if_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
@@ -87,6 +118,17 @@ fun run_on_tree_helper(func_before: fun(*ast_node,*stack<*ast_node>):void, func_
ast_node::case_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);) ast_node::case_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::while_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);) ast_node::while_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::for_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);) ast_node::for_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::return_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::defer_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::assignment_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::declaration_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::if_comp(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::function_call(backing) {
if (!is_function(backing.func))
run_on_tree_helper(func_before, func_after, backing.func, parent_chain)
node->function_call.parameters.for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
}
ast_node::cast(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
} }
parent_chain->pop() parent_chain->pop()
func_after(node, parent_chain) func_after(node, parent_chain)

View File

@@ -10,7 +10,6 @@ import io:*
adt base_type { adt base_type {
none, none,
object, object,
adt,
no_type_adt_option, no_type_adt_option,
function, function,
template, template,
@@ -95,10 +94,7 @@ obj type (Object) {
return this return this
} }
fun construct(type_def_in: *ast_node, traits_in: set<string>): *type { fun construct(type_def_in: *ast_node, traits_in: set<string>): *type {
if (is_type_def(type_def_in)) base.copy_construct(&base_type::object())
base.copy_construct(&base_type::object())
else
base.copy_construct(&base_type::adt())
parameter_types.construct() parameter_types.construct()
indirection = 0 indirection = 0
return_type = null<type>() return_type = null<type>()
@@ -160,7 +156,7 @@ obj type (Object) {
traits.for_each(fun(t: string) trait_string += t;) traits.for_each(fun(t: string) trait_string += t;)
trait_string += "] " trait_string += "] "
} }
var indr_string = string("") var indr_string = string("")
if (is_ref) if (is_ref)
indr_string += " ref " indr_string += " ref "
@@ -169,8 +165,7 @@ obj type (Object) {
for (var i = 0; i < indirection; i++;) indr_string += "*" for (var i = 0; i < indirection; i++;) indr_string += "*"
match (base) { match (base) {
base_type::none() return indr_string + string("none") + trait_string base_type::none() return indr_string + string("none") + trait_string
base_type::object() return indr_string + type_def->type_def.name + trait_string base_type::object() return indr_string + get_ast_name(type_def) + trait_string
base_type::adt() return indr_string + type_def->adt_def.name + trait_string
base_type::no_type_adt_option() return indr_string + "no_type_adt_option" + trait_string base_type::no_type_adt_option() return indr_string + "no_type_adt_option" + trait_string
base_type::template() return indr_string + string("template") + trait_string base_type::template() return indr_string + string("template") + trait_string
base_type::template_type() return indr_string + string("template_type") + trait_string base_type::template_type() return indr_string + string("template_type") + trait_string
@@ -225,20 +220,12 @@ obj type (Object) {
to_ret->is_ref = is_ref_in to_ret->is_ref = is_ref_in
return to_ret return to_ret
} }
fun is_object_like(): bool
return is_object() || is_adt()
fun is_object(): bool { fun is_object(): bool {
match (base) { match (base) {
base_type::object() return true base_type::object() return true
} }
return false return false
} }
fun is_adt(): bool {
match (base) {
base_type::adt() return true
}
return false
}
fun is_function(): bool { fun is_function(): bool {
match (base) { match (base) {
base_type::function() return true base_type::function() return true

View File

@@ -14,13 +14,15 @@ destructed object 100 : 100
copy constructed object 100 : 300 from 100 : 200 copy constructed object 100 : 300 from 100 : 200
destructed object 100 : 200 destructed object 100 : 200
copy constructed object 100 : 400 from 100 : 300 copy constructed object 100 : 400 from 100 : 300
destructed object 100 : 300
copy constructed object 100 : 500 from 100 : 400 copy constructed object 100 : 500 from 100 : 400
destructed object 100 : 400 destructed object 100 : 400
done assignment to old variable destructed object 100 : 300
matched an_obj correctly 100 : 500 copy constructed object 100 : 600 from 100 : 500
int assignment to old var
destructed object 100 : 500 destructed object 100 : 500
done assignment to old variable
matched an_obj correctly 100 : 600
int assignment to old var
destructed object 100 : 600
done int assignment to old var done int assignment to old var
matched an_int correctly 1337 matched an_int correctly 1337
test copy_construct for non ref equality test copy_construct for non ref equality
@@ -31,6 +33,8 @@ destructed object 110 : 110
copy constructed object 110 : 310 from 110 : 210 copy constructed object 110 : 310 from 110 : 210
destructed object 110 : 210 destructed object 110 : 210
copy constructed object 110 : 410 from 110 : 310 copy constructed object 110 : 410 from 110 : 310
copy constructed object 110 : 510 from 110 : 410
destructed object 110 : 410
destructed object 110 : 310 destructed object 110 : 310
gonna make object in function 110 gonna make object in function 110
constructed object 110 : 110 constructed object 110 : 110
@@ -39,10 +43,13 @@ destructed object 110 : 110
copy constructed object 110 : 310 from 110 : 210 copy constructed object 110 : 310 from 110 : 210
destructed object 110 : 210 destructed object 110 : 210
copy constructed object 110 : 410 from 110 : 310 copy constructed object 110 : 410 from 110 : 310
destructed object 110 : 310
copy constructed object 110 : 510 from 110 : 410 copy constructed object 110 : 510 from 110 : 410
destructed object 110 : 510 destructed object 110 : 410
destructed object 110 : 310
copy constructed object 110 : 610 from 110 : 510
destructed object 110 : 610
equality an_obj correctly equality an_obj correctly
destructed object 110 : 410 destructed object 110 : 510
destructed object 110 : 410 destructed object 110 : 510
done test copy_construct for non ref equality done test copy_construct for non ref equality
10

View File

@@ -157,6 +157,7 @@ fun main():int {
else else
println("equality an_obj incorrectly ") println("equality an_obj incorrectly ")
println("done test copy_construct for non ref equality"); println("done test copy_construct for non ref equality");
println(maybe_object::an_int(10).an_int)
return 0 return 0
} }