From 83a76c36deba5ff5133d91ac27fe1028723a89f5 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sun, 24 Jan 2016 17:31:41 -0500 Subject: [PATCH] continue and break statements --- src/CGenerator.cpp | 2 +- stdlib/ast_nodes.krak | 76 ++++++++++------------------------ stdlib/ast_transformation.krak | 7 ++++ stdlib/c_generator.krak | 9 +++- tests/to_parse.krak | 27 ++++++------ 5 files changed, 53 insertions(+), 68 deletions(-) diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index 3d5fa9f..ebcda72 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -41,7 +41,7 @@ void CGenerator::generateCompSet(std::map*> ASTs, outputBuild.open(outputName + "/" + scriptName); outputBuild << buildString; outputBuild.close(); - std::cout << "KRAKEN COMPILING DONE, CALLING C COMPILER" << std::endl; + std::cout << "KRAKEN COMPILER DONE, CALLING C COMPILER" << std::endl; ssystem("cd " + outputName + "/; sh " + scriptName); std::cout << "DEFER DOUBLE STACK " << deferDoubleStack.size() << std::endl; } diff --git a/stdlib/ast_nodes.krak b/stdlib/ast_nodes.krak index f5e5034..c7116f0 100644 --- a/stdlib/ast_nodes.krak +++ b/stdlib/ast_nodes.krak @@ -26,8 +26,7 @@ adt ast_node { while_loop: while_loop, for_loop: for_loop, return_statement: return_statement, - break_statement: break_statement, - continue_statement: continue_statement, + branching_statement: branching_statement, defer_statement: defer_statement, assignment_statement: assignment_statement, declaration_statement: declaration_statement, @@ -597,67 +596,39 @@ obj return_statement (Object) { return return_value == other.return_value } } -fun ast_break_statement_ptr(): *ast_node { - var to_ret.construct(): break_statement +adt branching_type { + break_stmt, + continue_stmt +} +fun ast_branching_statement_ptr(b_type: branching_type): *ast_node { + var to_ret.construct(b_type): branching_statement var ptr = new() - ptr->copy_construct(&ast_node::break_statement(to_ret)) + ptr->copy_construct(&ast_node::branching_statement(to_ret)) return ptr } -fun is_break_statement(node: *ast_node): bool { +fun is_branching_statement(node: *ast_node): bool { match(*node) { - ast_node::break_statement(backing) return true + ast_node::branching_statement(backing) return true } return false } -obj break_statement (Object) { - var scope: map> - fun construct(): *break_statement { - scope.construct() +obj branching_statement (Object) { + var b_type: branching_type + fun construct(b_type_in: branching_type): *branching_statement { + b_type.copy_construct(&b_type_in) return this } - fun copy_construct(old: *break_statement) { - scope.copy_construct(&old->scope) + fun copy_construct(old: *branching_statement) { + b_type.copy_construct(&old->b_type) } fun destruct() { - scope.destruct() + b_type.destruct() } - fun operator=(other: ref break_statement) { + fun operator=(other: ref branching_statement) { destruct() copy_construct(&other) } - fun operator==(other: ref break_statement): bool { - return true - } -} -fun ast_continue_statement_ptr(): *ast_node { - var to_ret.construct(): continue_statement - var ptr = new() - ptr->copy_construct(&ast_node::continue_statement(to_ret)) - return ptr -} -fun is_continue_statement(node: *ast_node): bool { - match(*node) { - ast_node::continue_statement(backing) return true - } - return false -} -obj continue_statement (Object) { - var scope: map> - fun construct(): *continue_statement { - scope.construct() - return this - } - fun copy_construct(old: *continue_statement) { - scope.copy_construct(&old->scope) - } - fun destruct() { - scope.destruct() - } - fun operator=(other: ref continue_statement) { - destruct() - copy_construct(&other) - } - fun operator==(other: ref continue_statement): bool { + fun operator==(other: ref branching_statement): bool { return true } } @@ -922,8 +893,7 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> { ast_node::while_loop(backing) return vector(backing.condition, backing.statement) 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::break_statement(backing) return vector<*ast_node>() - ast_node::continue_statement(backing) return vector<*ast_node>() + ast_node::branching_statement(backing) return vector<*ast_node>() ast_node::defer_statement(backing) return vector<*ast_node>() ast_node::assignment_statement(backing) return vector(backing.to, backing.from) ast_node::declaration_statement(backing) return vector(backing.identifier, backing.expression) @@ -949,8 +919,7 @@ fun get_ast_name(node: *ast_node): string { ast_node::while_loop(backing) return string("while_loop") ast_node::for_loop(backing) return string("for_loop") ast_node::return_statement(backing) return string("return_statement") - ast_node::break_statement(backing) return string("break_statement") - ast_node::continue_statement(backing) return string("continue_statement") + ast_node::branching_statement(backing) return string("branching_statement") ast_node::defer_statement(backing) return string("defer_statement") ast_node::assignment_statement(backing) return string("assignment_statement") ast_node::declaration_statement(backing) return string("declaration_statement") @@ -976,8 +945,7 @@ 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::break_statement() return &node->break_statement.scope - ast_node::continue_statement() return &node->continue_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>>() diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index b3bda99..b4f01a2 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -227,6 +227,8 @@ obj ast_transformation (Object) { return transform_for_loop(node, scope) } else if (name == "return_statement") { return transform_return_statement(node, scope) + } else if (name == "continue_statement" || name == "break_statement") { + return transform_branching_statement(node, scope) } else if (name == "function_call") { return transform_function_call(node, scope) } else if (name == "boolean_expression" || name == "and_boolean_expression" @@ -363,6 +365,11 @@ obj ast_transformation (Object) { fun transform_return_statement(node: *tree, scope: *ast_node): *ast_node { return ast_return_statement_ptr(transform(node->children[0], scope)) } + fun transform_branching_statement(node: *tree, scope: *ast_node): *ast_node { + if (node->data.name == "break_statement") + return ast_branching_statement_ptr(branching_type::break_stmt()) + return ast_branching_statement_ptr(branching_type::continue_stmt()) + } 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 dde002b..234774e 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -135,6 +135,12 @@ obj c_generator (Object) { return node->identifier.name } fun generate_return_statement(node: *ast_node, enclosing_object: *ast_node): string return string("return ") + generate(node->return_statement.return_value, enclosing_object); + fun generate_branching_statement(node: *ast_node, enclosing_object: *ast_node): string { + match(node->branching_statement.b_type) { + branching_type::break_stmt() return string("break") + branching_type::continue_stmt() return string("continue") + } + } 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") @@ -176,7 +182,7 @@ obj c_generator (Object) { var parameters = node->function_call.parameters if (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/" || func_name == "||" || func_name == "&&" || func_name == "<" || func_name == ">" || func_name == "<=" || func_name == ">=" - || func_name == "==" + || func_name == "==" || func_name == "%" ) return string("(") + generate(parameters[0], enclosing_object) + func_name + generate(parameters[1], enclosing_object) + string(")") // don't propegate enclosing function down right of access @@ -211,6 +217,7 @@ obj c_generator (Object) { ast_node::function_call(backing) return generate_function_call(node, enclosing_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::value(backing) return generate_value(node) ast_node::identifier(backing) return generate_identifier(node, enclosing_object) } diff --git a/tests/to_parse.krak b/tests/to_parse.krak index 718ca58..69d7a18 100644 --- a/tests/to_parse.krak +++ b/tests/to_parse.krak @@ -30,18 +30,21 @@ fun main(): int { /*simple_print(1337)*/ /*if (1 + 2 && false) simple_print("its true!")*/ /*else simple_print("its false!")*/ - /*var counter = 10*/ - /*counter--*/ - /*--counter*/ - /*while (counter) simple_print(counter--)*/ - /*simple_print("\n")*/ - /*counter = 8*/ - /*while (counter) {*/ - /*simple_print(--counter)*/ - /*}*/ - /*simple_print("\n")*/ - /*for (var j = 0; j < 10; j++;)*/ - /*simple_print(j)*/ + var counter = 10 + counter-- + --counter + while (counter) simple_print(counter--) + simple_print("\n") + counter = 8 + while (counter) { + simple_print(--counter) + if (counter == 2) + break + } + simple_print("\n") + for (var j = 0; j < 10; j++;) + if (j%2) continue + else simple_print(j) var an_obj: Something an_obj.member = 20 simple_print(an_obj.member)