Parameterless functions working
This commit is contained in:
7
bf.kp
7
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)))
|
||||
|
||||
184
k_prime.krak
184
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 <stdlib.h>\n#include <stdio.h>\n#include <stddef.h>\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 <stdlib.h>\n#include <stdio.h>\n#include <stddef.h>\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<MalValue>()*/
|
||||
/*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<MalValue>()*/
|
||||
/*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<str>()
|
||||
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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user