diff --git a/stdlib/ast_nodes.krak b/stdlib/ast_nodes.krak index c7116f0..81d672a 100644 --- a/stdlib/ast_nodes.krak +++ b/stdlib/ast_nodes.krak @@ -632,8 +632,8 @@ obj branching_statement (Object) { return true } } -fun ast_defer_statement_ptr(): *ast_node { - var to_ret.construct(): defer_statement +fun ast_defer_statement_ptr(statement_in: *ast_node): *ast_node { + var to_ret.construct(statement_in): defer_statement var ptr = new() ptr->copy_construct(&ast_node::defer_statement(to_ret)) return ptr @@ -645,16 +645,15 @@ fun is_defer_statement(node: *ast_node): bool { return false } obj defer_statement (Object) { - var scope: map> - fun construct(): *defer_statement { - scope.construct() + var statement: *ast_node + fun construct(statement_in: *ast_node): *defer_statement { + statement = statement_in return this } fun copy_construct(old: *defer_statement) { - scope.copy_construct(&old->scope) + statement = old->statement } fun destruct() { - scope.destruct() } fun operator=(other: ref defer_statement) { destruct() @@ -894,7 +893,7 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> { ast_node::for_loop(backing) return vector(backing.init, backing.condition, backing.update, backing.body) ast_node::return_statement(backing) return vector(backing.return_value) ast_node::branching_statement(backing) return vector<*ast_node>() - ast_node::defer_statement(backing) return vector<*ast_node>() + ast_node::defer_statement(backing) return vector(backing.statement) ast_node::assignment_statement(backing) return vector(backing.to, backing.from) ast_node::declaration_statement(backing) return vector(backing.identifier, backing.expression) ast_node::if_comp(backing) return vector<*ast_node>(backing.statement) @@ -945,15 +944,10 @@ fun get_ast_scope(node: *ast_node): *map> { ast_node::while_loop() return &node->while_loop.scope ast_node::for_loop() return &node->for_loop.scope ast_node::return_statement() return &node->return_statement.scope - ast_node::branching_statement() return null>>() - ast_node::defer_statement() return &node->defer_statement.scope - ast_node::assignment_statement() return null>>() - ast_node::declaration_statement() return null>>() - ast_node::if_comp() return null>>() ast_node::simple_passthrough() return &node->simple_passthrough.scope - ast_node::function_call() return null>>() ast_node::value() return &node->value.scope } + return null>>() } fun get_ast_type(node: *ast_node): *type { match (*node) { diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index b4f01a2..09d94fa 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -229,6 +229,8 @@ obj ast_transformation (Object) { return transform_return_statement(node, scope) } else if (name == "continue_statement" || name == "break_statement") { return transform_branching_statement(node, scope) + } else if (name == "defer_statement") { + return transform_defer_statement(node, scope) } else if (name == "function_call") { return transform_function_call(node, scope) } else if (name == "boolean_expression" || name == "and_boolean_expression" @@ -370,6 +372,9 @@ obj ast_transformation (Object) { return ast_branching_statement_ptr(branching_type::break_stmt()) return ast_branching_statement_ptr(branching_type::continue_stmt()) } + fun transform_defer_statement(node: *tree, scope: *ast_node): *ast_node { + return ast_defer_statement_ptr(transform(node->children[0], scope)) + } fun transform_function_call(node: *tree, scope: *ast_node): *ast_node { // don't bother with a full transform for parameters with their own function, just get the boolean expression and transform it var parameters = get_nodes("parameter", node).map(fun(child: *tree): *ast_node return transform(get_node("boolean_expression", child), scope);) diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index 234774e..69df492 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -141,6 +141,7 @@ obj c_generator (Object) { branching_type::continue_stmt() return string("continue") } } + fun generate_defer_statement(node: *ast_node, enclosing_object: *ast_node): string return string("/*defer ") + generate(node->defer_statement.statement, enclosing_object) + "*/"; fun generate_value(node: *ast_node): string return node->value.string_value; fun generate_code_block(node: *ast_node, enclosing_object: *ast_node): string { var to_ret = string("{\n") @@ -218,6 +219,7 @@ obj c_generator (Object) { ast_node::code_block(backing) return generate_code_block(node, enclosing_object) ast_node::return_statement(backing) return generate_return_statement(node, enclosing_object) ast_node::branching_statement(backing) return generate_branching_statement(node, enclosing_object) + ast_node::defer_statement(backing) return generate_defer_statement(node, enclosing_object) ast_node::value(backing) return generate_value(node) ast_node::identifier(backing) return generate_identifier(node, enclosing_object) } diff --git a/stdlib/importer.krak b/stdlib/importer.krak index c499099..13070ed 100644 --- a/stdlib/importer.krak +++ b/stdlib/importer.krak @@ -85,6 +85,7 @@ obj importer (Object) { remove_node(symbol("\"fun\"", true), parse_tree) remove_node(symbol("\"template\"", true), parse_tree) remove_node(symbol("\"return\"", true), parse_tree) + remove_node(symbol("\"defer\"", true), parse_tree) remove_node(symbol("\";\"", true), parse_tree) remove_node(symbol("line_end", false), parse_tree) remove_node(symbol("\"{\"", true), parse_tree) diff --git a/tests/to_parse.krak b/tests/to_parse.krak index 69d7a18..8234a5d 100644 --- a/tests/to_parse.krak +++ b/tests/to_parse.krak @@ -57,6 +57,10 @@ fun main(): int { var with_ptr = an_obj.return_this() simple_print(with_ptr->method(2)) simple_print("\n") + { + defer simple_print("should_be_second\n") + simple_print("should be first\n") + } return 0 }