Parameterless functions working

This commit is contained in:
Nathan Braswell
2020-04-14 23:34:23 -04:00
parent 8da9190b3d
commit ed01b5f580
2 changed files with 105 additions and 86 deletions

7
bf.kp
View File

@@ -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)))

View File

@@ -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)
}