From 4d5e65e962ea17c2d2f7519b6097c2dd02f7f157 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sun, 30 Sep 2018 16:06:07 -0400 Subject: [PATCH] Groundwork for primitive operations, including > for ints --- k.krak | 121 +++++++++++++++++++++++++++++++++++++++++----- krakenGrammer.kgm | 4 +- stdlib/ast.krak | 12 ++--- 3 files changed, 116 insertions(+), 21 deletions(-) diff --git a/k.krak b/k.krak index 595acda..6c8d078 100644 --- a/k.krak +++ b/k.krak @@ -88,6 +88,13 @@ fun main(argc: int, argv: **char): int { var passes = map): void>() var multiple_binding_options = map<*tree, vec<*tree>>() + var primitive_ops.construct(): map>> + primitive_ops[str("op>")] = vec(_compiler_intrinsic(str(">"), binding(type(base_type::_fun(make_triple(make_pair(vec( + binding(type(base_type::_int(), 0, false)), + binding(type(base_type::_int(), 0, false)) + ), + binding(type(base_type::_bool(), 0, false)) + ), false, false)), 0, false)), vec<*binding>())) // resolves all binding possibilities for one top level item passes[str("name_possibility_resolve")] = fun(item: *tree) { @@ -128,6 +135,8 @@ fun main(argc: int, argv: **char): int { } if (scope->parent != null>()) return to_ret + scope_lookup(scope->parent, name, is_type) + else if (primitive_ops.contains_key(name)) + to_ret += primitive_ops[name] return to_ret } var try_binding = fun(binding: *tree, start_scope: *tree, type_binding: bool) { @@ -158,9 +167,12 @@ fun main(argc: int, argv: **char): int { ast::_identifier(b) handle_type(b.second, t) /*_binding: triple, *tree>,*/ ast::_function(b) handle_type(b.second, t) - ast::_compiler_intrinsic(b) b.second.for_each(fun(tb: *binding) { - handle_type(tb, t) - }) + ast::_compiler_intrinsic(b) { + /*handle_type(b.second, t)*/ + b.third.for_each(fun(tb: *binding) { + handle_type(tb, t) + }) + } ast::_cast(b) handle_type(b, t) /*_value: pair*/ ast::_binding(b) try_binding(t, t, false) @@ -190,6 +202,7 @@ fun main(argc: int, argv: **char): int { return new_type } ast::_function(b) return b.second + ast::_compiler_intrinsic(b) return b.second ast::_call() { var t = get_type(a->children[0]) if (t->bound_to->is_fun()) @@ -294,6 +307,72 @@ fun main(argc: int, argv: **char): int { } var taken_names = map<*tree, str>() var id = 0 + + var replacement_map.construct() : map + replacement_map[str("+")] = str("plus") + replacement_map[str("-")] = str("minus") + replacement_map[str("*")] = str("star") + replacement_map[str("/")] = str("div") + replacement_map[str("%")] = str("mod") + replacement_map[str("^")] = str("carat") + replacement_map[str("&")] = str("amprsd") + replacement_map[str("|")] = str("pipe") + replacement_map[str("~")] = str("tilde") + replacement_map[str("!")] = str("exlmtnpt") + replacement_map[str(",")] = str("comma") + replacement_map[str("=")] = str("eq") + replacement_map[str("++")] = str("dbplus") + replacement_map[str("--")] = str("dbminus") + replacement_map[str("<<")] = str("dbleft") + replacement_map[str(">>")] = str("dbright") + replacement_map[str("::")] = str("scopeop") + replacement_map[str(":")] = str("colon") + replacement_map[str("==")] = str("dbq") + replacement_map[str("!=")] = str("notequals") + replacement_map[str("&&")] = str("doubleamprsnd") + replacement_map[str("||")] = str("doublepipe") + replacement_map[str("+=")] = str("plusequals") + replacement_map[str("-=")] = str("minusequals") + replacement_map[str("/=")] = str("divequals") + replacement_map[str("%=")] = str("modequals") + replacement_map[str("^=")] = str("caratequals") + replacement_map[str("&=")] = str("amprsdequals") + replacement_map[str("|=")] = str("pipeequals") + replacement_map[str("*=")] = str("starequals") + replacement_map[str("<<=")] = str("doublerightequals") + replacement_map[str("<")] = str("lt") + replacement_map[str(">")] = str("gt") + replacement_map[str(">>=")] = str("doubleleftequals") + replacement_map[str("(")] = str("openparen") + replacement_map[str(")")] = str("closeparen") + replacement_map[str("[")] = str("obk") + replacement_map[str("]")] = str("cbk") + replacement_map[str(" ")] = str("_") + replacement_map[str(".")] = str("dot") + replacement_map[str("->")] = str("arrow") + + var longest_replacement = 0 + replacement_map.for_each(fun(key: str, value: str) { + if (key.length() > longest_replacement) + longest_replacement = key.length() + }) + var cify_name = fun(name: ref str): str { + var to_ret = str() + for (var i = 0; i < name.length(); i++;) { + var replaced = false + for (var j = longest_replacement; j > 0; j--;) { + if (i + j <= name.length() && replacement_map.contains_key(name.slice(i,i+j))) { + to_ret += replacement_map[name.slice(i,i+j)] + replaced = true + i += j-1; + break + } + } + if (!replaced) + to_ret += name[i] + } + return to_ret + } var get_c_name = fun(x: *tree): str { if (taken_names.contains_key(x)) return taken_names[x] @@ -308,8 +387,8 @@ fun main(argc: int, argv: **char): int { if (taken_names.contains_value(possible)) { possible += id++ } - taken_names[x] = possible - return possible + taken_names[x] = cify_name(possible) + return taken_names[x] } @@ -425,14 +504,28 @@ fun main(argc: int, argv: **char): int { ast::_continue() { C_str += idt + "continue"; } ast::_defer() { error("no defer should remain at C emit"); } ast::_call() { - emit_C(t->children[0], level) - C_str += "(" - for (var i = 1; i < t->children.size; i++;) { - if (i != 1) - C_str += ", " - emit_C(t->children[i], 0) + if (is_compiler_intrinsic(get_ast_binding(t->children[0]))) { + if (t->children.size == 2) { + C_str += idt + "(" + get_ast_binding(t->children[0])->data._compiler_intrinsic.first + "(" + emit_C(t->children[1], 0) + C_str += "))" + } else if (t->children.size == 3) { + C_str += idt + "((" + emit_C(t->children[1], 0) + C_str += ")" + get_ast_binding(t->children[0])->data._compiler_intrinsic.first + "(" + emit_C(t->children[2], 0) + C_str += "))" + } else error("Calling primitive intrinsic with not 1 or 2 arguments") + } else { + emit_C(t->children[0], level) + C_str += "(" + for (var i = 1; i < t->children.size; i++;) { + if (i != 1) + C_str += ", " + emit_C(t->children[i], 0) + } + C_str += ")" } - C_str += ")" } ast::_compiler_intrinsic(b) { error("compiler_intrinsic gen unimplemented"); } ast::_cast(b) { error("cast gen unimplemented"); } @@ -525,6 +618,8 @@ fun parse_type(syntax: *tree): *binding { variadic, raw)), indr, is_ref)) } else if (first_child_name == "\"void\"") { return binding(type(base_type::_void(), indr, is_ref)) + } else if (first_child_name == "\"bool\"") { + return binding(type(base_type::_bool(), indr, is_ref)) } else if (first_child_name == "\"char\"") { return binding(type(base_type::_char(), indr, is_ref)) } else if (first_child_name == "\"uchar\"") { @@ -671,7 +766,7 @@ fun syntax_to_ast(file_name: str, syntax: *tree, import_paths: ref vecchildren[0]))) } } else { - return _call(vec(make_ast_binding(concat(syntax->children[1])), + return _call(vec(make_ast_binding("op" + concat(syntax->children[1])), syntax_to_ast_helper(syntax->children[0]), syntax_to_ast_helper(syntax->children[2]))) } diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index c534855..2b47d21 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -4,7 +4,7 @@ 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 | compiler_intrinsic line_end WS unorderd_list_part | import | function | type_def line_end | adt_def line_end | if_comp | simple_passthrough | declaration_statement line_end | compiler_intrinsic line_end ; type = "ref" WS pre_reffed | pre_reffed ; -pre_reffed = "\*" WS pre_reffed | "void" | "char" | "uchar" | "short" | "ushort" | "int" | "uint" | "long" | "ulong" | "float" | "double" | scoped_identifier | scoped_identifier WS template_inst | function_type ; +pre_reffed = "\*" WS pre_reffed | "void" | "bool" | "char" | "uchar" | "short" | "ushort" | "int" | "uint" | "long" | "ulong" | "float" | "double" | scoped_identifier | scoped_identifier WS template_inst | function_type ; function_type = "fun" WS "\(" WS opt_type_list WS "\)" WS ":" WS type | "run" WS "\(" WS opt_type_list WS "\)" WS ":" WS type ; dec_type = ":" WS type ; @@ -66,7 +66,7 @@ scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ; #Note that to prevent confilct with nested templates (T>) right_shift is a nonterminal contructed as follows right_shift = ">" ">" ; -overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "\[]" | "\[]=" ; +overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | "<" | ">" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "\[]" | "\[]=" ; func_identifier = identifier | identifier overloadable_operator ; # allow omitting of return type (automatic void) diff --git a/stdlib/ast.krak b/stdlib/ast.krak index 8b4ff72..780a9dd 100644 --- a/stdlib/ast.krak +++ b/stdlib/ast.krak @@ -28,7 +28,7 @@ adt ast { _continue, _defer, _call, - _compiler_intrinsic: pair>>, + _compiler_intrinsic: triple, vec<*binding>>, _cast: *binding, _value: pair> } @@ -55,7 +55,7 @@ fun to_string(a: ref ast): str { ast::_continue() return str("_continue") ast::_defer() return str("_defer") ast::_call() return str("_call") - ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ")" + ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ": " + deref_to_string(b.second->bound_to) + ")" ast::_cast(b) return str("_cast") ast::_value(b) return str("_value(") + b.first + ": " + deref_to_string(b.second->bound_to) + ")" } @@ -87,8 +87,8 @@ fun _function(p1: str, p2: *binding, p3: bool): *tree { fun _template(p1: str, p2: set): *tree { return new>()->construct(ast::_template(make_pair(p1, p2))) } -fun _compiler_intrinsic(p1: str, p2: vec<*binding>): *tree { - return new>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2))) +fun _compiler_intrinsic(p1: str, p2: *binding, p3: vec<*binding>): *tree { + return new>()->construct(ast::_compiler_intrinsic(make_triple(p1, p2, p3))) } fun _value(p1: str, p2: *binding): *tree { return new>()->construct(ast::_value(make_pair(p1, p2))) @@ -162,8 +162,8 @@ fun _function(p1: str, p2: *binding, p3: bool, c: ref vec<*tree>): *t fun _template(p1: str, p2: set, c: ref vec<*tree>): *tree { return new>()->construct(ast::_template(make_pair(p1, p2)), c) } -fun _compiler_intrinsic(p1: str, p2: vec<*binding>, c: ref vec<*tree>): *tree { - return new>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)), c) +fun _compiler_intrinsic(p1: str, p2: *binding, p3: vec<*binding>, c: ref vec<*tree>): *tree { + return new>()->construct(ast::_compiler_intrinsic(make_triple(p1, p2, p3)), c) } fun _value(p1: str, p2: *binding, c: ref vec<*tree>): *tree { return new>()->construct(ast::_value(make_pair(p1, p2)), c)