From 62e991d0dd6cd80c6802bf768695b4f19df0e34e Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Wed, 16 Sep 2020 00:07:49 -0400 Subject: [PATCH] Y combinator works, as well as vY (the vau version, which is different b/c applicative order), and prototype for new load style removing set works --- k_prime.krak | 27 +++++++++++++++++------- k_prime_stdlib/prelude.kp | 10 +++++++++ load_test.kp | 43 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 load_test.kp diff --git a/k_prime.krak b/k_prime.krak index 0671497..bc738f4 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -565,7 +565,7 @@ fun READ(grammar: ref Grammer, s: str): KPResult { } else { println("parsed to var: " + pr_str(get_value(to_ret.second), true)) } - error("parsed some, but not all") + error("parsed some, but not all, remaining: " + s.slice(to_ret.first, -1)) } return to_ret.second } @@ -1195,17 +1195,20 @@ fun main(argc: int, argv: **char): int { } })); var ERS = fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { - if params.size != 2 { - return make_pair(null(), KPResult::Err(kpString(str("eval-read-string with not a single string and env")))) + if params.size == 0 || params.size > 2 { + return make_pair(null(), KPResult::Err(kpString(str("eval-read-string with not a single string and optional env")))) } else { if !params[0].is_string() { return make_pair(null(), KPResult::Err(kpString(str("first param to eval-read-string s not a string")))) } var input = params[0].get_string() - if !params[1].is_env() { + if params.size == 2 && !params[1].is_env() { return make_pair(null(), KPResult::Err(kpString(str("second param to eval-read-string is not a env")))) } - var eval_env = params[1].get_env() + var eval_env = dynamic_env + if params.size == 2 { + eval_env = params[1].get_env() + } var i = 0 var current_ret = KPResult::Ok(kpNil()) if i < input.length() { @@ -1267,14 +1270,24 @@ fun main(argc: int, argv: **char): int { return make_pair(null(), KPResult::Err(kpString(str("slurp with not a single string")))) } else { if !params[0].is_string() { - return make_pair(null(), KPResult::Err(kpString(str("read-string with not a single string")))) + return make_pair(null(), KPResult::Err(kpString(str("slurp with not a single string")))) } if !file_exists(params[0].get_string()) { - return make_pair(null(), KPResult::Err(kpString(str("read-string with bad path ") + params[0].get_string()))) + return make_pair(null(), KPResult::Err(kpString(str("slurp with bad path ") + params[0].get_string()))) } return make_pair(null(), KPResult::Ok(kpString(read_file(params[0].get_string())))) } })); + env->set(str("get_line"), make_builtin_combiner(str("get_line"), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { + if params.size != 1 { + return make_pair(null(), KPResult::Err(kpString(str("get_line with not a single string")))) + } else { + if !params[0].is_string() { + return make_pair(null(), KPResult::Err(kpString(str("get_line with not a single string")))) + } + return make_pair(null(), KPResult::Ok(kpString(get_line(params[0].get_string(), 1024)))) + } + })); env->set(str("wrap"), make_builtin_combiner(str("wrap"), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { if params.size != 1 { return make_pair(null(), KPResult::Err(kpString(str("wrap called with not one argument")))) diff --git a/k_prime_stdlib/prelude.kp b/k_prime_stdlib/prelude.kp index 09cf5c9..ec172bd 100644 --- a/k_prime_stdlib/prelude.kp +++ b/k_prime_stdlib/prelude.kp @@ -70,3 +70,13 @@ (add_grammar_rule 'form '("~" optional_WS form) (lambda (_ _ f) ['unquote f])) (add_grammar_rule 'form '("," optional_WS form) (lambda (_ _ f) ['splice-unquote f])) +(set! Y (lambda (f) + ((lambda (x) (x x)) + (lambda (x) (f (lambda (& y) (lapply (x x) y))))))) + +(set! vY (lambda (f) + ((lambda (x) (x x)) + (lambda (x) (f (vau de (& y) (vapply (x x) y de))))))) + +(set! rep (Y (lambda (recurse) (wrap (vau de () + (do (println (eval (read-string (get_line "> ")) de)) (recurse))))))) diff --git a/load_test.kp b/load_test.kp new file mode 100644 index 0000000..609a489 --- /dev/null +++ b/load_test.kp @@ -0,0 +1,43 @@ +(vau de (code) + +((wrap (vau _ (quote) +((wrap (vau _ (let1) + +(let1 lambda (vau se (p b) (wrap (eval (array vau (quote _) p b) se))) + + + +(let1 do_helper (lambda (recurse s i se) (cond (= i (len s)) nil + (= i (- (len s) 1)) (eval (idx s i) se) + (eval (idx s i) se) (recurse recurse s (+ i 1) se) + true (recurse recurse s (+ i 1) se))) +(let1 do (vau se (& s) (do_helper do_helper s 0 se)) + +(let1 concat_helper (lambda (recurse a1 a2 a3 i) (cond (< i (len a1)) (do (set-idx! a3 i (idx a1 i)) (recurse recurse a1 a2 a3 (+ i 1))) + (< i (+ (len a1) (len a2))) (do (set-idx! a3 i (idx a2 (- i (len a1)))) (recurse recurse a1 a2 a3 (+ i 1))) + true a3)) +(let1 concat (lambda (a1 a2) (concat_helper concat_helper a1 a2 (array-with-len (+ (len a1) (len a2))) 0)) + +(let1 current-env (vau de () de) +(let1 lapply (lambda (f p) (eval (concat (array (unwrap f)) p) (current-env))) +(let1 vapply (lambda (f p ede) (eval (concat (array f) p) ede)) +(let1 Y (lambda (f) + ((lambda (x) (x x)) + (lambda (x) (f (lambda (& y) (lapply (x x) y)))))) +(let1 vY (lambda (f) + ((lambda (x) (x x)) + (lambda (x) (f (vau de (& y) (vapply (x x) y de)))))) + +(let1 let (vY (lambda (recurse) (vau de (vs b) (cond (= (len vs) 0) (eval b de) + true (vapply let1 (array (idx vs 0) (idx vs 1) (array recurse (slice vs 2 -1) b)) de))))) + +(let1 rec-lambda (vau se (p b) (eval (array Y (array lambda (quote (recurse)) (array lambda p b))))) + +(eval code) + +)))))))))))) + +)) (vau de (s v b) (eval (array (array vau (quote _) (array s) b) (eval v de)) de))) +)) (vau _ (x) x)) + +)