From ca85edaeeeace3bcc368b55718e8072af52e051f Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Tue, 19 Jan 2016 03:16:16 -0500 Subject: [PATCH] added while loops and fixed unary operators (including correct precrement and decrement) --- krakenGrammer.kgm | 2 +- stdlib/ast_nodes.krak | 16 +++++++--- stdlib/ast_transformation.krak | 26 ++++++++++++++-- stdlib/c_generator.krak | 7 +++++ tests/to_parse.krak | 57 ++++++++++++++++++++-------------- 5 files changed, 75 insertions(+), 33 deletions(-) diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index c7c2077..6ea9388 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -124,7 +124,7 @@ comparator = "==" | "<=" | ">=" | "!=" | "<" | ">" ; expression = expression WS "<<" WS term | expression WS right_shift WS shiftand | shiftand ; shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ; term = term WS "/" WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ; -factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\(" WS type WS "\)" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ; +factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ; unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | unarad WS "[" WS expression WS "]" | lambda ; number = integer | floating_literal ; access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier | unarad WS "." WS identifier WS template_inst | unarad WS "->" WS identifier WS template_inst ; diff --git a/stdlib/ast_nodes.krak b/stdlib/ast_nodes.krak index 35475bc..059e51e 100644 --- a/stdlib/ast_nodes.krak +++ b/stdlib/ast_nodes.krak @@ -469,8 +469,8 @@ obj case_statement (Object) { return true } } -fun ast_while_loop_ptr(): *ast_node { - var to_ret.construct(): while_loop +fun ast_while_loop_ptr(condition: *ast_node): *ast_node { + var to_ret.construct(condition): while_loop var ptr = new() ptr->copy_construct(&ast_node::while_loop(to_ret)) return ptr @@ -482,12 +482,18 @@ fun is_while_loop(node: *ast_node): bool { return false } obj while_loop (Object) { + var condition: *ast_node + var statement: *ast_node var scope: map> - fun construct(): *while_loop { + fun construct(condition_in: *ast_node): *while_loop { + condition = condition_in + statement = null() scope.construct() return this } fun copy_construct(old: *while_loop) { + condition = old->condition + statement = old->statement scope.copy_construct(&old->scope) } fun destruct() { @@ -498,7 +504,7 @@ obj while_loop (Object) { copy_construct(&other) } fun operator==(other: ref while_loop): bool { - return true + return condition == other.condition && statement == other.statement } } fun ast_for_loop_ptr(): *ast_node { @@ -890,7 +896,7 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> { ast_node::if_statement(backing) return vector(backing.condition, backing.then_part, backing.else_part) 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<*ast_node>() + ast_node::while_loop(backing) return vector(backing.condition, backing.statement) ast_node::for_loop(backing) return vector<*ast_node>() ast_node::return_statement(backing) return vector(backing.return_value) ast_node::break_statement(backing) return vector<*ast_node>() diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index 76742df..a429706 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -190,6 +190,8 @@ obj ast_transformation (Object) { return transform_assignment_statement(node, scope) } else if (name == "if_statement") { return transform_if_statement(node, scope) + } else if (name == "while_loop") { + return transform_while_loop(node, scope) } else if (name == "return_statement") { return transform_return_statement(node, scope) } else if (name == "function_call") { @@ -300,6 +302,12 @@ obj ast_transformation (Object) { if_statement->if_statement.else_part = statements[1] return if_statement } + fun transform_while_loop(node: *tree, scope: *ast_node): *ast_node { + var while_loop = ast_while_loop_ptr(transform_expression(get_node("boolean_expression", node), scope)) + add_to_scope("~enclosing_scope", scope, while_loop) + while_loop->while_loop.statement = transform(get_node("statement", node), while_loop) + return while_loop + } fun transform_return_statement(node: *tree, scope: *ast_node): *ast_node { return ast_return_statement_ptr(transform(node->children[0], scope)) } @@ -318,14 +326,26 @@ obj ast_transformation (Object) { fun transform_expression(node: *tree, scope: *ast_node): *ast_node { // figure out what the expression is, handle overloads, or you know // ignore everything and do a passthrough + var func_name = string() + var parameters = vector<*ast_node>() if (node->children.size == 1) return transform(node->children[0], scope) else if (node->children.size == 2) { - return transform(node->children[0], scope) + var check_if_post = concat_symbol_tree(node->children[1]) + if (check_if_post == "--" || check_if_post == "++") { + // give the post-operators a special suffix so the c_generator knows to emit them post + func_name = concat_symbol_tree(node->children[1]) + "p" + parameters = vector(transform(node->children[0], scope)) + } else { + func_name = concat_symbol_tree(node->children[0]) + parameters = vector(transform(node->children[1], scope)) + } + } else { + func_name = concat_symbol_tree(node->children[1]) + parameters = vector(transform(node->children[0], scope), transform(node->children[2], scope)) } - var parameters = vector(transform(node->children[0], scope), transform(node->children[2], scope)) var parameter_types = parameters.map(fun(param: *ast_node): *type return get_ast_type(param);) - return ast_function_call_ptr(get_builtin_function(concat_symbol_tree(node->children[1]), parameter_types), parameters) + return ast_function_call_ptr(get_builtin_function(func_name, parameter_types), parameters) } fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node { return ast_function_ptr(name, type_ptr(param_types, param_types[0]), vector<*ast_node>()) diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index a2bd941..afd324b 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -99,6 +99,9 @@ obj c_generator (Object) { if_str += string(" else {\n") + generate(node->if_statement.else_part) + "}" return if_str + "\n" } + 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_identifier(node: *ast_node): string { return node->identifier.name } @@ -121,6 +124,9 @@ obj c_generator (Object) { var parameters = node->function_call.parameters if (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") + return string("(") + generate(parameters[0]) + ")" + func_name.slice(0,-2) var call_string = string() parameters.for_each(fun(param: *ast_node) { if (call_string != "") @@ -140,6 +146,7 @@ obj c_generator (Object) { ast_node::declaration_statement(backing) return generate_declaration_statement(node) 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::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_parse.krak b/tests/to_parse.krak index 33a96a4..a4b5912 100644 --- a/tests/to_parse.krak +++ b/tests/to_parse.krak @@ -1,31 +1,40 @@ import to_import: simple_print, a, b -obj Something (ObjectTrait) { - var member: int - fun method():int { - return 5 - } -} +/*obj Something (ObjectTrait) {*/ + /*var member: int*/ + /*fun method():int {*/ + /*return 5*/ + /*}*/ +/*}*/ -fun some_function(): int return 0; -fun some_other_function(in: bool): float { - return 0.0 -} +/*fun some_function(): int return 0;*/ +/*fun some_other_function(in: bool): float {*/ + /*return 0.0*/ +/*}*/ fun main(): int { - var a_declaration:int - simple_print(1 + 2) - var again = 2 + 4 - 1 * 400 - simple_print(again) - again = 2 + (4 - 1) * 400 - simple_print(again) - var another_declaration: int = 8.0 - simple_print(another_declaration) - var yet_another_declaration = "Hello Marcus\n" - simple_print(yet_another_declaration) - simple_print("Hello World!\n") - simple_print(1337) - if (1 + 2 && false) simple_print("its true!") - else simple_print("its false!") + /*var a_declaration:int*/ + /*simple_print(1 + 2)*/ + /*var again = 2 + 4 - 1 * 400*/ + /*simple_print(again)*/ + /*again = 2 + (4 - 1) * 400*/ + /*simple_print(again)*/ + /*var another_declaration: int = 8.0*/ + /*simple_print(another_declaration)*/ + /*var yet_another_declaration = "Hello Marcus\n"*/ + /*simple_print(yet_another_declaration)*/ + /*simple_print("Hello World!\n")*/ + /*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) + } return 0 }