Now using adt_lower, which also makes the backing deconstruct a reference, which makes sense
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, ¶m_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, ¶m_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, ¶m_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, ¶m_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())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user