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)
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 { //"
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<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> {
if params.size != 1 {
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 {
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")))); }
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<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> {
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