diff --git a/k_prime.krak b/k_prime.krak index 27274e9..951fa33 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -789,6 +789,32 @@ fun main(argc: int, argv: **char): int { return KPResult::Ok(kpNil()) })); + env->set(str("symbol?"), make_builtin_combiner(str("symbol?"), fun(params: vec, dynamic_env: *KPEnv): KPResult { + if params.size != 1 { + return KPResult::Err(kpString(str("Need 1 param to symbol?"))) + } + var ip = EVAL(dynamic_env, params[0]) + if is_err(ip) { + return ip + } + return KPResult::Ok(kpBool(get_value(ip).is_symbol())) + })); + + env->set(str("get-text"), make_builtin_combiner(str("get-text"), fun(params: vec, dynamic_env: *KPEnv): KPResult { + if params.size != 1 { + return KPResult::Err(kpString(str("Need 1 param to get-text"))) + } + var ip = EVAL(dynamic_env, params[0]) + if is_err(ip) { + return ip + } + var iv = get_value(ip) + if !iv.is_symbol() { + return KPResult::Err(kpString(str("Called get-text with not a symbol"))) + } + return KPResult::Ok(kpString(iv.get_symbol_text())) + })); + env->set(str("vector"), make_builtin_combiner(str("vector"), fun(params: vec, dynamic_env: *KPEnv): KPResult { var evaled_params = vec() for (var i = 0; i < params.size; i++;) { @@ -800,6 +826,16 @@ fun main(argc: int, argv: **char): int { } return KPResult::Ok(kpVector(evaled_params)) })); + env->set(str("vector?"), make_builtin_combiner(str("vector?"), fun(params: vec, dynamic_env: *KPEnv): KPResult { + if params.size != 1 { + return KPResult::Err(kpString(str("Need 1 param to vector?"))) + } + var ip = EVAL(dynamic_env, params[0]) + if is_err(ip) { + return ip + } + return KPResult::Ok(kpBool(get_value(ip).is_vector())) + })); env->set(str("len"), make_builtin_combiner(str("len"), fun(params: vec, dynamic_env: *KPEnv): KPResult { if params.size != 1 { return KPResult::Err(kpString(str("Need 1 param to len"))) @@ -852,7 +888,7 @@ fun main(argc: int, argv: **char): int { return ip } var v = get_value(ip) - if !v.is_vector() { return KPResult::Err(kpString(str("Param ") + i + " to concat is not vector")); } + if !v.is_vector() { return KPResult::Err(kpString(str("Param ") + i + " to concat is not vector: " + pr_str(v, false))); } to_ret += v.get_vector_rc().get() } return KPResult::Ok(kpVector(to_ret)) diff --git a/quasi.kp b/quasi.kp new file mode 100644 index 0000000..21c53fc --- /dev/null +++ b/quasi.kp @@ -0,0 +1,19 @@ +(fun print_through (x) (let (_ (println x)) x)) + +(fun is_pair? (x) (and (vector? x) (> (len x) 0))) + +(set! quasiquote (vau de (x) + (cond (is_pair? x) + (cond (and (symbol? (idx x 0)) (= (get-text (idx x 0)) "unquote")) + (eval (idx x 1) de) + true + (cond (and (is_pair? (idx x 0)) (symbol? (idx (idx x 0) 0)) (= (get-text (idx (idx x 0) 0)) "splice-unquote")) + (concat (eval (idx (idx x 0) 1) de) (apply quasiquote [(slice x 1 -1)] de)) + true + (concat [(apply quasiquote [(idx x 0)] de)] (apply quasiquote [(slice x 1 -1)] de)))) + true x))) + +(add_grammar_rule 'form '("`" optional_WS form) (lambda (_ _ f) ['quasiquote f])) +(add_grammar_rule 'form '("~" optional_WS form) (lambda (_ _ f) ['unquote f])) +(add_grammar_rule 'form '("," optional_WS form) (lambda (_ _ f) ['splice-unquote f])) +