diff --git a/stdlib/adt_lower.krak b/stdlib/adt_lower.krak index ea71181..95f2156 100644 --- a/stdlib/adt_lower.krak +++ b/stdlib/adt_lower.krak @@ -25,9 +25,6 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ 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(), false)) type_def_option_map[node].add(opt) @@ -52,17 +49,12 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ 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) @@ -78,12 +70,10 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ 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)) @@ -101,12 +91,10 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ } 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)) diff --git a/stdlib/interpreter.krak b/stdlib/interpreter.krak index c49f6fd..a837e0d 100644 --- a/stdlib/interpreter.krak +++ b/stdlib/interpreter.krak @@ -307,7 +307,6 @@ fun store_into_variable(to: ref value, from: value) { base_type::ulong_int() { assert(is_ulong_int(from), "mismatching assignemnt types - from is not ulong_int"); *(variable.first) cast *ulong = from.ulong_int; } base_type::floating() { assert(is_floating(from), "mismatching assignemnt types - from is not floating"); *(variable.first) cast *float = from.floating; } base_type::double_precision() { assert(is_double_precision(from), "mismatching assignemnt types - from is not double"); *(variable.first) cast *double = from.double_precision; } - 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; } } } fun get_real_value(v: value): value { @@ -322,8 +321,6 @@ fun get_real_value(v: value): value { match (var_type->base) { // really this could just be make_pair(variable) base_type::object() return value::object_like(make_pair(var_ptr, var_type)) - /*base_type::adt() return #sizeof<>*/ - /*base_type::function() return #sizeof<>*/ base_type::boolean() return value::boolean(*(var_ptr) cast *bool) base_type::character() return value::character(*(var_ptr) cast *char) base_type::ucharacter() return value::ucharacter(*(var_ptr) cast *uchar) @@ -470,7 +467,6 @@ fun type_size(t: *type): ulong { }) return size } - /*base_type::adt() return #sizeof<>*/ base_type::function() return #sizeof>> base_type::boolean() return #sizeof base_type::character() return #sizeof @@ -553,7 +549,7 @@ obj interpreter (Object) { printlnerr("=============") var var_stack = stack>() var_stack.push(map<*ast_node,value>()) - var result = call_function(results[0], vector(), vector<*ast_node>(), &var_stack, value::void_nothing(), value::void_nothing(), null()) + var result = call_function(results[0], vector(), vector<*ast_node>(), &var_stack, map<*ast_node,value>(), value::void_nothing(), value::void_nothing(), null()) printlnerr("=============") printlnerr("Done!") printlnerr("=============") @@ -588,11 +584,18 @@ obj interpreter (Object) { var func_call_func = func_call->function_call.func var new_enclosing_object = value::void_nothing() var dot_style_method_call = is_dot_style_method_call(func_call) + var possible_closure_map = map<*ast_node,value>() // test for function value if (!dot_style_method_call && !is_function(func_call_func)) { /*error("func_call_func is not a function")*/ /*println(string("func_call_func is not a function: ") + get_ast_name(func_call_func))*/ - func_call_func = get_real_value(interpret(func_call_func, var_stack, enclosing_object, enclosing_func).first).function.first + var func_value = get_real_value(interpret(func_call_func, var_stack, enclosing_object, enclosing_func).first) + func_call_func = func_value.function.first + possible_closure_map = func_value.function.second + println("possible_closure_map is") + possible_closure_map.for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");) + println() + println("end pcm") /*println(string("calling func we got from interpreting: ") + get_ast_name(func_call_func))*/ } // note here also that this is likely not a foolproof method @@ -676,19 +679,27 @@ obj interpreter (Object) { // not the operator & and at least one object like parameter parameter_sources = func_call_parameters } - return make_pair(call_function(func_call_func, parameters, parameter_sources, var_stack, enclosing_object, new_enclosing_object, enclosing_func), control_flow::nor()) + return make_pair(call_function(func_call_func, parameters, parameter_sources, var_stack, possible_closure_map, enclosing_object, new_enclosing_object, enclosing_func), control_flow::nor()) } // call_function can be called with either parameter values in parameters or ast expressions in parameter_sources // this is to allow easy function calling if we already have the values (for main, say, or to make our job if it's not // an operator easier), but we need to be able to be called with ast_expressions too so we can properly copy_construct once - fun call_function(func: *ast_node, parameters: vector, parameter_sources: vector<*ast_node>, var_stack: *stack>, enclosing_object: value, new_enclosing_object: value, enclosing_func: *ast_node): value { + fun call_function(func: *ast_node, parameters: vector, parameter_sources: vector<*ast_node>, var_stack: *stack>, possible_closure_map: ref map<*ast_node, value>, enclosing_object: value, new_enclosing_object: value, enclosing_func: *ast_node): value { // will need adjustment if (!is_function(func)) error("Can't handle not function function calls (can do regular method, is this chained or something?)") var func_name = func->function.name // do regular function - var new_var_stack = stack>() + // start out with the possible closure map as the highest scope (gloabals checked seperately) + var new_var_stack = stack(possible_closure_map) new_var_stack.push(map<*ast_node,value>()) + println("stack after pcm and new m is") + for (var i = 0; i < new_var_stack.size(); i++;) { + println(string("level: ") + i) + new_var_stack.from_top(i).for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");) + println() + } + println("end stack after") // if this is a value based call, pull from parameters if (parameter_sources.size == 0) { /*println(func_name + " being called with parameter values")*/ @@ -814,7 +825,16 @@ obj interpreter (Object) { return value::void_nothing() } fun interpret_function(function: *ast_node, var_stack: *stack>, enclosing_object: value, enclosing_func: *ast_node): pair { - return make_pair(value::function(make_pair(function, map<*ast_node,value>())), control_flow::nor()) + var possible_closure_map = map<*ast_node,value>() + function->function.closed_variables.for_each(fun(v: *ast_node) { + possible_closure_map[v] = interpret_identifier(v, var_stack, enclosing_object, enclosing_func).first + println(string("closing over ") + get_ast_name(v)) + }) + println("in interpret function possible_closure_map is") + possible_closure_map.for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");) + println() + println("end in inteprret function pcm") + return make_pair(value::function(make_pair(function, possible_closure_map)), control_flow::nor()) } fun interpret_statement(stmt: *ast_node, var_stack: *stack>, enclosing_object: value, enclosing_func: *ast_node): pair { return interpret(stmt->statement.child, var_stack, enclosing_object, enclosing_func) @@ -960,6 +980,12 @@ obj interpreter (Object) { // check for global if (globals.contains_key(ident)) return make_pair(globals[ident], control_flow::nor()) + println("couldn't find it in interpret identifier") + for (var i = 0; i < var_stack->size(); i++;) { + println(string("level: ") + i) + var_stack->from_top(i).for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");) + println() + } error(string("Cannot find variable: ") + ident->identifier.name) } fun interpret_cast(node: *ast_node, var_stack: *stack>, enclosing_object: value, enclosing_func: *ast_node): pair {