throw and catch implemented
This commit is contained in:
26
bf.kp
26
bf.kp
@@ -100,13 +100,25 @@
|
|||||||
; (println (deref it))
|
; (println (deref it))
|
||||||
; (deref it)
|
; (deref it)
|
||||||
; ))))
|
; ))))
|
||||||
(def! my_atom (atom 5))
|
;(def! my_atom (atom 5))
|
||||||
(def! main (fn* [] (do
|
;(def! main (fn* [] (do
|
||||||
(println my_atom)
|
; (println my_atom)
|
||||||
(println (deref my_atom))
|
; (println (deref my_atom))
|
||||||
(reset! my_atom 1337)
|
; (reset! my_atom 1337)
|
||||||
(println my_atom)
|
; (println my_atom)
|
||||||
(println (deref my_atom))
|
; (println (deref my_atom))
|
||||||
|
; 7)))
|
||||||
|
|
||||||
|
|
||||||
|
;(def! inner (fn* [x] (do (throw (+ x 1)) (+ x 2))))
|
||||||
|
(def! inner (fn* [x] (do (println 7) (+ x 2))))
|
||||||
|
;(def! main (fn* [] (do (println (try*
|
||||||
|
; (inner 7)
|
||||||
|
; (catch* exp (+ exp 10))))
|
||||||
|
; 7)))
|
||||||
|
(def! main (fn* [] (do (println (try*
|
||||||
|
(inner 7)))
|
||||||
7)))
|
7)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
57
k_prime.krak
57
k_prime.krak
@@ -1414,8 +1414,11 @@ fun main(argc: int, argv: **char): int {
|
|||||||
println("Starting compile!")
|
println("Starting compile!")
|
||||||
match (get_value(main)) {
|
match (get_value(main)) {
|
||||||
MalValue::Function(f) {
|
MalValue::Function(f) {
|
||||||
var top_decs = str("#include <stdlib.h>\n#include <stdio.h>\n#include <stddef.h>\n#include <string.h>\n")
|
var top_decs = str("#include <stdlib.h>\n#include <stdio.h>\n#include <stddef.h>\n#include <string.h>\n#include <setjmp.h>\n")
|
||||||
top_decs += """void error(char* message) {fprintf(stderr, "%s", message); exit(1);}
|
top_decs += """
|
||||||
|
jmp_buf *current_exception_handler;
|
||||||
|
size_t current_exception_value;
|
||||||
|
void error(char* message) {fprintf(stderr, "%s", message); exit(1);}
|
||||||
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);}}
|
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);}}
|
||||||
void check_int(size_t p, char* function) { if ((p&0x7)!=0) {fprintf(stderr, "%s: expected param to be int\n", function); exit(1);}}
|
void check_int(size_t p, char* function) { if ((p&0x7)!=0) {fprintf(stderr, "%s: expected param to be int\n", function); exit(1);}}
|
||||||
void check_function(size_t p, char* message) { if ((p&0x7)!=0x6) {fprintf(stderr, "%s: expected a function\n", message); exit(1);}}
|
void check_function(size_t p, char* message) { if ((p&0x7)!=0x6) {fprintf(stderr, "%s: expected a function\n", message); exit(1);}}
|
||||||
@@ -1587,6 +1590,13 @@ fun main(argc: int, argv: **char): int {
|
|||||||
}
|
}
|
||||||
closure _reset_closure = (closure){ _reset_impl, NULL};
|
closure _reset_closure = (closure){ _reset_impl, NULL};
|
||||||
|
|
||||||
|
size_t _throw_impl(size_t* _, size_t num, size_t* args) {
|
||||||
|
check_num_params(num, 1, "throw");
|
||||||
|
current_exception_value = args[0];
|
||||||
|
longjmp(*current_exception_handler, 1);
|
||||||
|
}
|
||||||
|
closure _throw_closure = (closure){ _throw_impl, NULL};
|
||||||
|
|
||||||
""" //"
|
""" //"
|
||||||
var main_s = str("int main(int argc, char** argv) {\n")
|
var main_s = str("int main(int argc, char** argv) {\n")
|
||||||
var main_body = str()
|
var main_body = str()
|
||||||
@@ -1810,6 +1820,8 @@ fun compile_value(top_decs: *str, top_defs: *str, main_init: *str, defs: *str, e
|
|||||||
return str("((((size_t)&_deref_closure)<<3)|0x6)")
|
return str("((((size_t)&_deref_closure)<<3)|0x6)")
|
||||||
} else if (s == "reset!") {
|
} else if (s == "reset!") {
|
||||||
return str("((((size_t)&_reset_closure)<<3)|0x6)")
|
return str("((((size_t)&_reset_closure)<<3)|0x6)")
|
||||||
|
} else if (s == "throw") {
|
||||||
|
return str("((((size_t)&_throw_closure)<<3)|0x6)")
|
||||||
} else {
|
} else {
|
||||||
var e = env->find(s);
|
var e = env->find(s);
|
||||||
if e != null<Env>() && e->outer == null<Env>() {
|
if e != null<Env>() && e->outer == null<Env>() {
|
||||||
@@ -1964,22 +1976,31 @@ fun compile(top_decs: *str, top_defs: *str, main_init: *str, defs: *str, env: *E
|
|||||||
} else if (is_symbol(l[0], "macroexpand")) {
|
} else if (is_symbol(l[0], "macroexpand")) {
|
||||||
error("macroexpand doesn't make sense while compiling")
|
error("macroexpand doesn't make sense while compiling")
|
||||||
} else if (is_symbol(l[0], "try*")) {
|
} else if (is_symbol(l[0], "try*")) {
|
||||||
error("compile try* unimplemented")
|
var tmp_name = new_tmp()
|
||||||
/*if l.size != 2 && (l.size != 3 || !is_list(l[2])) {*/
|
var tmp_exception_name = new_tmp()
|
||||||
/*return MalResult::Err(MalValue::String(str("try* wrong arguments")))*/
|
var tmp_new_exception_name = new_tmp()
|
||||||
/*}*/
|
*defs += "size_t " + tmp_name + " = 0;\n"
|
||||||
/*var A = EVAL(env, l[1])*/
|
*defs += "jmp_buf *" + tmp_exception_name + " = current_exception_handler;\n"
|
||||||
/*if l.size == 3 && is_err(A) {*/
|
*defs += "jmp_buf " + tmp_new_exception_name + ";\n"
|
||||||
/*var catch = get_list(l[2])*/
|
*defs += "current_exception_handler = &" + tmp_new_exception_name + ";\n"
|
||||||
/*if catch.size != 3 || !is_symbol(catch[0], "catch*") || !is_symbol(catch[1]) {*/
|
*defs += "if (!setjmp(*current_exception_handler)) {\n"
|
||||||
/*return MalResult::Err(MalValue::String(str("catch* block malformed")))*/
|
*defs += tmp_name + " = " + compile(top_decs, top_defs, main_init, defs, env, l[1]) + ";\n"
|
||||||
/*}*/
|
*defs += "} else {\n"
|
||||||
/*var new_env = new<Env>()->construct(env)*/
|
if l.size == 3 {
|
||||||
/*env->set(get_symbol_text(catch[1]), get_err(A))*/
|
var catch = get_list(l[2])
|
||||||
/*return EVAL(new_env, catch[2])*/
|
if catch.size != 3 || !is_symbol(catch[0], "catch*") || !is_symbol(catch[1]) {
|
||||||
/*} else {*/
|
error("catch* block malformed")
|
||||||
/*return A*/
|
}
|
||||||
/*}*/
|
var new_env = new<Env>()->construct(env)
|
||||||
|
new_env->set(get_symbol_text(catch[1]), MalValue::Nil())
|
||||||
|
*defs += "size_t " + get_symbol_text(catch[1]) + " = current_exception_value;\n"
|
||||||
|
*defs += tmp_name + " = " + compile(top_decs, top_defs, main_init, defs, new_env, catch[2]) + ";\n"
|
||||||
|
} else {
|
||||||
|
*defs += tmp_name + " = current_exception_value;\n";
|
||||||
|
}
|
||||||
|
*defs += "}\n"
|
||||||
|
*defs += "current_exception_handler = " + tmp_exception_name + ";\n"
|
||||||
|
return tmp_name
|
||||||
} else {
|
} else {
|
||||||
var to_call = vec<str>()
|
var to_call = vec<str>()
|
||||||
for (var i = 0; i < l.size; i++;) {
|
for (var i = 0; i < l.size; i++;) {
|
||||||
|
|||||||
Reference in New Issue
Block a user