From ed01b5f5806e096f44b013938a256f3350db6fc9 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Tue, 14 Apr 2020 23:34:23 -0400 Subject: [PATCH] Parameterless functions working --- bf.kp | 7 +- k_prime.krak | 184 +++++++++++++++++++++++++++------------------------ 2 files changed, 105 insertions(+), 86 deletions(-) diff --git a/bf.kp b/bf.kp index 7122960..b241070 100644 --- a/bf.kp +++ b/bf.kp @@ -54,6 +54,11 @@ ;(def! main (fn* [] (if false 1 2))) ;(def! main (fn* [] (+ 13 1))) ;(def! main (fn* [] (- 13 -1))) -(def! main (fn* [] (- 13 -1))) +;(def! main (fn* [] (- 13 -1))) ;(def! main (fn* [] (+ 13 -))) ;(def! main (fn* [] (+ 13 1 2))) +;(def! main (fn* [] (cond false 1 false 2 true 3 true 4 false 5))) +;(def! main (fn* [] ((fn* [] (+ (+ 1 2) 3)) 13 1 2))) +(def! main (fn* [] (((fn* [] (fn* [] 1)))))) + +;(def! main (fn* [] ((fn* [a b c] (- (+ a b) c)) 13 1 2))) diff --git a/k_prime.krak b/k_prime.krak index 7a13499..308175c 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -1394,64 +1394,64 @@ fun main(argc: int, argv: **char): int { println("Starting compile!") match (get_value(main)) { MalValue::Function(f) { - var main_s = str("#include \n#include \n#include \n") - main_s += "void error(char* message) {fprintf(stderr, \"%s\", message); exit(1);}\n" - main_s += "void check_num_params(size_t a, size_t b, char* function) { if (a!=b) {fprintf(stderr, \"%s: expected num params to be %d\\n\", function, b); exit(1);}}\n" - main_s += "void check_int(size_t p, char* function) { if ((p&0x7)!=0) {fprintf(stderr, \"%s: expected param to be int\\n\", function); exit(1);}}\n" - main_s += "void check_function(size_t p, char* message) { if ((p&0x7)!=0x6) {fprintf(stderr, \"%s: expected a function\\n\", message); exit(1);}}\n" - main_s += "typedef struct {\n" - main_s += "size_t (*func)(size_t*,size_t,size_t*);\n" - main_s += "size_t* data;\n" - main_s += "} closure;\n" - main_s += "size_t _plus_impl(size_t* _, size_t num, size_t* args) {\n" - main_s += "check_num_params(num, 2, \"+\"); check_int(args[0], \"+\"); check_int(args[1], \"+\");" - main_s += " return (size_t)(((((ptrdiff_t)args[0]) >> 3) + (((ptrdiff_t)args[1]) >> 3)) << 3);\n" - main_s += "}\n" - main_s += "closure _plus_closure = { _plus_impl, NULL};\n" - main_s += "size_t _minus_impl(size_t* _, size_t num, size_t* args) {\n" - main_s += "check_num_params(num, 2, \"-\"); check_int(args[0], \"-\"); check_int(args[1], \"-\");" - main_s += " return (size_t)(((((ptrdiff_t)args[0]) >> 3) - (((ptrdiff_t)args[1]) >> 3)) << 3);\n" - main_s += "}\n" - main_s += "closure _minus_closure =(closure){ _minus_impl, NULL};\n" - main_s += "size_t _mult_impl(size_t* _, size_t num, size_t* args) {\n" - main_s += "check_num_params(num, 2, \"*\"); check_int(args[0], \"*\"); check_int(args[1], \"*\");" - main_s += " return (size_t)(((((ptrdiff_t)args[0]) >> 3) * (((ptrdiff_t)args[1]) >> 3)) << 3);\n" - main_s += "}\n" - main_s += "closure _mult_closure = (closure){ _mult_impl, NULL};\n" - main_s += "size_t _div_impl(size_t* _, size_t num, size_t* args) {\n" - main_s += "check_num_params(num, 2, \"/\"); check_int(args[0], \"/\"); check_int(args[1], \"/\");" - main_s += " return (size_t)(((((ptrdiff_t)args[0]) >> 3) / (((ptrdiff_t)args[1]) >> 3)) << 3);\n" - main_s += "}\n" - main_s += "closure _div_closure = (closure){ _div_impl, NULL};\n" - main_s += "size_t _eq_impl(size_t* _, size_t num, size_t* args) {\n" - main_s += "check_num_params(num, 2, \"=\");" - main_s += "if (args[0] == args[1]) { return 0x9F; } else { return 0x1F; }\n" - main_s += "}\n" - main_s += "closure _eq_closure = (closure){ _eq_impl, NULL};\n" - main_s += "size_t _lt_impl(size_t* _, size_t num, size_t* args) {\n" - main_s += "check_num_params(num, 2, \"<\"); check_int(args[0], \"<\"); check_int(args[1], \"<\");" - main_s += "if (args[0] < args[1]) { return 0x9F; } else { return 0x1F; }\n" - main_s += "}\n" - main_s += "closure _lt_closure = (closure){ _lt_impl, NULL};\n" - main_s += "size_t _lte_impl(size_t* _, size_t num, size_t* args) {\n" - main_s += "check_num_params(num, 2, \"<=\"); check_int(args[0], \"<=\"); check_int(args[1], \"<=\");" - main_s += "if (args[0] <= args[1]) { return 0x9F; } else { return 0x1F; }\n" - main_s += "}\n" - main_s += "closure _lte_closure = (closure){ _lte_impl, NULL};\n" - main_s += "size_t _gt_impl(size_t* _, size_t num, size_t* args) {\n" - main_s += "check_num_params(num, 2, \">\"); check_int(args[0], \">\"); check_int(args[1], \">\");" - main_s += "if (args[0] > args[1]) { return 0x9F; } else { return 0x1F; }\n" - main_s += "}\n" - main_s += "closure _gt_closure = (closure){ _gt_impl, NULL};\n" - main_s += "size_t _gte_impl(size_t* _, size_t num, size_t* args) {\n" - main_s += "check_num_params(num, 2, \">=\"); check_int(args[0], \">=\"); check_int(args[1], \">=\");" - main_s += "if (args[0] >= args[1]) { return 0x9F; } else { return 0x1F; }\n" - main_s += "}\n" - main_s += "closure _gte_closure = (closure){ _gte_impl, NULL};\n" - main_s += "int main(int argc, char** argv) {\n" - var inner_main = compile(&main_s, env, *f.body) + var top_decs = str("#include \n#include \n#include \n") + top_decs += "void error(char* message) {fprintf(stderr, \"%s\", message); exit(1);}\n" + top_decs += "void check_num_params(size_t a, size_t b, char* function) { if (a!=b) {fprintf(stderr, \"%s: expected num params to be %d\\n\", function, b); exit(1);}}\n" + top_decs += "void check_int(size_t p, char* function) { if ((p&0x7)!=0) {fprintf(stderr, \"%s: expected param to be int\\n\", function); exit(1);}}\n" + top_decs += "void check_function(size_t p, char* message) { if ((p&0x7)!=0x6) {fprintf(stderr, \"%s: expected a function\\n\", message); exit(1);}}\n" + top_decs += "typedef struct {\n" + top_decs += "size_t (*func)(size_t*,size_t,size_t*);\n" + top_decs += "size_t* data;\n" + top_decs += "} closure;\n" + top_decs += "size_t _plus_impl(size_t* _, size_t num, size_t* args) {\n" + top_decs += "check_num_params(num, 2, \"+\"); check_int(args[0], \"+\"); check_int(args[1], \"+\");" + top_decs += " return (size_t)(((((ptrdiff_t)args[0]) >> 3) + (((ptrdiff_t)args[1]) >> 3)) << 3);\n" + top_decs += "}\n" + var top_defs = str("closure _plus_closure = { _plus_impl, NULL};\n") + top_defs += "size_t _minus_impl(size_t* _, size_t num, size_t* args) {\n" + top_defs += "check_num_params(num, 2, \"-\"); check_int(args[0], \"-\"); check_int(args[1], \"-\");" + top_defs += " return (size_t)(((((ptrdiff_t)args[0]) >> 3) - (((ptrdiff_t)args[1]) >> 3)) << 3);\n" + top_defs += "}\n" + top_defs += "closure _minus_closure =(closure){ _minus_impl, NULL};\n" + top_defs += "size_t _mult_impl(size_t* _, size_t num, size_t* args) {\n" + top_defs += "check_num_params(num, 2, \"*\"); check_int(args[0], \"*\"); check_int(args[1], \"*\");" + top_defs += " return (size_t)(((((ptrdiff_t)args[0]) >> 3) * (((ptrdiff_t)args[1]) >> 3)) << 3);\n" + top_defs += "}\n" + top_defs += "closure _mult_closure = (closure){ _mult_impl, NULL};\n" + top_defs += "size_t _div_impl(size_t* _, size_t num, size_t* args) {\n" + top_defs += "check_num_params(num, 2, \"/\"); check_int(args[0], \"/\"); check_int(args[1], \"/\");" + top_defs += " return (size_t)(((((ptrdiff_t)args[0]) >> 3) / (((ptrdiff_t)args[1]) >> 3)) << 3);\n" + top_defs += "}\n" + top_defs += "closure _div_closure = (closure){ _div_impl, NULL};\n" + top_defs += "size_t _eq_impl(size_t* _, size_t num, size_t* args) {\n" + top_defs += "check_num_params(num, 2, \"=\");" + top_defs += "if (args[0] == args[1]) { return 0x9F; } else { return 0x1F; }\n" + top_defs += "}\n" + top_defs += "closure _eq_closure = (closure){ _eq_impl, NULL};\n" + top_defs += "size_t _lt_impl(size_t* _, size_t num, size_t* args) {\n" + top_defs += "check_num_params(num, 2, \"<\"); check_int(args[0], \"<\"); check_int(args[1], \"<\");" + top_defs += "if (args[0] < args[1]) { return 0x9F; } else { return 0x1F; }\n" + top_defs += "}\n" + top_defs += "closure _lt_closure = (closure){ _lt_impl, NULL};\n" + top_defs += "size_t _lte_impl(size_t* _, size_t num, size_t* args) {\n" + top_defs += "check_num_params(num, 2, \"<=\"); check_int(args[0], \"<=\"); check_int(args[1], \"<=\");" + top_defs += "if (args[0] <= args[1]) { return 0x9F; } else { return 0x1F; }\n" + top_defs += "}\n" + top_defs += "closure _lte_closure = (closure){ _lte_impl, NULL};\n" + top_defs += "size_t _gt_impl(size_t* _, size_t num, size_t* args) {\n" + top_defs += "check_num_params(num, 2, \">\"); check_int(args[0], \">\"); check_int(args[1], \">\");" + top_defs += "if (args[0] > args[1]) { return 0x9F; } else { return 0x1F; }\n" + top_defs += "}\n" + top_defs += "closure _gt_closure = (closure){ _gt_impl, NULL};\n" + top_defs += "size_t _gte_impl(size_t* _, size_t num, size_t* args) {\n" + top_defs += "check_num_params(num, 2, \">=\"); check_int(args[0], \">=\"); check_int(args[1], \">=\");" + top_defs += "if (args[0] >= args[1]) { return 0x9F; } else { return 0x1F; }\n" + top_defs += "}\n" + top_defs += "closure _gte_closure = (closure){ _gte_impl, NULL};\n" + var main_s = str("int main(int argc, char** argv) {\n") + var inner_main = compile(&top_decs, &top_defs, &main_s, f.env, *f.body) main_s += "return (" + inner_main + ")>>3;\n}\n" - write_file(str(argv[1]) + ".c", main_s) + write_file(str(argv[1]) + ".c", top_decs + top_defs + main_s) println("Finished compile") return 0 } @@ -1471,10 +1471,15 @@ fun main(argc: int, argv: **char): int { } } } - -fun compile_value(defs: *str, env: *Env, ast: MalValue): str { +var tmp_idx: int = 0 +fun new_tmp(): str { + tmp_idx += 1 + return str("x") + tmp_idx +} +fun compile_value(top_decs: *str, top_defs: *str, defs: *str, env: *Env, ast: MalValue): str { match (ast) { - /*MalValue::List(l) {*/ + MalValue::List(l) { + error("could not compile list: " + pr_str(ast, true)) /*var to_ret = vec()*/ /*for (var i = 0; i < l.size; i++;) {*/ /*var mid = EVAL(env, l[i])*/ @@ -1484,8 +1489,9 @@ fun compile_value(defs: *str, env: *Env, ast: MalValue): str { /*to_ret.add(get_value(mid))*/ /*}*/ /*return MalResult::Ok(MalValue::List(to_ret))*/ - /*}*/ - /*MalValue::Vector(l) {*/ + } + MalValue::Vector(l) { + error("could not compile vector: " + pr_str(ast, true)) /*var to_ret = vec()*/ /*for (var i = 0; i < l.size; i++;) {*/ /*var mid = EVAL(env, l[i])*/ @@ -1495,7 +1501,7 @@ fun compile_value(defs: *str, env: *Env, ast: MalValue): str { /*to_ret.add(get_value(mid))*/ /*}*/ /*return MalResult::Ok(MalValue::Vector(to_ret))*/ - /*}*/ + } MalValue::Symbol(s) { /*return env->get(s)*/ if (s == "+") { @@ -1535,24 +1541,19 @@ fun compile_value(defs: *str, env: *Env, ast: MalValue): str { } error("could not compile value: " + pr_str(ast, true)) } -var tmp_idx: int = 0 -fun new_tmp(): str { - tmp_idx += 1 - return str("x") + tmp_idx -} -fun compile(defs: *str, env: *Env, ast: MalValue): str { +fun compile(top_decs: *str, top_defs: *str, defs: *str, env: *Env, ast: MalValue): str { var expanded = macroexpand(ast, env) if (is_err(expanded)) { error("compile error in macroexpand: " + pr_str(get_err(expanded), true)) } ast = get_value(expanded) if !is_list(ast) { - return compile_value(defs, env, ast) + return compile_value(top_decs, top_defs, defs, env, ast) } match (ast) { MalValue::List(l) { if (l.size == 0) { - return compile_value(defs, env, ast) + return compile_value(top_decs, top_defs, defs, env, ast) } else if (is_symbol(l[0], "def!")) { if (l.size != 3) { error("def! without exaclty key and value") @@ -1561,7 +1562,7 @@ fun compile(defs: *str, env: *Env, ast: MalValue): str { error("def! not on symbol") } var to_set_name = get_symbol_text(l[1]) - var to_set_value = compile(defs, env, l[2]) + var to_set_value = compile(top_decs, top_defs, defs, env, l[2]) *defs += "size_t " + to_set_name + " = " + to_set_value + ";\n" return to_set_name } else if (is_symbol(l[0], "defmacro!")) { @@ -1584,30 +1585,43 @@ fun compile(defs: *str, env: *Env, ast: MalValue): str { if (!is_symbol(bindings[i])) { error("let* var name not symbol") } - var to_set_value = compile(defs, new_env, bindings[i+1]) + var to_set_value = compile(top_decs, top_defs, defs, new_env, bindings[i+1]) *defs += "size_t " + get_symbol_text(bindings[i]) + " = " + to_set_value + ";\n" } - *defs += let_val + " = " + compile(defs, new_env, l[2]) + ";\n}\n" + *defs += let_val + " = " + compile(top_decs, top_defs, defs, new_env, l[2]) + ";\n}\n" return let_val } else if (is_symbol(l[0], "do")) { for (var i = 1; i < l.size-1; i++;) { - var _ = compile(defs, env, l[i]) + var _ = compile(top_decs, top_defs, defs, env, l[i]) *defs += ";\n" } - return compile(defs, env, l[l.size-1]) + return compile(top_decs, top_defs, defs, env, l[l.size-1]) } else if (is_symbol(l[0], "if")) { if l.size != 3 && l.size != 4 { error("if needs 2 or 3 children") } - var cond = compile(defs, env, l[1]) + var cond = compile(top_decs, top_defs, defs, env, l[1]) var tmp_name = new_tmp() *defs += "size_t " + tmp_name + "; if (" + cond + " != 0x1F) {\n" - var then = compile(defs, env, l[2]) + var then = compile(top_decs, top_defs, defs, env, l[2]) *defs += tmp_name + " = " + then + ";\n} else {\n" - var else_ = compile(defs, env, l[3]) + var else_ = compile(top_decs, top_defs, defs, env, l[3]) *defs += tmp_name + " = " + else_ + ";\n}\n" return tmp_name } else if (is_symbol(l[0], "fn*")) { + + var fun_name = "fun_" + new_tmp() + *top_decs += "size_t " + fun_name + "(size_t*, size_t, size_t*);\n" + var function = "size_t " + fun_name + "(size_t* _, size_t num, size_t* args) {\n" + /*var inner_value = compile(top_decs, top_defs, &function, f.env, *f.body)*/ + var inner_value = compile(top_decs, top_defs, &function, env, l[2]) + function += "return " + inner_value + ";\n}\n" + *top_defs += function + *defs += "closure* " + fun_name + "_closure = malloc(sizeof(closure));\n" + *defs += fun_name + "_closure->func = " + fun_name + ";\n" + *defs += fun_name + "_closure->data = NULL;\n" + return "((((size_t)"+fun_name+"_closure)<<3)|0x6)" + error("compile fn* unimplemented") /*if l.size != 3 {*/ /*return MalResult::Err(MalValue::String(str("fn* needs 2 children")))*/ @@ -1642,12 +1656,12 @@ fun compile(defs: *str, env: *Env, ast: MalValue): str { if l.size == 1 { error("compile quote with no arguments") } - return compile_value(defs, env, l[1]) + return compile_value(top_decs, top_defs, defs, env, l[1]) } else if (is_symbol(l[0], "quasiquote")) { if l.size == 1 { error("compile quasiquote with no arguments") } - return compile(defs, env, quasiquote(l[1])) + return compile(top_decs, top_defs, defs, env, quasiquote(l[1])) } else if (is_symbol(l[0], "macroexpand")) { error("macroexpand doesn't make sense while compiling") } else if (is_symbol(l[0], "try*")) { @@ -1670,17 +1684,17 @@ fun compile(defs: *str, env: *Env, ast: MalValue): str { } else { var to_call = vec() for (var i = 0; i < l.size; i++;) { - to_call.add(compile_value(defs, env, l[i])) + to_call.add(compile(top_decs, top_defs, defs, env, l[i])) } var func_name = new_tmp() *defs += "size_t " + func_name + "_r = " + to_call[0] + ";\n" *defs += "check_function(" + func_name + "_r, \"trying to call\");"; *defs += "closure* " + func_name + " = (closure*)(" + func_name + "_r>>3);\n" var params_name = new_tmp() - *defs += "size_t " + params_name + "[] = {"+str(", ").join(to_call.slice(1,-1))+"};\n" - return func_name + "->func(" + func_name + "->data, " + to_string(l.size-1) + ", " + params_name + ")" + *defs += "size_t " + params_name + "_params[] = {"+str(", ").join(to_call.slice(1,-1))+"};\n" + return func_name + "->func(" + func_name + "->data, " + to_string(l.size-1) + ", " + params_name + "_params)" } } } - return compile_value(defs, env, ast) + return compile_value(top_decs, top_defs, defs, env, ast) }