diff --git a/k_prime.krak b/k_prime.krak index 840271d..ef920cd 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -692,13 +692,17 @@ fun main(argc: int, argv: **char): int { grammar.add_to_nonterminal(optional_WS, vec(WS), kpNil(), ret_nil_sym) var atom = grammar.add_new_nonterminal("atom", vec(grammar.add_terminal("-?[0-9]+", kpNil(), fun(_: ref KPValue, input: ref str, l: int, r: int): KPResult { return KPResult::Ok(kpInt(string_to_num(input.slice(l,r)))); })), kpNil(), ret_0_sym) - grammar.add_to_nonterminal(atom, vec(grammar.add_terminal("\"([#-[]| |[]-~]|(\\\\)|(\\n)|(\\t)|(\\\*)|(\\0)| + grammar.add_to_nonterminal(atom, vec(grammar.add_terminal("\"([#-[]| |[]-~]|(\\\\\\\\)|(\\\\n)|(\\\\t)|(\\*)|(\\\\0)| |[ -!]|(\\\\\"))*\"", kpNil(), fun(_: ref KPValue, input: ref str, l: int, r: int): KPResult { //" var to_ret = str() for (var i = l+1; i < r-1; i++;) { if input[i] == '\\' { if input[i+1] == 'n' { to_ret += '\n' + } else if input[i+1] == 't' { + to_ret += '\t' + } else if input[i+1] == '0' { + to_ret += '\0' } else if input[i+1] == '\\' || input[i+1] == '"' { to_ret += input[i+1] } else { @@ -846,6 +850,16 @@ fun main(argc: int, argv: **char): int { return make_pair(null(), KPResult::Ok(kpBool(params[0].is_symbol()))) })); + env->set(str("str-to-symbol"), make_builtin_combiner(str("str-to-symbol"), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { + if params.size != 1 { + return make_pair(null(), KPResult::Err(kpString(str("Need 1 param to str-to-symbol")))) + } + if !params[0].is_string() { + return make_pair(null(), KPResult::Err(kpString(str("Called get-text with not a symbol")))) + } + return make_pair(null(), KPResult::Ok(kpSymbol(params[0].get_string()))) + })); + env->set(str("get-text"), make_builtin_combiner(str("get-text"), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { if params.size != 1 { return make_pair(null(), KPResult::Err(kpString(str("Need 1 param to get-text")))) @@ -893,7 +907,7 @@ fun main(argc: int, argv: **char): int { 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") + pr_str(params[0], true)))); } + if !params[0].is_array() && !params[0].is_string() { return make_pair(null(), KPResult::Err(kpString(str("Param 1 to idx is not string or 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() @@ -901,7 +915,11 @@ fun main(argc: int, argv: **char): int { index += params[0].get_array_rc().get().size } - return make_pair(null(), KPResult::Ok(params[0].get_array_rc().get()[index])) + if params[0].is_array() { + return make_pair(null(), KPResult::Ok(params[0].get_array_rc().get()[index])) + } else { + return make_pair(null(), KPResult::Ok(kpInt((params[0].get_string()[index]) cast int))) + } })); env->set(str("set-idx!"), make_builtin_combiner(str("set-idx!"), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { if params.size != 3 { @@ -949,7 +967,7 @@ fun main(argc: int, argv: **char): int { for (var i = 0; i < params.size; i++;) { match (params[i].internal) { KPValue_int::Int(v) { - if i == 0 { + if i == 0 && params.size > 1 { to_ret += v } else { to_ret -= v diff --git a/prelude.kp b/prelude.kp index bc17e80..e997f84 100644 --- a/prelude.kp +++ b/prelude.kp @@ -149,6 +149,33 @@ print_through ) insert_into_scope_let (lambda (scope_let name item) (array (idx scope_let 0) (concat (idx scope_let 1) (array name (array quote item))))) + string-to-int (lambda (s) (let ( + helper (rec-lambda recurse (s i result) + (if (< i (len s)) + (recurse s (+ i 1) (+ (* 10 result) (- (idx s i) (idx "0" 0)))) + result + ) + )) + (if (= (idx s 0) (idx "-" 0)) + (- (helper s 1 0)) + (helper s 0 0) + ))) + + unescape-str (lambda (s) (let ( + helper (rec-lambda recurse (s i r) + (cond (>= (+ 1 i) (len s)) r + (= (idx s i) (idx "\\" 0)) (cond (= (+ i 1) (len s)) "BAD ESCAPE AT END" + (= (idx s (+ i 1)) (idx "n" 0)) (recurse s (+ i 2) (str r "\n")) + (= (idx s (+ i 1)) (idx "t" 0)) (recurse s (+ i 2) (str r "\t")) + (= (idx s (+ i 1)) (idx "0" 0)) (recurse s (+ i 2) (str r "\0")) + (= (idx s (+ i 1)) (idx "\\" 0)) (recurse s (+ i 2) (str r "\\")) + (= (idx s (+ i 1)) (idx "\"" 0)) (recurse s (+ i 2) (str r "\"")) + true "BAD ESCAPE IS NORMAL CHAR" + ) + true (recurse s (+ i 1) (str r (slice s i (+ i 1)))) + ) + )) (helper s 1 ""))) + scope_let (let-vrec ( with_import (vau de (lib_path code) (let (imported_scope_let (eval (concat @@ -161,13 +188,13 @@ (array (quote WS) (array "( | | |(;[ -~]* ))+") (lambda (x) nil)) - (array (quote atom) (array "-?[0-9]+") (lambda (x) (do (println "read-str for number") (read-string x)))) - (array (quote atom) (array "\"([#-[]| |[]-~]|(\\\\)|(\\n)|(\\t)|(\\\\*)|(\\0)| -|[ -!]|(\\\\\"))*\"") (lambda (x) (do (println "read-str for string") (read-string x)))) + (array (quote atom) (array "-?[0-9]+") (lambda (x) (string-to-int x))) + (array (quote atom) (array "\"([#-[]| |[]-~]|(\\\\\\\\)|(\\\\n)|(\\\\t)|(\\*)|(\\\\0)| +|[ -!]|(\\\\\"))*\"") (lambda (x) (unescape-str x))) (array (quote atom) (array "-|(([a-z]|[A-Z]|_|\\*|/|\\?|\\+|!|=|&|<|>|%)([a-z]|[A-Z]|_|[0-9]|\\*|\\?|\\+|-|!|=|&|<|>|%)*)") (lambda (x) (cond (= "true" x) true (= "false" x) false (= "nil" x) nil - true (do (println "read-string for atom") (read-string x))))) + true (str-to-symbol x)))) (array (quote form) (array (quote atom)) (lambda (x) x)) (array (quote form) (array "\\(" (quote WS) * "\\)" ) (lambda (_ _ _) (array))) (array (quote form) (array "\\(" (quote WS) * (quote form) (array (quote WS) + (quote form)) * (quote WS) * "\\)" ) (lambda (_ _ head tail _ _) (concat (array head) (map (lambda (x) (idx x 1)) tail))))