Extended foldl and foldr to be variadic, fixed foldr, and added pattern matching!
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
(let (
|
(let (
|
||||||
|
|
||||||
foldl (let (helper (rec-lambda recurse (f z v i) (if (= i (len v)) z
|
foldl (let (helper (rec-lambda recurse (f z vs i) (if (= i (len (idx vs 0))) z
|
||||||
(recurse f (f z (idx v i)) v (+ i 1)))))
|
(recurse f (lapply f (cons z (map (lambda (x) (idx x i)) vs))) vs (+ i 1)))))
|
||||||
(lambda (f z v) (helper f z v 0)))
|
(lambda (f z & vs) (helper f z vs 0)))
|
||||||
foldr (let (helper (rec-lambda recurse (f z v i) (if (= i (len v)) z
|
foldr (let (helper (rec-lambda recurse (f z vs i) (if (= i (len (idx vs 0))) z
|
||||||
(f (idx v i) (recurse f z v (+ i 1))))))
|
(lapply f (cons (recurse f z vs (+ i 1)) (map (lambda (x) (idx x i)) vs))))))
|
||||||
(lambda (f z v) (helper f z v 0)))
|
(lambda (f z & vs) (helper f z vs 0)))
|
||||||
reverse (lambda (x) (foldl (lambda (acc i) (cons i acc)) [] x))
|
reverse (lambda (x) (foldl (lambda (acc i) (cons i acc)) [] x))
|
||||||
empty_dict []
|
empty_dict []
|
||||||
put (lambda (m k v) (cons [k v] m))
|
put (lambda (m k v) (cons [k v] m))
|
||||||
|
|||||||
63
k_prime.krak
63
k_prime.krak
@@ -115,7 +115,7 @@ obj KPBuiltinCombiner (Object) {
|
|||||||
copy_construct(&other)
|
copy_construct(&other)
|
||||||
}
|
}
|
||||||
fun operator==(other: ref KPBuiltinCombiner):bool {
|
fun operator==(other: ref KPBuiltinCombiner):bool {
|
||||||
return false
|
return name == other.name
|
||||||
}
|
}
|
||||||
fun call(params: vec<KPValue>, dynamic_env: KPValue): pair<*KPEnv, KPResult> {
|
fun call(params: vec<KPValue>, dynamic_env: KPValue): pair<*KPEnv, KPResult> {
|
||||||
if !dynamic_env.is_env() {
|
if !dynamic_env.is_env() {
|
||||||
@@ -388,6 +388,17 @@ obj KPValue (Object) {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
fun is_bool(): bool {
|
||||||
|
match (internal) {
|
||||||
|
KPValue_int::True() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
KPValue_int::False() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
fun is_truthy(): bool {
|
fun is_truthy(): bool {
|
||||||
match (internal) {
|
match (internal) {
|
||||||
KPValue_int::False() {
|
KPValue_int::False() {
|
||||||
@@ -839,13 +850,55 @@ fun main(argc: int, argv: **char): int {
|
|||||||
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_symbol())))
|
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_symbol())))
|
||||||
}));
|
}));
|
||||||
|
|
||||||
env->set(str("int?"), make_builtin_combiner(str("symbol?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
env->set(str("int?"), make_builtin_combiner(str("int?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
if params.size != 1 {
|
if params.size != 1 {
|
||||||
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to int?"))))
|
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to int?"))))
|
||||||
}
|
}
|
||||||
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_int())))
|
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_int())))
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
env->set(str("string?"), make_builtin_combiner(str("string?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
|
if params.size != 1 {
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to string?"))))
|
||||||
|
}
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_string())))
|
||||||
|
}));
|
||||||
|
|
||||||
|
env->set(str("combiner?"), make_builtin_combiner(str("combiner?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
|
if params.size != 1 {
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to combiner?"))))
|
||||||
|
}
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_combiner())))
|
||||||
|
}));
|
||||||
|
|
||||||
|
env->set(str("env?"), make_builtin_combiner(str("env?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
|
if params.size != 1 {
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to env?"))))
|
||||||
|
}
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_env())))
|
||||||
|
}));
|
||||||
|
|
||||||
|
env->set(str("nil?"), make_builtin_combiner(str("nil?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
|
if params.size != 1 {
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to nil?"))))
|
||||||
|
}
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_nil())))
|
||||||
|
}));
|
||||||
|
|
||||||
|
env->set(str("bool?"), make_builtin_combiner(str("bool?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
|
if params.size != 1 {
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to bool?"))))
|
||||||
|
}
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_bool())))
|
||||||
|
}));
|
||||||
|
|
||||||
|
env->set(str("array?"), make_builtin_combiner(str("array?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
|
if params.size != 1 {
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to array?"))))
|
||||||
|
}
|
||||||
|
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_array())))
|
||||||
|
}));
|
||||||
|
|
||||||
env->set(str("str-to-symbol"), make_builtin_combiner(str("str-to-symbol"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
env->set(str("str-to-symbol"), make_builtin_combiner(str("str-to-symbol"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
if params.size != 1 {
|
if params.size != 1 {
|
||||||
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to str-to-symbol"))))
|
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to str-to-symbol"))))
|
||||||
@@ -869,12 +922,6 @@ fun main(argc: int, argv: **char): int {
|
|||||||
env->set(str("array"), make_builtin_combiner(str("array"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
env->set(str("array"), make_builtin_combiner(str("array"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
return make_pair(null<KPEnv>(), KPResult::Ok(kpArray(params)))
|
return make_pair(null<KPEnv>(), KPResult::Ok(kpArray(params)))
|
||||||
}));
|
}));
|
||||||
env->set(str("array?"), make_builtin_combiner(str("array?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
|
||||||
if params.size != 1 {
|
|
||||||
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to array?"))))
|
|
||||||
}
|
|
||||||
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_array())))
|
|
||||||
}));
|
|
||||||
env->set(str("len"), make_builtin_combiner(str("len"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
env->set(str("len"), make_builtin_combiner(str("len"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
|
||||||
if params.size != 1 {
|
if params.size != 1 {
|
||||||
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to len"))))
|
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to len"))))
|
||||||
|
|||||||
29
match.kp
Normal file
29
match.kp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
(with_import "./collections.kp"
|
||||||
|
(let (
|
||||||
|
|
||||||
|
match (vau de (x & cases) (let (
|
||||||
|
x (eval x de)
|
||||||
|
evaluate_case (rec-lambda recurse (name_dict x c) (cond
|
||||||
|
; an explicit nil name_dict case allows us to simply fold over recurse in the array case later
|
||||||
|
(nil? name_dict) nil
|
||||||
|
(symbol? c) (put name_dict c x)
|
||||||
|
(and (int? x) (int? c) (= x c)) name_dict
|
||||||
|
(and (string? x) (string? c) (= x c)) name_dict
|
||||||
|
(and (bool? x) (bool? c) (= x c)) name_dict
|
||||||
|
(and (combiner? x) (combiner? c) (= x c)) name_dict
|
||||||
|
; check for invocation of quote directly
|
||||||
|
; not necessarily ideal if they define their own quote or something
|
||||||
|
(and (symbol? x) (array? c) (= 2 (len c)) (= quote (idx c 0)) (= x (idx c 1))) name_dict
|
||||||
|
; ditto with above, but with array
|
||||||
|
(and (array? x) (array? c) (= (+ 1 (len x)) (len c)) (= array (idx c 0))) (foldl recurse name_dict x (slice c 1 -1))
|
||||||
|
true nil
|
||||||
|
))
|
||||||
|
|
||||||
|
iter (rec-lambda recurse (x i cases) (if (>= i (len cases)) (error "none of match arms matched!")
|
||||||
|
(let ( mapping (evaluate_case empty_dict x (idx cases i)))
|
||||||
|
(if (!= nil mapping) (eval (idx cases (+ i 1)) (add-dict-to-env de mapping))
|
||||||
|
(recurse x (+ i 2) cases)))))
|
||||||
|
) (iter x 0 cases)))
|
||||||
|
)
|
||||||
|
(provide match)
|
||||||
|
))
|
||||||
41
match_test.kp
Normal file
41
match_test.kp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
(with_import "./match.kp"
|
||||||
|
(do
|
||||||
|
(println "first "
|
||||||
|
(match 1
|
||||||
|
1 true
|
||||||
|
a (+ a 1)
|
||||||
|
))
|
||||||
|
|
||||||
|
(println "second "
|
||||||
|
(match 3
|
||||||
|
1 true
|
||||||
|
a (+ a 1)
|
||||||
|
))
|
||||||
|
(println "third "
|
||||||
|
(match "str"
|
||||||
|
1 true
|
||||||
|
"str" "It was a string!"
|
||||||
|
a (+ a 1)
|
||||||
|
))
|
||||||
|
(println "fourth "
|
||||||
|
(match [ 1337 "str" ]
|
||||||
|
1 true
|
||||||
|
"str" "It was a string!"
|
||||||
|
[ 1337 "str" ] "matched an array of int str"
|
||||||
|
a (+ a 1)
|
||||||
|
))
|
||||||
|
(println "fifth "
|
||||||
|
(match [ 1337 "str" 'sy ]
|
||||||
|
1 true
|
||||||
|
"str" "It was a string!"
|
||||||
|
[ 1337 "str" 'sy ] "matched an array of int str symbol"
|
||||||
|
a (+ a 1)
|
||||||
|
))
|
||||||
|
(println "sixth "
|
||||||
|
(match [ 1337 "str" 'walla + 11 false 'kraken [ 'inner 'middle 'end ] [ 'inner1 'middle1 'end1 ] ]
|
||||||
|
1 true
|
||||||
|
"str" "It was a string!"
|
||||||
|
[ 1337 "str" 'walla + a false b [ 'inner c 'end ] d ] (str "matched, and got " a b c d)
|
||||||
|
a (+ a 1)
|
||||||
|
))
|
||||||
|
))
|
||||||
Reference in New Issue
Block a user