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 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
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>>())
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<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)
/*_binding: triple<str, vec<*type>, *tree<ast>>,*/
ast::_function(b) handle_type(b.second, t)
ast::_compiler_intrinsic(b) b.second.for_each(fun(tb: *binding<type>) {
handle_type(tb, t)
})
ast::_compiler_intrinsic(b) {
/*handle_type(b.second, t)*/
b.third.for_each(fun(tb: *binding<type>) {
handle_type(tb, t)
})
}
ast::_cast(b) handle_type(b, t)
/*_value: pair<str, *type>*/
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<ast>, str>()
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 {
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<symbol>): *binding<type> {
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<symbol>, import_paths: ref vec<s
syntax_to_ast_helper(syntax->children[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])))
}

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 ;
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<A<B>>) 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)

View File

@@ -28,7 +28,7 @@ adt ast {
_continue,
_defer,
_call,
_compiler_intrinsic: pair<str, vec<*binding<type>>>,
_compiler_intrinsic: triple<str, *binding<type>, vec<*binding<type>>>,
_cast: *binding<type>,
_value: pair<str, *binding<type>>
}
@@ -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<type>, p3: bool): *tree<ast> {
fun _template(p1: str, p2: set<str>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_template(make_pair(p1, p2)))
}
fun _compiler_intrinsic(p1: str, p2: vec<*binding<type>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)))
fun _compiler_intrinsic(p1: str, p2: *binding<type>, p3: vec<*binding<type>>): *tree<ast> {
return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_triple(p1, p2, p3)))
}
fun _value(p1: str, p2: *binding<type>): *tree<ast> {
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> {
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> {
return new<tree<ast>>()->construct(ast::_compiler_intrinsic(make_pair(p1, p2)), c)
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_triple(p1, p2, p3)), c)
}
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)