Groundwork for primitive operations, including > for ints

This commit is contained in:
Nathan Braswell
2018-09-30 16:06:07 -04:00
parent 9f26472b97
commit 4d5e65e962
3 changed files with 116 additions and 21 deletions

121
k.krak
View File

@@ -88,6 +88,13 @@ fun main(argc: int, argv: **char): int {
var passes = map<str, fun(*tree<ast>): void>() var passes = map<str, fun(*tree<ast>): void>()
var multiple_binding_options = map<*tree<ast>, vec<*tree<ast>>>() var multiple_binding_options = map<*tree<ast>, vec<*tree<ast>>>()
var primitive_ops.construct(): map<str, vec<*tree<ast>>>
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<type>>()))
// resolves all binding possibilities for one top level item // resolves all binding possibilities for one top level item
passes[str("name_possibility_resolve")] = fun(item: *tree<ast>) { passes[str("name_possibility_resolve")] = fun(item: *tree<ast>) {
@@ -128,6 +135,8 @@ fun main(argc: int, argv: **char): int {
} }
if (scope->parent != null<tree<ast>>()) if (scope->parent != null<tree<ast>>())
return to_ret + scope_lookup(scope->parent, name, is_type) 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 return to_ret
} }
var try_binding = fun(binding: *tree<ast>, start_scope: *tree<ast>, type_binding: bool) { var try_binding = fun(binding: *tree<ast>, start_scope: *tree<ast>, type_binding: bool) {
@@ -158,9 +167,12 @@ fun main(argc: int, argv: **char): int {
ast::_identifier(b) handle_type(b.second, t) ast::_identifier(b) handle_type(b.second, t)
/*_binding: triple<str, vec<*type>, *tree<ast>>,*/ /*_binding: triple<str, vec<*type>, *tree<ast>>,*/
ast::_function(b) handle_type(b.second, t) ast::_function(b) handle_type(b.second, t)
ast::_compiler_intrinsic(b) b.second.for_each(fun(tb: *binding<type>) { ast::_compiler_intrinsic(b) {
handle_type(tb, t) /*handle_type(b.second, t)*/
}) b.third.for_each(fun(tb: *binding<type>) {
handle_type(tb, t)
})
}
ast::_cast(b) handle_type(b, t) ast::_cast(b) handle_type(b, t)
/*_value: pair<str, *type>*/ /*_value: pair<str, *type>*/
ast::_binding(b) try_binding(t, t, false) ast::_binding(b) try_binding(t, t, false)
@@ -190,6 +202,7 @@ fun main(argc: int, argv: **char): int {
return new_type return new_type
} }
ast::_function(b) return b.second ast::_function(b) return b.second
ast::_compiler_intrinsic(b) return b.second
ast::_call() { ast::_call() {
var t = get_type(a->children[0]) var t = get_type(a->children[0])
if (t->bound_to->is_fun()) if (t->bound_to->is_fun())
@@ -294,6 +307,72 @@ fun main(argc: int, argv: **char): int {
} }
var taken_names = map<*tree<ast>, str>() var taken_names = map<*tree<ast>, str>()
var id = 0 var id = 0
var replacement_map.construct() : map<str, str>
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<ast>): str { var get_c_name = fun(x: *tree<ast>): str {
if (taken_names.contains_key(x)) if (taken_names.contains_key(x))
return taken_names[x] return taken_names[x]
@@ -308,8 +387,8 @@ fun main(argc: int, argv: **char): int {
if (taken_names.contains_value(possible)) { if (taken_names.contains_value(possible)) {
possible += id++ possible += id++
} }
taken_names[x] = possible taken_names[x] = cify_name(possible)
return possible return taken_names[x]
} }
@@ -425,14 +504,28 @@ fun main(argc: int, argv: **char): int {
ast::_continue() { C_str += idt + "continue"; } ast::_continue() { C_str += idt + "continue"; }
ast::_defer() { error("no defer should remain at C emit"); } ast::_defer() { error("no defer should remain at C emit"); }
ast::_call() { ast::_call() {
emit_C(t->children[0], level) if (is_compiler_intrinsic(get_ast_binding(t->children[0]))) {
C_str += "(" if (t->children.size == 2) {
for (var i = 1; i < t->children.size; i++;) { C_str += idt + "(" + get_ast_binding(t->children[0])->data._compiler_intrinsic.first + "("
if (i != 1) emit_C(t->children[1], 0)
C_str += ", " C_str += "))"
emit_C(t->children[i], 0) } 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::_compiler_intrinsic(b) { error("compiler_intrinsic gen unimplemented"); }
ast::_cast(b) { error("cast gen unimplemented"); } ast::_cast(b) { error("cast gen unimplemented"); }
@@ -525,6 +618,8 @@ fun parse_type(syntax: *tree<symbol>): *binding<type> {
variadic, raw)), indr, is_ref)) variadic, raw)), indr, is_ref))
} else if (first_child_name == "\"void\"") { } else if (first_child_name == "\"void\"") {
return binding(type(base_type::_void(), indr, is_ref)) 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\"") { } else if (first_child_name == "\"char\"") {
return binding(type(base_type::_char(), indr, is_ref)) return binding(type(base_type::_char(), indr, is_ref))
} else if (first_child_name == "\"uchar\"") { } else if (first_child_name == "\"uchar\"") {
@@ -671,7 +766,7 @@ fun syntax_to_ast(file_name: str, syntax: *tree<symbol>, import_paths: ref vec<s
syntax_to_ast_helper(syntax->children[0]))) syntax_to_ast_helper(syntax->children[0])))
} }
} else { } 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[0]),
syntax_to_ast_helper(syntax->children[2]))) syntax_to_ast_helper(syntax->children[2])))
} }

View File

@@ -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 ; 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 ; 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 ; 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 ; 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<A<B>>) right_shift is a nonterminal contructed as follows #Note that to prevent confilct with nested templates (T<A<B>>) right_shift is a nonterminal contructed as follows
right_shift = ">" ">" ; right_shift = ">" ">" ;
overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "\[]" | "\[]=" ; overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | "<" | ">" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "\[]" | "\[]=" ;
func_identifier = identifier | identifier overloadable_operator ; func_identifier = identifier | identifier overloadable_operator ;
# allow omitting of return type (automatic void) # allow omitting of return type (automatic void)

View File

@@ -28,7 +28,7 @@ adt ast {
_continue, _continue,
_defer, _defer,
_call, _call,
_compiler_intrinsic: pair<str, vec<*binding<type>>>, _compiler_intrinsic: triple<str, *binding<type>, vec<*binding<type>>>,
_cast: *binding<type>, _cast: *binding<type>,
_value: pair<str, *binding<type>> _value: pair<str, *binding<type>>
} }
@@ -55,7 +55,7 @@ fun to_string(a: ref ast): str {
ast::_continue() return str("_continue") ast::_continue() return str("_continue")
ast::_defer() return str("_defer") ast::_defer() return str("_defer")
ast::_call() return str("_call") 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::_cast(b) return str("_cast")
ast::_value(b) return str("_value(") + b.first + ": " + deref_to_string(b.second->bound_to) + ")" 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<type>, p3: bool): *tree<ast> {
fun _template(p1: str, p2: set<str>): *tree<ast> { fun _template(p1: str, p2: set<str>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_template(make_pair(p1, p2))) return new<tree<ast>>()->construct(ast::_template(make_pair(p1, p2)))
} }
fun _compiler_intrinsic(p1: str, p2: vec<*binding<type>>): *tree<ast> { fun _compiler_intrinsic(p1: str, p2: *binding<type>, p3: vec<*binding<type>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2))) return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_triple(p1, p2, p3)))
} }
fun _value(p1: str, p2: *binding<type>): *tree<ast> { fun _value(p1: str, p2: *binding<type>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_value(make_pair(p1, p2))) return new<tree<ast>>()->construct(ast::_value(make_pair(p1, p2)))
@@ -162,8 +162,8 @@ fun _function(p1: str, p2: *binding<type>, p3: bool, c: ref vec<*tree<ast>>): *t
fun _template(p1: str, p2: set<str>, c: ref vec<*tree<ast>>): *tree<ast> { fun _template(p1: str, p2: set<str>, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_template(make_pair(p1, p2)), c) return new<tree<ast>>()->construct(ast::_template(make_pair(p1, p2)), c)
} }
fun _compiler_intrinsic(p1: str, p2: vec<*binding<type>>, c: ref vec<*tree<ast>>): *tree<ast> { fun _compiler_intrinsic(p1: str, p2: *binding<type>, p3: vec<*binding<type>>, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)), c) return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_triple(p1, p2, p3)), c)
} }
fun _value(p1: str, p2: *binding<type>, c: ref vec<*tree<ast>>): *tree<ast> { fun _value(p1: str, p2: *binding<type>, c: ref vec<*tree<ast>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_value(make_pair(p1, p2)), c) return new<tree<ast>>()->construct(ast::_value(make_pair(p1, p2)), c)