diff --git a/k_prime.krak b/k_prime.krak index 8670477..0671497 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -718,15 +718,18 @@ fun main(argc: int, argv: **char): int { return KPResult::Ok(kpArray(vec(get_value(x[0])) + get_value(x[2]).get_array_rc().get())) }) - grammar.add_to_nonterminal(form, vec(grammar.add_terminal("\\(", kpNil(), ret_nil_term), + var call_form = grammar.add_new_nonterminal("call_form", vec(grammar.add_terminal("\\(", kpNil(), ret_nil_term), optional_WS, grammar.add_terminal("\\)", kpNil(), ret_nil_term)), kpNil(), fun(_: ref KPValue, x: ref vec): KPResult { return KPResult::Ok(kpArray(vec())); }) - grammar.add_to_nonterminal(form, vec(grammar.add_terminal("\\(", kpNil(), ret_nil_term), + grammar.add_to_nonterminal(call_form, vec(grammar.add_terminal("\\(", kpNil(), ret_nil_term), optional_WS, space_forms, optional_WS, grammar.add_terminal("\\)", kpNil(), ret_nil_term)), kpNil(), fun(_: ref KPValue, x: ref vec): KPResult { return x[2]; }) + grammar.add_to_nonterminal(form, vec(call_form), kpNil(), fun(_: ref KPValue, x: ref vec): KPResult { + return x[0]; + }) grammar.set_start_symbol(form) @@ -848,16 +851,20 @@ fun main(argc: int, argv: **char): int { if params.size != 1 { return make_pair(null(), KPResult::Err(kpString(str("Need 1 param to len")))) } - if !params[0].is_array() { - return make_pair(null(), KPResult::Err(kpString(str("Called len with not an array")))) + if !params[0].is_array() && !params[0].is_string() { + return make_pair(null(), KPResult::Err(kpString(str("Called len with not an array/string ") + pr_str(params[0], true)))) + } + if params[0].is_array() { + return make_pair(null(), KPResult::Ok(kpInt(params[0].get_array_rc().get().size))) + } else { + return make_pair(null(), KPResult::Ok(kpInt(params[0].get_string().length()))) } - return make_pair(null(), KPResult::Ok(kpInt(params[0].get_array_rc().get().size))) })); env->set(str("idx"), make_builtin_combiner(str("idx"), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { if params.size != 2 { return make_pair(null(), KPResult::Err(kpString(str("Need 2 params to idx")))) } - if !params[0].is_array() { return make_pair(null(), KPResult::Err(kpString(str("Param 1 to idx is not array")))); } + if !params[0].is_array() { return make_pair(null(), KPResult::Err(kpString(str("Param 1 to idx is not array") + pr_str(params[0], true)))); } if !params[1].is_int() { return make_pair(null(), KPResult::Err(kpString(str("Param 2 to idx is not int")))); } var index = params[1].get_int() @@ -882,13 +889,17 @@ fun main(argc: int, argv: **char): int { if params.size != 3 { return make_pair(null(), KPResult::Err(kpString(str("Need 3 params to slice")))) } - if !params[0].is_array() { return make_pair(null(), KPResult::Err(kpString(str("first param to slice is not array")))); } + if !params[0].is_array() && !params[0].is_string() { return make_pair(null(), KPResult::Err(kpString(str("first param to slice is not string or array")))); } if !params[1].is_int() { return make_pair(null(), KPResult::Err(kpString(str("second param to slice is not int")))); } var start = params[1].get_int(); if !params[2].is_int() { return make_pair(null(), KPResult::Err(kpString(str("third param to slice is not int")))); } var end = params[2].get_int(); - return make_pair(null(), KPResult::Ok(kpArray(params[0].get_array_rc().get().slice(start, end)))) + if params[0].is_array() { + return make_pair(null(), KPResult::Ok(kpArray(params[0].get_array_rc().get().slice(start, end)))) + } else { + return make_pair(null(), KPResult::Ok(kpString(params[0].get_string().slice(start, end)))) + } })); env->set(str("+"), make_builtin_combiner(str("+"), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { diff --git a/k_prime_stdlib/prelude.kp b/k_prime_stdlib/prelude.kp index af96259..09cf5c9 100644 --- a/k_prime_stdlib/prelude.kp +++ b/k_prime_stdlib/prelude.kp @@ -38,6 +38,12 @@ (do (set-idx! n i (f (idx l i))) (recurse f l n (+ i 1) recurse))))) (helper f l (array-with-len (len l)) 0 helper))) +(fun flat_map (f l) + (let (helper (lambda (f l n i recurse) + (if (= i (len l)) + n + (recurse f l (concat n (f (idx l i))) (+ i 1) recurse)))) + (helper f l (array) 0 helper))) (fun map_with_idx (f l) (let (helper (lambda (f l n i recurse) (if (= i (len l)) diff --git a/method.kp b/method.kp index 1181804..bde6354 100644 --- a/method.kp +++ b/method.kp @@ -49,12 +49,25 @@ |_ _ inner _| (construct_body true [do] (map |x| (idx x 0) inner) 0)) ; Call functions with function first, c style (notice no whitespace) -(add_grammar_rule 'form [ 'form 'form ] |f ps| (concat [f] ps)) +(add_grammar_rule 'form [ 'form 'call_form ] |f ps| (concat [f] ps)) ; fun syntax (add_grammar_rule 'form [ "fun" 'WS 'atom 'optional_WS "\\(" 'optional_WS [ 'atom 'optional_WS ] * "\\)" 'optional_WS 'form ] |_ _ name _ _ _ params _ _ body| `(fun ~name (,(map |x| (idx x 0) params)) ~body)) +; string interpolation +fun remove_dollar(done to_do i j) (do (println "remove_dollar" done to_do i j) (cond (>= j (- (len to_do) 2)) done + (= "\\$" (slice to_do j (+ j 2))) (remove_dollar (concat done (slice to_do i j)) to_do (+ j 2) (+ j 2)) + true (remove_dollar done to_do i (+ j 1)))) +fun fixup_str_parts(s) (remove_dollar "" (slice s 0 -2) 0 0) +(add_grammar_rule 'form [ "$\"" [ "(#|[%-[]| |[]-~]|(\\\\)|(\\n)|(\\t)|(\\*)|(\\\\$)| +|[ -!]|(\\\\\"))*$" 'form ] * "(#|[%-[]| |[]-~]|(\\\\)|(\\n)|(\\t)|(\\*)|(\\\\$)| +|[ -!]|(\\\\\"))*\"" ] + |_ string_form_pairs end| `(str ,( flat_map |x| [ (fixup_str_parts (idx x 0)) (idx x 1) ] string_form_pairs) ~(fixup_str_parts end))) + +(println "HAY") +(println $"unu |\$| $$"inner $(+ 1 2) post-inner" sual") +(println "YAAAA") obj Point( x y ) { add |self other| { Point((+ self.x other.x) (+ self.y other.y)) } @@ -79,10 +92,10 @@ fun test() { let p3 = p1.add(p2) let p4 = p1.sub(p2) - println("p1:" p1.to_str()) - println("p2:" p2.to_str()) - println("p3:" p3.to_str()) - println("p4:" p4.to_str()) + println("p1:" p1.to_str) + println("p2:" p2.to_str) + println("p3:" p3.to_str) + println("p4:" p4.to_str) (+ a b) }