Fix some longstanding string bugs and stop cheating with read-string in standard_grammer, implementing both unescape and string-to-int in k'

This commit is contained in:
Nathan Braswell
2021-01-04 00:11:15 -05:00
parent 6c0a46099a
commit ddd5ce7032
2 changed files with 53 additions and 8 deletions

View File

@@ -692,13 +692,17 @@ fun main(argc: int, argv: **char): int {
grammar.add_to_nonterminal(optional_WS, vec(WS), kpNil(), ret_nil_sym) 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<int>(input.slice(l,r)))); })), kpNil(), ret_0_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<int>(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 { //" |[ -!]|(\\\\\"))*\"", kpNil(), fun(_: ref KPValue, input: ref str, l: int, r: int): KPResult { //"
var to_ret = str() var to_ret = str()
for (var i = l+1; i < r-1; i++;) { for (var i = l+1; i < r-1; i++;) {
if input[i] == '\\' { if input[i] == '\\' {
if input[i+1] == 'n' { if input[i+1] == 'n' {
to_ret += '\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] == '"' { } else if input[i+1] == '\\' || input[i+1] == '"' {
to_ret += input[i+1] to_ret += input[i+1]
} else { } else {
@@ -846,6 +850,16 @@ 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("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 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to str-to-symbol"))))
}
if !params[0].is_string() {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Called get-text with not a symbol"))))
}
return make_pair(null<KPEnv>(), KPResult::Ok(kpSymbol(params[0].get_string())))
}));
env->set(str("get-text"), make_builtin_combiner(str("get-text"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("get-text"), make_builtin_combiner(str("get-text"), 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 get-text")))) return make_pair(null<KPEnv>(), 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 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to idx")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to idx"))))
} }
if !params[0].is_array() { return make_pair(null<KPEnv>(), 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<KPEnv>(), 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<KPEnv>(), KPResult::Err(kpString(str("Param 2 to idx is not int")))); } if !params[1].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Param 2 to idx is not int")))); }
var index = params[1].get_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 index += params[0].get_array_rc().get().size
} }
return make_pair(null<KPEnv>(), KPResult::Ok(params[0].get_array_rc().get()[index])) if params[0].is_array() {
return make_pair(null<KPEnv>(), KPResult::Ok(params[0].get_array_rc().get()[index]))
} else {
return make_pair(null<KPEnv>(), 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<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("set-idx!"), make_builtin_combiner(str("set-idx!"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 3 { if params.size != 3 {
@@ -949,7 +967,7 @@ fun main(argc: int, argv: **char): int {
for (var i = 0; i < params.size; i++;) { for (var i = 0; i < params.size; i++;) {
match (params[i].internal) { match (params[i].internal) {
KPValue_int::Int(v) { KPValue_int::Int(v) {
if i == 0 { if i == 0 && params.size > 1 {
to_ret += v to_ret += v
} else { } else {
to_ret -= v to_ret -= v

View File

@@ -149,6 +149,33 @@
print_through 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))))) 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 ( scope_let (let-vrec (
with_import (vau de (lib_path code) with_import (vau de (lib_path code)
(let (imported_scope_let (eval (concat (let (imported_scope_let (eval (concat
@@ -161,13 +188,13 @@
(array (quote WS) (array "( | | (array (quote WS) (array "( | |
|(;[ -~]* |(;[ -~]*
))+") (lambda (x) nil)) ))+") (lambda (x) nil))
(array (quote atom) (array "-?[0-9]+") (lambda (x) (do (println "read-str for number") (read-string x)))) (array (quote atom) (array "-?[0-9]+") (lambda (x) (string-to-int x)))
(array (quote atom) (array "\"([#-[]| |[]-~]|(\\\\)|(\\n)|(\\t)|(\\\\*)|(\\0)| (array (quote atom) (array "\"([#-[]| |[]-~]|(\\\\\\\\)|(\\\\n)|(\\\\t)|(\\*)|(\\\\0)|
|[ -!]|(\\\\\"))*\"") (lambda (x) (do (println "read-str for string") (read-string x)))) |[ -!]|(\\\\\"))*\"") (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 (array (quote atom) (array "-|(([a-z]|[A-Z]|_|\\*|/|\\?|\\+|!|=|&|<|>|%)([a-z]|[A-Z]|_|[0-9]|\\*|\\?|\\+|-|!|=|&|<|>|%)*)") (lambda (x) (cond (= "true" x) true
(= "false" x) false (= "false" x) false
(= "nil" x) nil (= "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 atom)) (lambda (x) x))
(array (quote form) (array "\\(" (quote WS) * "\\)" ) (lambda (_ _ _) (array))) (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)))) (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))))