diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index f93de847..ffb1aaab 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -20,6 +20,57 @@ e_hash_from_string(U64 seed, String8 string) return result; } +internal String8 +e_raw_from_escaped_string(Arena *arena, String8 string) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List strs = {0}; + U64 start = 0; + for(U64 idx = 0; idx <= string.size; idx += 1) + { + if(idx == string.size || string.str[idx] == '\\' || string.str[idx] == '\r') + { + String8 str = str8_substr(string, r1u64(start, idx)); + if(str.size != 0) + { + str8_list_push(scratch.arena, &strs, str); + } + start = idx+1; + } + if(idx < string.size && string.str[idx] == '\\') + { + U8 next_char = string.str[idx+1]; + U8 replace_byte = 0; + switch(next_char) + { + default:{}break; + case 'a': replace_byte = 0x07; break; + case 'b': replace_byte = 0x08; break; + case 'e': replace_byte = 0x1b; break; + case 'f': replace_byte = 0x0c; break; + case 'n': replace_byte = 0x0a; break; + case 'r': replace_byte = 0x0d; break; + case 't': replace_byte = 0x09; break; + case 'v': replace_byte = 0x0b; break; + case '\\':replace_byte = '\\'; break; + case '\'':replace_byte = '\''; break; + case '"': replace_byte = '"'; break; + case '?': replace_byte = '?'; break; + } + String8 replace_string = push_str8_copy(scratch.arena, str8(&replace_byte, 1)); + str8_list_push(scratch.arena, &strs, replace_string); + if(replace_byte == '\\' || replace_byte == '"' || replace_byte == '\'') + { + idx += 1; + start += 1; + } + } + } + String8 result = str8_list_join(arena, &strs, 0); + scratch_end(scratch); + return result; +} + //////////////////////////////// //~ rjf: Message Functions diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 25b67c27..f24564d8 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -113,6 +113,7 @@ struct E_Module //~ rjf: Basic Helper Functions internal U64 e_hash_from_string(U64 seed, String8 string); +internal String8 e_raw_from_escaped_string(Arena *arena, String8 string); //////////////////////////////// //~ rjf: Message Functions diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index ce367699..c5059057 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1698,7 +1698,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') { - U8 char_val = token_string.str[1]; + String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); + String8 char_literal_raw = e_raw_from_escaped_string(scratch.arena, char_literal_escaped); + U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); atom->u64 = (U64)char_val; } @@ -1712,8 +1714,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to case E_TokenKind_StringLiteral: { String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = e_raw_from_escaped_string(arena, string_value_escaped); atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); - atom->string = string_value_escaped; + atom->string = string_value_raw; it += 1; }break; diff --git a/src/metagen/metagen.c b/src/metagen/metagen.c index 8cfc6a3d..7b2e7304 100644 --- a/src/metagen/metagen.c +++ b/src/metagen/metagen.c @@ -142,7 +142,7 @@ mg_escaped_from_str8(Arena *arena, String8 string) String8 str = str8_substr(string, r1u64(start, idx)); if(str.size != 0) { - str8_list_push(arena, &strs, str); + str8_list_push(scratch.arena, &strs, str); } start = idx+1; }