diff --git a/bf.kp b/bf.kp index 1db4201..876becc 100644 --- a/bf.kp +++ b/bf.kp @@ -1,90 +1,3 @@ -;(def! main (fn* (argv) 2)) -;(def! main (fn* () (let* (a 13 b 12 c 11) b))) -;(def! main (fn* () (do 13 12 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 -))) -;(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 4))) -;(def! main (fn* () (fn* () 1))) - -;(def! other (fn* (a b c) (- (+ a b) c))) -;(def! main (fn* () (other 13 1 4))) - -;(def! other 12) -;(def! main (fn* () (+ other 4))) - -;(def! fact (fn* (n) (if (<= n 1) 1 (* (fact (- n 1)) n)))) -;(def! main (fn* () (let* (to_ret (fact 5)) (do (println to_ret) to_ret)))) - -;(def! ret_with_call (fn* (n) (fn* (x) (+ n x)))) -;(def! main (fn* () ((ret_with_call 3) 5))) - -(def! test (fn* () (let* ( - ;(l (list 3 4 5)) - a 5 - ;l '(a 4 5) - ;l (vector 3 4 5) - ;l [a 4 5] - l '[3 4 5] - ;l '[a 4 5] - ) - (nth l 0)))) -;(def! main (fn* () (let* (it (test)) (do (println it) it)))) -;(def! main (fn* () (let* (it "asdf") (do (println it) 0)))) -;(def! main (fn* () (let* (it 'sym_baby) (do (println it) 0)))) -;(def! main (fn* () (let* (it [1 2 3]) (do (println it) 0)))) -;(def! main (fn* () (let* (it '(1 2 3)) (do (println it) 0)))) -;(def! my_str "asdf") -;(def! main (fn* () (do (println my_str) 0))) - -;(def! main (fn* () (let* (it (atom 7)) (do -; (println it) -; (println (deref it)) -; (reset! it 8) -; (println (deref it)) -; (deref it) -; )))) -;(def! my_atom (atom 5)) -;(def! main (fn* () (do -; (println my_atom) -; (println (deref my_atom)) -; (reset! my_atom 1337) -; (println 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))) - -(def! to_be_saved (with-meta [1] [2])) -(def! to_be_saved_s "asdfasdf") - -(let* ( a [0] - b (with-meta a (fn* () (set-nth! b 0 (+ 1 (nth b 0)))))) - (do - (println "testing meta stuff!") - (println b) - ((meta b)) - (println b) - ((meta b)) - (println b))) - - - ; Use the power of GLL reader macros to implement ; BF support @@ -98,10 +11,7 @@ (add_grammer_rule 'bfs_atom ["."] (fn* (xs) '(set-nth! output 0 (cons (nth tape (nth cursor 0)) (nth output 0))))) ; Define strings of BF atoms -(add_grammer_rule 'non_empty_bfs_list ['bfs_atom] (fn* (xs) (vector (nth xs 0)))) -(add_grammer_rule 'non_empty_bfs_list ['bfs_atom 'optional_WS 'non_empty_bfs_list] (fn* (xs) (cons (nth xs 0) (nth xs 2)))) -(add_grammer_rule 'bfs_list [] (fn* (xs) xs)) -(add_grammer_rule 'bfs_list ['non_empty_bfs_list] (fn* (xs) (nth xs 0))) +(add_grammer_rule 'bfs_list ['bfs_atom +] (fn* (xs) (nth xs 0))) ; Add loop as an atom (add_grammer_rule 'bfs_atom ["\\[" 'bfs_list "]"] (fn* (xs) @@ -129,73 +39,9 @@ inptr (vector 0) output (vector (vector)) ) - (do ,(nth xs 4) (nth output 0)))))) + (do (println "beginning bfs") ,(nth xs 4) (nth output 0)))))) ; Let's try it out! This BF program prints the input 3 times -;(println (bf { ,>+++[<.>-] } [1337])) -;(println "BF: " (bf { ++-. } [1337])) - -(def! our_obj (with-meta [0] (fn* () (set-nth! our_obj 0 (+ 1 (nth our_obj 0)))))) - -(def! get-value-helper (fn* (dict key idx) (if (>= idx (count dict)) nil (if (= key (nth dict idx)) (nth dict (+ idx 1)) (get-value-helper dict key (+ idx 2)))))) -(def! get-value (fn* (dict key) (get-value-helper dict key 0))) -(def! method-call (fn* (object method & arguments) (let* (method_fn (get-value (meta object) method)) - (if (= method_fn nil) - (println "no method " method) - (apply method_fn object arguments))))) -; method call syntax -(add_grammer_rule 'form [ 'form "\\." 'atom 'optional_WS "\\(" 'optional_WS 'space_forms 'optional_WS "\\)" ] (fn* (xs) `(method-call ~(nth xs 0) '~(nth xs 2) ,(nth xs 6)))) -(def! actual_obj (with-meta [0] [ - 'inc (fn* (o) (set-nth! o 0 (+ (nth o 0) 1))) - 'dec (fn* (o) (set-nth! o 0 (- (nth o 0) 1))) - 'set (fn* (o n) (set-nth! o 0 n)) - 'get (fn* (o) (nth o 0)) - ])) - -(def! main (fn* () (let* ( a 7 - b [1] - c (with-meta b "yolo") ) - (do - (try* - ((fn* () (do - (println b) - (set-nth! b 0 2) - (println b) - (println c) - (println (meta c)) - (println "world") - (println to_be_saved) - (println (meta to_be_saved)) - (println to_be_saved_s) - (println "Here in main testing our_obj") - (println our_obj) - ((meta our_obj)) - (println our_obj) - ((meta our_obj)) - (println our_obj) - (println (bf { ,>+++[<.>-] } [1337])) - (println "actual_obj" actual_obj) - (method-call actual_obj 'inc) - (println "actual_obj" actual_obj) - (println "with get: " (method-call actual_obj 'get)) - (println "actual_obj" actual_obj) - (method-call actual_obj 'dec) - (method-call actual_obj 'dec) - (println "actual_obj" actual_obj) - (println "setting old style 654") - (method-call actual_obj 'set 654) - (println "actual_obj" actual_obj) - (println "Ok, doing with new method call syntax") - actual_obj.inc() - (println "actual_obj" actual_obj) - (println "setting new style 1337") - actual_obj.set(1337) - (println "actual_obj" actual_obj) - (println "with get " actual_obj.get()) - a))) - ))))) -(do - (println "interp-main") - (main) - (println "done interp-main") - nil) +(println (bf { ,>+++[<.>-] } [1337])) +; we can also have it compile into our main program +(def! main (fn* () (do (println "BF: " (bf { ,>+++[<.>-] } [1337])) 0))) diff --git a/fungll.krak b/fungll.krak index cf2415b..a0654b6 100644 --- a/fungll.krak +++ b/fungll.krak @@ -51,12 +51,13 @@ obj Grammer (Object) { nonterminal_funs.add(vec(make_pair(d,f))) return -1*nonterminals.size } - fun add_to_or_create_nonterminal(name: ref str, rule: ref vec, d: K, f: fun(ref K,ref vec): T) { + fun add_to_or_create_nonterminal(name: ref str, rule: ref vec, d: K, f: fun(ref K,ref vec): T): int { var idx = nonterminal_names.find(name) if idx >= 0 { add_to_nonterminal(-1*(idx+1), rule, d, f) + return -1*(idx+1) } else { - add_new_nonterminal(name, rule, d, f) + return add_new_nonterminal(name, rule, d, f) } } fun add_to_nonterminal(nonterminal: int, rule: ref vec, d: K, f: fun(ref K,ref vec): T) { diff --git a/k_prime.krak b/k_prime.krak index aa5bc94..6b8fdf8 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -120,6 +120,17 @@ obj MalValue (Object) { } return *this } + fun is_function(): bool { + match (internal) { + MalValue_int::Function(f) { + return true + } + MalValue_int::BuiltinFunction(f) { + return true + } + } + return false + } fun is_vector(): bool { match (internal) { MalValue_int::Vector(v) { @@ -488,7 +499,8 @@ fun get_err(r: MalResult): MalValue { return e } } - return malString(str("not error")) + /*return malSymbol(str("get-err-not-error"))*/ + error("get-err-not-error") } fun get_value(r: MalResult): MalValue { match (r) { @@ -496,7 +508,8 @@ fun get_value(r: MalResult): MalValue { return v } } - return malSymbol(str("error")) + /*return malSymbol(str("get-value-is-error"))*/ + error("get-value-is-error") } fun pr_str(v: MalValue, print_readably: bool): str { match (v.internal) { @@ -1246,6 +1259,37 @@ fun main(argc: int, argv: **char): int { return MalResult::Ok(malString(input.slice(l,r))) })) } else { + match (rule[i].internal) { + MalValue_int::BuiltinFunction(f) { + if f.name == "+" || f.name == "*" { + if int_rule.size == 0 { + return MalResult::Err(malString(str("add_grammer_rule has + or * in first position, with nothing to repeat"))) + } + var current = int_rule.last() + var sub_rule_names = nonterminal_str + "_" + new_tmp() + var new = grammer.add_to_or_create_nonterminal(sub_rule_names + "_one_or_more", vec(current), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { + if is_err(x[0]) { return x[0]; } + return MalResult::Ok(malVector(vec(get_value(x[0])))) + }) + grammer.add_to_nonterminal(new, vec(current, new), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { + if is_err(x[0]) { return x[0]; } + if is_err(x[1]) { return x[1]; } + return MalResult::Ok(malVector(vec(get_value(x[0])) + get_value(x[1]).get_vector_rc().get())) + }) + if f.name == "*" { + new = grammer.add_to_or_create_nonterminal(sub_rule_names + "_zero_or_more", vec(new), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { + if is_err(x[0]) { return x[0]; } + return MalResult::Ok(get_value(x[0])) + }) + grammer.add_to_nonterminal(new, vec(), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { + return MalResult::Ok(malVector(vec())) + }) + } + int_rule.last() = new + continue + } + } + } return MalResult::Err(malString(str("add_grammer_rule called with not symbol, int, or string in rule"))) } } @@ -1259,6 +1303,7 @@ fun main(argc: int, argv: **char): int { } return function_call(f, vec(malVector(params))) }) + return MalResult::Ok(malNil()) } })); var ERS = fun(params: vec): MalResult { @@ -1343,7 +1388,7 @@ fun main(argc: int, argv: **char): int { env->set(str("*ARGV*"), malVector(params)) var eval_result_str = rep(grammer, env, str("(load-file \"") + argv[1] + "\")") println(eval_result_str) - if eval_result_str.slice(0,11) == "Exception: " { + if eval_result_str.length() >= 11 && eval_result_str.slice(0,11) == "Exception: " { error("aborting compile") } // check for compile diff --git a/method.kp b/method.kp new file mode 100644 index 0000000..2fefb70 --- /dev/null +++ b/method.kp @@ -0,0 +1,63 @@ + +(def! our_obj (with-meta [0] (fn* () (set-nth! our_obj 0 (+ 1 (nth our_obj 0)))))) + +(def! get-value-helper (fn* (dict key idx) (if (>= idx (count dict)) nil (if (= key (nth dict idx)) (nth dict (+ idx 1)) (get-value-helper dict key (+ idx 2)))))) +(def! get-value (fn* (dict key) (get-value-helper dict key 0))) +(def! method-call (fn* (object method & arguments) (let* (method_fn (get-value (meta object) method)) + (if (= method_fn nil) + (println "no method " method) + (apply method_fn object arguments))))) +; method call syntax +(add_grammer_rule 'form [ 'form "\\." 'atom 'optional_WS "\\(" 'optional_WS 'space_forms 'optional_WS "\\)" ] (fn* (xs) `(method-call ~(nth xs 0) '~(nth xs 2) ,(nth xs 6)))) +(def! actual_obj (with-meta [0] [ + 'inc (fn* (o) (set-nth! o 0 (+ (nth o 0) 1))) + 'dec (fn* (o) (set-nth! o 0 (- (nth o 0) 1))) + 'set (fn* (o n) (set-nth! o 0 n)) + 'get (fn* (o) (nth o 0)) + ])) +(def! to_be_saved (with-meta [1] [2])) +(def! main (fn* () (let* ( a 7 + b [1] + c (with-meta b "yolo") ) + (do + (try* + ((fn* () (do + (println b) + (set-nth! b 0 2) + (println b) + (println c) + (println (meta c)) + (println "world") + (println to_be_saved) + (println (meta to_be_saved)) + (println "Here in main testing our_obj") + (println our_obj) + ((meta our_obj)) + (println our_obj) + ((meta our_obj)) + (println our_obj) + (println "actual_obj" actual_obj) + (method-call actual_obj 'inc) + (println "actual_obj" actual_obj) + (println "with get: " (method-call actual_obj 'get)) + (println "actual_obj" actual_obj) + (method-call actual_obj 'dec) + (method-call actual_obj 'dec) + (println "actual_obj" actual_obj) + (println "setting old style 654") + (method-call actual_obj 'set 654) + (println "actual_obj" actual_obj) + (println "Ok, doing with new method call syntax") + actual_obj.inc() + (println "actual_obj" actual_obj) + (println "setting new style 1337") + actual_obj.set(1337) + (println "actual_obj" actual_obj) + (println "with get " actual_obj.get()) + a))) + ))))) +(do + (println "interp-main") + (main) + (println "done interp-main") + nil)