Now computes closed_variables for each lambda, placeholder closure_struct type stuff.
This commit is contained in:
@@ -169,10 +169,13 @@ obj ast_transformation (Object) {
|
||||
// transform parameters
|
||||
var parameters = vector<*ast_node>()
|
||||
get_nodes("typed_parameter", node).for_each(fun(child: *tree<symbol>) {
|
||||
parameters.add(ast_identifier_ptr(concat_symbol_tree(get_node("identifier", child)), transform_type(get_node("type", child), scope, template_replacements)))
|
||||
// note the temporary null<ast_node>() which gets replaced below, as the dependency is circular
|
||||
parameters.add(ast_identifier_ptr(concat_symbol_tree(get_node("identifier", child)), transform_type(get_node("type", child), scope, template_replacements), null<ast_node>()))
|
||||
})
|
||||
// figure out function type and make function_node
|
||||
var function_node = ast_function_ptr(function_name, type_ptr(parameters.map(fun(parameter: *ast_node): *type return parameter->identifier.type;), return_type), parameters)
|
||||
// fix up the enclosing_scope's
|
||||
parameters.for_each(fun(n: *ast_node) n->identifier.enclosing_scope = function_node;)
|
||||
// add to scope
|
||||
add_to_scope(function_name, function_node, scope)
|
||||
add_to_scope("~enclosing_scope", scope, function_node)
|
||||
@@ -372,7 +375,7 @@ obj ast_transformation (Object) {
|
||||
var name = concat_symbol_tree(node)
|
||||
if (name == "this") {
|
||||
while (!is_type_def(scope)) scope = get_ast_scope(scope)->get(string("~enclosing_scope"))[0]
|
||||
return ast_identifier_ptr("this", scope->type_def.self_type->clone_with_indirection(1))
|
||||
return ast_identifier_ptr("this", scope->type_def.self_type->clone_with_indirection(1), scope)
|
||||
}
|
||||
match (searching_for) {
|
||||
search_type::none() return identifier_lookup(name, scope)
|
||||
@@ -465,7 +468,7 @@ obj ast_transformation (Object) {
|
||||
ident_type = get_ast_type(expression)
|
||||
}
|
||||
if (!ident_type) error("declaration statement with no type or expression from which to inference type")
|
||||
var identifier = ast_identifier_ptr(name, ident_type)
|
||||
var identifier = ast_identifier_ptr(name, ident_type, scope)
|
||||
var declaration = ast_declaration_statement_ptr(identifier, expression)
|
||||
// ok, deal with the possible init position method call
|
||||
if (identifiers.size == 2) {
|
||||
@@ -541,10 +544,50 @@ obj ast_transformation (Object) {
|
||||
fun transform_lambda(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
||||
var function_node = second_pass_function(node, scope, template_replacements, false)
|
||||
function_node->function.body_statement = transform_statement(get_node("statement", node), function_node, template_replacements)
|
||||
function_node->function.closed_variables = find_closed_variables(function_node, function_node->function.body_statement)
|
||||
println(string("Found ") + function_node->function.closed_variables.size() + " closed variables!")
|
||||
while (!is_translation_unit(scope)) scope = get_ast_scope(scope)->get(string("~enclosing_scope"))[0]
|
||||
scope->translation_unit.lambdas.add(function_node)
|
||||
return function_node
|
||||
}
|
||||
fun find_closed_variables(func: *ast_node, node: *ast_node): set<*ast_node> {
|
||||
match (*node) {
|
||||
ast_node::identifier(backing) {
|
||||
println("found an identifier")
|
||||
println(backing.name)
|
||||
if (!in_scope_chain(backing.enclosing_scope, func))
|
||||
return set(node);
|
||||
}
|
||||
ast_node::statement(backing) {
|
||||
println("found an statement")
|
||||
return find_closed_variables(func, backing.child)
|
||||
}
|
||||
ast_node::code_block(backing) {
|
||||
println("found an code_block")
|
||||
var to_ret = set<*ast_node>()
|
||||
backing.children.for_each(fun(n: *ast_node) to_ret += find_closed_variables(func, n);)
|
||||
return to_ret
|
||||
}
|
||||
ast_node::function_call(backing) {
|
||||
println("found an function_call")
|
||||
var to_ret = find_closed_variables(func, backing.func)
|
||||
backing.parameters.for_each(fun(n: *ast_node) to_ret += find_closed_variables(func, n);)
|
||||
return to_ret
|
||||
}
|
||||
ast_node::return_statement(backing) {
|
||||
println("found an return_statement")
|
||||
return find_closed_variables(func, backing.return_value)
|
||||
}
|
||||
}
|
||||
return set<*ast_node>()
|
||||
}
|
||||
fun in_scope_chain(node: *ast_node, high_scope: *ast_node): bool {
|
||||
if (node == high_scope)
|
||||
return true
|
||||
if (get_ast_scope(node)->contains_key(string("~enclosing_scope")))
|
||||
return in_scope_chain(get_ast_scope(node)->get(string("~enclosing_scope"))[0], high_scope)
|
||||
return false
|
||||
}
|
||||
fun transform_expression(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node return transform_expression(node, scope, search_type::none(), template_replacements)
|
||||
fun transform_expression(node: *tree<symbol>, scope: *ast_node, searching_for: search_type, template_replacements: map<string, *type>): *ast_node {
|
||||
var func_name = string()
|
||||
|
||||
Reference in New Issue
Block a user