diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 1f42e8a..676b201 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -1,4 +1,5 @@ Goal = translation_unit ; +cast_expression = "\(" WS boolean_expression WS "\)" WS "cast" WS type ; translation_unit = WS unorderd_list_part WS ; unorderd_list_part = import WS unorderd_list_part | function WS unorderd_list_part | type_def line_end WS unorderd_list_part | adt_def line_end WS unorderd_list_part | if_comp WS unorderd_list_part | simple_passthrough WS unorderd_list_part | declaration_statement line_end WS unorderd_list_part | import | function | type_def line_end | adt_def line_end | if_comp | simple_passthrough | declaration_statement line_end ; @@ -125,7 +126,8 @@ expression = expression WS "<<" WS term | expression WS right_shift WS 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 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 ; +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 | cast_expression ; +cast_expression = "\(" WS boolean_expression WS "\)" WS "cast" WS type ; 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 ; @@ -139,7 +141,7 @@ float_end = "(0|1|2|3|4|5|6|7|8|9)+" | "(0|1|2|3|4|5|6|7|8|9)+f" | "(0|1|2|3|4|5 bool = "true" | "false" ; character = "'(`|1|2|3|4|5|6|7|8|9|0|-|=|(\\t)|q|w|e|r|t|y|u|i|o|p|[|]|(\\\\)|a|s|d|f|g|h|j|k|l|;|(\\')|(\\n)|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|\"|Z|X|C|V|B|N|M|<|>|\?| |(\\0))'" ; -keywords_also_identifiers = "obj" | "def" | "fun" | "var" | "ref" | "adt" | "import" | "simple_passthrough" ; +keywords_also_identifiers = "obj" | "def" | "fun" | "var" | "ref" | "adt" | "cast" | "import" | "simple_passthrough" ; alpha_alphanumeric = "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|_)(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|_|0|1|2|3|4|5|6|7|8|9)*" ; augmented_alpha_alphanumeric = alpha_alphanumeric augmented_alpha_alphanumeric | keywords_also_identifiers augmented_alpha_alphanumeric | alpha_alphanumeric | keywords_also_identifiers ; diff --git a/stdlib/ast_nodes.krak b/stdlib/ast_nodes.krak index 7255e26..d58c2b5 100644 --- a/stdlib/ast_nodes.krak +++ b/stdlib/ast_nodes.krak @@ -35,6 +35,7 @@ adt ast_node { if_comp: if_comp, simple_passthrough: simple_passthrough, function_call: function_call, + cast: cast, value: value } /* @@ -960,6 +961,40 @@ obj function_call (Object) { return func == func && parameters == other.parameters } } +fun ast_cast_ptr(value: *ast_node, to_type: *type): *ast_node { + var to_ret.construct(value, to_type): cast + var ptr = new() + ptr->copy_construct(&ast_node::cast(to_ret)) + return ptr +} +fun is_cast(node: *ast_node): bool { + match(*node) { + ast_node::cast(backing) return true + } + return false +} +obj cast (Object) { + var value: *ast_node + var to_type: *type + fun construct(value_in: *ast_node, to_type_in: *type): *cast { + value = value_in + to_type = to_type_in + return this + } + fun copy_construct(old: *cast) { + value = old->value + to_type = old->to_type + } + fun destruct() { + } + fun operator=(other: cast) { + destruct() + copy_construct(&other) + } + fun operator==(other: cast): bool { + return value == other.value && to_type == other.to_type + } +} fun ast_value_ptr(string_value: string, value_type: *type): *ast_node { var to_ret.construct(string_value, value_type): value var ptr = new() @@ -1024,6 +1059,7 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> { ast_node::if_comp(backing) return vector<*ast_node>(backing.statement) ast_node::simple_passthrough(backing) return vector<*ast_node>() ast_node::function_call(backing) return vector(backing.func) + backing.parameters + ast_node::cast(backing) return vector<*ast_node>(backing.value) ast_node::value(backing) return vector<*ast_node>() } } @@ -1051,6 +1087,7 @@ fun get_ast_name(node: *ast_node): string { ast_node::if_comp(backing) return string("if_comp: ") + backing.wanted_generator ast_node::simple_passthrough(backing) return string("simple_passthrough: , string:") + backing.passthrough_str ast_node::function_call(backing) return string("function_call:") + get_ast_name(backing.func) + "(" + backing.parameters.size + ")" + ast_node::cast(backing) return string("cast: ") + get_ast_name(backing.value) + ": " + backing.to_type->to_string() ast_node::value(backing) return string("value: ") + backing.string_value + ": " + backing.value_type->to_string() } return string("impossible adt type") @@ -1079,10 +1116,11 @@ fun get_ast_scope(node: *ast_node): *map> { } fun get_ast_type(node: *ast_node): *type { match (*node) { - ast_node::identifier() return node->identifier.type - ast_node::function() return node->function.type - ast_node::function_call() return get_ast_type(node->function_call.func)->return_type - ast_node::value() return node->value.value_type + ast_node::identifier(backing) return backing.type + ast_node::function(backing) return backing.type + ast_node::function_call(backing) return get_ast_type(backing.func)->return_type + ast_node::cast(backing) return backing.to_type + ast_node::value(backing) return backing.value_type } } diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index 9e50121..6fc84c5 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -460,7 +460,7 @@ obj ast_transformation (Object) { || name == "bool_exp" || name == "expression" || name == "shiftand" || name == "term" || name == "factor" || name == "unarad" - || name == "access_operation" + || name == "access_operation" || name == "cast_expression" ) { // for now, assume passthrough and just transform underneath return transform_expression(node, scope, searching_for, template_replacements) @@ -605,6 +605,8 @@ obj ast_transformation (Object) { if (identifiers.size == 2) { var parameters = get_nodes("parameter", node).map(fun(child: *tree): *ast_node return transform(get_node("boolean_expression", child), scope, template_replacements);) var method = transform(identifiers[1], identifier->identifier.type->type_def, search_type::function(parameters.map(fun(i:*ast_node):*type return get_ast_type(i);)), template_replacements) + if (!method) + error(identifiers[1], "Cannot find method for declaration site method call") declaration->declaration_statement.init_method_call = make_method_call(identifier, method, parameters) } return declaration @@ -885,6 +887,8 @@ obj ast_transformation (Object) { func_name = concat_symbol_tree(node->children[1]) if (func_name == "[") func_name += "]" + if (func_name == "cast") + return ast_cast_ptr(transform(get_node("boolean_expression", node), scope, template_replacements), transform_type(get_node("type", node), scope, template_replacements)) var first_param = transform(node->children[0], scope, template_replacements) var second_param = null() if (func_name == "." || func_name == "->") { diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index 88a899d..168e1bc 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -586,6 +586,11 @@ obj c_generator (Object) { var declaration = ast_declaration_statement_ptr(temp_ident, null()) // have to pass false to the declaration generator, so can't do it through generate_statement to_ret.pre = generate_declaration_statement(declaration, enclosing_object, enclosing_func, defer_stack, false).one_string() + ";\n" + if ((function_return_type->is_object() || temp_ident_type->is_object()) && + ( (!function_return_type->is_ref && !function_return_type->equality(temp_ident_type, false)) || + (function_return_type->is_ref && !function_return_type->equality(temp_ident_type->clone_with_decreased_indirection(), false)) ) ) + // note the clone with decreased indirection because of the clone with increased indirection above + error(string("return type does not match: ") + function_return_type->to_string() + ", " + temp_ident_type->to_string()); if (!function_return_type->is_ref && return_value_type->indirection == 0 && (return_value_type->is_adt() || (return_value_type->is_object() && has_method(return_value_type->type_def, "copy_construct", vector(return_value_type->clone_with_indirection(1)))))) { to_ret.pre += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(return_value))))), enclosing_object, enclosing_func, defer_stack).one_string() } else { @@ -658,6 +663,9 @@ obj c_generator (Object) { }) return to_ret } + fun generate_cast(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, defer_stack: *stack>>, need_variable: bool): code_triple { + return code_triple("(") + type_to_c(node->cast.to_type) + ")(" + generate(node->cast.value, enclosing_object, enclosing_func, defer_stack, false) + ")" + } fun generate_value(node: *ast_node, need_variable: bool): code_triple { var value = node->value.string_value var to_ret = string() @@ -924,6 +932,7 @@ obj c_generator (Object) { ast_node::branching_statement(backing) return generate_branching_statement(node, enclosing_object, enclosing_func, defer_stack) ast_node::defer_statement(backing) return generate_defer_statement(node, enclosing_object, enclosing_func, defer_stack) ast_node::match_statement(backing) return generate_match_statement(node, enclosing_object, enclosing_func, defer_stack) + ast_node::cast(backing) return generate_cast(node, enclosing_object, enclosing_func, defer_stack, need_variable) ast_node::value(backing) return generate_value(node, need_variable) ast_node::identifier(backing) return generate_identifier(node, enclosing_object, enclosing_func) } diff --git a/stdlib/io.krak b/stdlib/io.krak index 96494c5..b2a9a4b 100644 --- a/stdlib/io.krak +++ b/stdlib/io.krak @@ -19,6 +19,7 @@ fun print(toPrint: *T) : void{ __if_comp__ __C__ { simple_passthrough(toPrint = toPrint::) """ printf("%p", (void*)toPrint); + fflush(0); """ } return; @@ -28,6 +29,7 @@ fun print(toPrint: *char) : void { __if_comp__ __C__ { simple_passthrough(toPrint = toPrint::) """ printf("%s", toPrint); + fflush(0); """ } return; @@ -37,6 +39,7 @@ fun print(toPrint: char) : void { __if_comp__ __C__ { simple_passthrough(toPrint = toPrint::) """ printf("%c", toPrint); + fflush(0); """ } return; @@ -60,6 +63,7 @@ fun print(toPrint: int): void { __if_comp__ __C__ { simple_passthrough(toPrint = toPrint::) """ printf("%d", toPrint); + fflush(0); """ } return; @@ -69,6 +73,7 @@ fun print(toPrint: float): void { __if_comp__ __C__ { simple_passthrough(toPrint = toPrint::) """ printf("%f", toPrint); + fflush(0); """ } return; @@ -78,6 +83,7 @@ fun print(toPrint: double) : void{ __if_comp__ __C__ { simple_passthrough(toPrint = toPrint::) """ printf("%f", toPrint); + fflush(0); """ } return; diff --git a/stdlib/type.krak b/stdlib/type.krak index aa8f5cb..81c3e4b 100644 --- a/stdlib/type.krak +++ b/stdlib/type.krak @@ -185,6 +185,7 @@ obj type (Object) { } fun clone(): *type return clone_with_indirection(indirection, is_ref); fun clone_without_ref(): *type return clone_with_indirection(indirection, false); + fun clone_with_ref(): *type return clone_with_indirection(indirection, true); fun clone_with_increased_indirection(): *type return clone_with_indirection(indirection+1); fun clone_with_increased_indirection(more: int, is_ref_in: bool): *type return clone_with_indirection(indirection+more, is_ref_in); fun clone_with_decreased_indirection(): *type return clone_with_indirection(indirection-1); diff --git a/tests/test_conversions.krak b/tests/test_conversions.krak index 8dcc090..56c63b0 100644 --- a/tests/test_conversions.krak +++ b/tests/test_conversions.krak @@ -6,8 +6,10 @@ fun main():int { println(to_int('B')) var a = 1337 - var b = &a - var c = cast_ptr<*int, *char>(b) + var b = &a; + var c = (b) cast *char + + /*var c = cast_ptr<*int, *char>(b)*/ //var d = c + 1 //var e = 1 + c println(to_int(*(c+0)))