diff --git a/stdlib/ast_nodes.krak b/stdlib/ast_nodes.krak index 059e51e..8ecf21b 100644 --- a/stdlib/ast_nodes.krak +++ b/stdlib/ast_nodes.krak @@ -520,12 +520,24 @@ fun is_for_loop(node: *ast_node): bool { return false } obj for_loop (Object) { + var init: *ast_node + var condition: *ast_node + var update: *ast_node + var body: *ast_node var scope: map> fun construct(): *for_loop { scope.construct() + init = null() + condition = null() + update = null() + body = null() return this } fun copy_construct(old: *for_loop) { + init = old->init + condition = old->condition + update = old->update + body = old->body scope.copy_construct(&old->scope) } fun destruct() { @@ -536,7 +548,7 @@ obj for_loop (Object) { copy_construct(&other) } fun operator==(other: ref for_loop): bool { - return true + return init == other.init && condition == other.condition && update == other.update && body == other.body } } fun ast_return_statement_ptr(return_value: *ast_node): *ast_node { @@ -897,7 +909,7 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> { ast_node::match_statement(backing) return vector<*ast_node>() ast_node::case_statement(backing) return vector<*ast_node>() ast_node::while_loop(backing) return vector(backing.condition, backing.statement) - ast_node::for_loop(backing) return 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::break_statement(backing) return vector<*ast_node>() ast_node::continue_statement(backing) return vector<*ast_node>() diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index a429706..be4a9a0 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -192,6 +192,8 @@ obj ast_transformation (Object) { return transform_if_statement(node, scope) } else if (name == "while_loop") { return transform_while_loop(node, scope) + } else if (name == "for_loop") { + return transform_for_loop(node, scope) } else if (name == "return_statement") { return transform_return_statement(node, scope) } else if (name == "function_call") { @@ -308,6 +310,16 @@ obj ast_transformation (Object) { while_loop->while_loop.statement = transform(get_node("statement", node), while_loop) return while_loop } + fun transform_for_loop(node: *tree, scope: *ast_node): *ast_node { + var for_loop = ast_for_loop_ptr() + add_to_scope("~enclosing_scope", scope, for_loop) + var statements = get_nodes("statement", node) + for_loop->for_loop.init = transform(statements[0], for_loop) + for_loop->for_loop.condition = transform(get_node("boolean_expression", node), for_loop) + for_loop->for_loop.update = transform(statements[1], for_loop) + for_loop->for_loop.body = transform(statements[2], for_loop) + return for_loop + } fun transform_return_statement(node: *tree, scope: *ast_node): *ast_node { return ast_return_statement_ptr(transform(node->children[0], scope)) } diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index afd324b..e4498ae 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -102,6 +102,11 @@ obj c_generator (Object) { fun generate_while_loop(node: *ast_node): string { return string("while (") + generate(node->while_loop.condition) + ") {\n" + generate(node->while_loop.statement) + "}\n" } + fun generate_for_loop(node: *ast_node): string { + // gotta take off last semicolon + return string("for (") + generate(node->for_loop.init) + " " + generate(node->for_loop.condition) + "; " + + generate(node->for_loop.update).slice(0,-3) + ") {\n" + generate(node->for_loop.body) + "}\n" + } fun generate_identifier(node: *ast_node): string { return node->identifier.name } @@ -121,8 +126,11 @@ obj c_generator (Object) { } fun generate_function_call(node: *ast_node): string { var func_name = generate(node->function_call.func) - var parameters = node->function_call.parameters - if (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/" || func_name == "||" || func_name == "&&") + 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 == "==" + ) return string("(") + generate(parameters[0]) + func_name + generate(parameters[1]) + string(")") // the post ones need to be post-ed specifically, and take the p off if (func_name == "++p" || func_name == "--p") @@ -147,6 +155,7 @@ obj c_generator (Object) { ast_node::assignment_statement(backing) return generate_assignment_statement(node) ast_node::if_statement(backing) return generate_if_statement(node) ast_node::while_loop(backing) return generate_while_loop(node) + ast_node::for_loop(backing) return generate_for_loop(node) ast_node::function(backing) return generate_function(node) ast_node::function_call(backing) return generate_function_call(node) ast_node::code_block(backing) return generate_code_block(node) diff --git a/tests/to_import.krak b/tests/to_import.krak index fd82aa5..18ac7df 100644 --- a/tests/to_import.krak +++ b/tests/to_import.krak @@ -9,9 +9,7 @@ fun simple_print(to_print: int) { printf("%d", to_print); """ } -/*var a = 1*/ -/*var b = 2*/ -var a:int +var a = 1 var b:int diff --git a/tests/to_parse.krak b/tests/to_parse.krak index a4b5912..624b871 100644 --- a/tests/to_parse.krak +++ b/tests/to_parse.krak @@ -35,6 +35,9 @@ fun main(): int { while (counter) { simple_print(--counter) } + simple_print("\n") + for (var j = 0; j < 10; j++;) + simple_print(j) return 0 }