diff --git a/bf.kp b/bf.kp index 43fee75..0101594 100644 --- a/bf.kp +++ b/bf.kp @@ -72,10 +72,11 @@ (def! main (fn* () (let* ( a 7 - b "hello" ) + b [1] + c (with-meta b "yolo") ) (do (try* - ((fn* () (do (println b) (println "world") a))) + ((fn* () (do (println b) (println c) (println (meta c)) (println "world") a))) ))))) diff --git a/k_prime.krak b/k_prime.krak index 2dab44d..d1efda3 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -1327,6 +1327,7 @@ fun main(argc: int, argv: **char): int { 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_int(size_t p, char* function) { if ((p&0x7)!=0) {fprintf(stderr, "%s: expected param to be int\n", function); exit(1);}} + void check_vector(size_t p, char* function) { if ((p&0x7)!=0x2) {fprintf(stderr, "%s: expected param to be vector\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);}} typedef struct { size_t (*func)(size_t*,size_t,size_t*); @@ -1389,8 +1390,8 @@ fun main(argc: int, argv: **char): int { else if ((args[_idx] & 0x07) == 0x02) { printf("( "); size_t* vec = (size_t*)(args[_idx]>>3); - for (int i = 0; i < vec[0]; i++) { - _print_impl(NULL, 1, vec+i+1); + for (int i = 0; i < vec[1]; i++) { + _print_impl(NULL, 1, vec+i+2); printf(" "); } printf(")"); @@ -1408,10 +1409,11 @@ fun main(argc: int, argv: **char): int { closure _println_closure = (closure){ _println_impl, NULL}; size_t _vector_impl(size_t* _, size_t num, size_t* args) { - size_t *vec = malloc(sizeof(size_t)*(num + 1)); - vec[0] = num; + size_t *vec = malloc(sizeof(size_t)*(num + 2)); + vec[0] = 0x2F; + vec[1] = num; for (int i = 0; i < num; i++) - vec[i+1] = args[i]; + vec[i+2] = args[i]; return ((((size_t)vec)<<3)|0x2); } closure _vector_closure = (closure){ _vector_impl, NULL}; @@ -1419,28 +1421,41 @@ fun main(argc: int, argv: **char): int { size_t _nth_impl(size_t* _, size_t num, size_t* args) { check_num_params(num, 2, "nth"); check_int(args[1], "nth"); - if ((args[0] & 0x7) == 0x1) { - size_t *node = (size_t*)(args[0]>>3); - for (int i = 0; i < (args[1]>>3); i++) { - if ((node[1] & 0x7) != 0x1) { - error("nth idx out of range\n"); - } - node = (size_t*)(node[1]>>3); - } - return node[0]; - } else if ((args[0] & 0x7) == 0x2) { + if ((args[0] & 0x7) == 0x2) { size_t* vec = (size_t*)(args[0]>>3); - if (((ptrdiff_t)(args[1]>>3)) < 0 || (args[1]>>3) >= vec[0]) { + if (((ptrdiff_t)(args[1]>>3)) < 0 || (args[1]>>3) >= vec[1]) { error("nth idx out of range\n"); } - return vec[(args[1]>>3)+1]; + return vec[(args[1]>>3)+2]; } else { - error("Passed not a list or vector to nth\n"); + error("Passed not a vector to nth\n"); } return 0x2F; } closure _nth_closure = (closure){ _nth_impl, NULL}; + size_t _with_meta_impl(size_t* _, size_t num, size_t* args) { + check_num_params(num, 2, "with-meta"); + check_vector(args[0], "with-meta"); + + size_t* og_vec = (size_t*)(args[0]>>3); + size_t *vec = malloc(sizeof(size_t)*(og_vec[1] + 2)); + vec[0] = args[1]; + vec[1] = og_vec[1]; + for (int i = 0; i < og_vec[1]; i++) + vec[i+2] = og_vec[i+2]; + return ((((size_t)vec)<<3)|0x2); + } + closure _with_meta_closure = (closure){ _with_meta_impl, NULL}; + + size_t _meta_impl(size_t* _, size_t num, size_t* args) { + check_num_params(num, 1, "meta"); + check_vector(args[0], "meta"); + + return ((size_t*)(args[0]>>3))[0]; + } + closure _meta_closure = (closure){ _meta_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]; @@ -1658,6 +1673,10 @@ fun compile_value(top_decs: *str, top_defs: *str, main_init: *str, defs: *str, e return str("((((size_t)&_nth_closure)<<3)|0x6)") } else if (s == "throw") { return str("((((size_t)&_throw_closure)<<3)|0x6)") + } else if (s == "with-meta") { + return str("((((size_t)&_with_meta_closure)<<3)|0x6)") + } else if (s == "meta") { + return str("((((size_t)&_meta_closure)<<3)|0x6)") } else { var e = env->find(s); if e != null() && e->outer == null() {