better escape code support

This commit is contained in:
2026-08-11 21:16:25 +02:00
parent c2343b54bb
commit 378eb637c6
5 changed files with 63 additions and 15 deletions
+17 -5
View File
@@ -8,6 +8,10 @@ is_identifier_start :: proc(value: byte) -> bool {
return value == '_' || value >= 'a' && value <= 'z' || value >= 'A' && value <= 'Z'
}
is_hex_digit :: proc(value: byte) -> bool {
return value >= '0' && value <= '9' || value >= 'a' && value <= 'f' || value >= 'A' && value <= 'F'
}
is_identifier_continue :: proc(value: byte) -> bool {
return is_identifier_start(value) || value >= '0' && value <= '9'
}
@@ -319,13 +323,21 @@ lex :: proc(
for cursor < len(bytes) && bytes[cursor] != '"' && bytes[cursor] != '\n' {
if bytes[cursor] == '\\' {
cursor += 1
if cursor >= len(bytes) ||
(bytes[cursor] != '\\' && bytes[cursor] != '"' && bytes[cursor] != 'n' &&
bytes[cursor] != 'r' && bytes[cursor] != 't' && bytes[cursor] != '0') {
valid_escape := cursor < len(bytes) &&
(bytes[cursor] == '\\' || bytes[cursor] == '"' || bytes[cursor] == 'n' ||
bytes[cursor] == 'r' || bytes[cursor] == 't' || bytes[cursor] == '0')
if cursor < len(bytes) && bytes[cursor] == 'x' {
valid_escape = cursor+2 < len(bytes) &&
is_hex_digit(bytes[cursor+1]) && is_hex_digit(bytes[cursor+2])
if valid_escape {
cursor += 2
}
}
if !valid_escape {
source.add(
diagnostics,
source.Span{file=source_file.id, start=source.Offset(max(cursor-1, start)), end=source.Offset(min(cursor+1, len(bytes)))},
"strings only support '\\\\', '\\\"', '\\n', '\\r', '\\t', and '\\0' escapes",
source.Span{file=source_file.id, start=source.Offset(max(cursor-1, start)), end=source.Offset(min(cursor+3, len(bytes)))},
"strings only support '\\\\', '\\\"', '\\n', '\\r', '\\t', '\\0', and '\\xNN' escapes",
)
valid = false
}
+13
View File
@@ -219,6 +219,16 @@ decode_character :: proc(parser: ^Parser, tok: token.Token) -> (u64, bool) {
return u64(value), width == len(contents)
}
decode_hex_digit :: proc(value: byte) -> byte {
if value >= '0' && value <= '9' {
return value - '0'
}
if value >= 'a' && value <= 'f' {
return value - 'a' + 10
}
return value - 'A' + 10
}
parse_type_constant :: proc(parser: ^Parser) -> (u64, bool) {
negative := false
if _, ok := allow(parser, .Minus); ok {
@@ -3243,6 +3253,9 @@ decode_import_path :: proc(parser: ^Parser, tok: token.Token) -> string {
case 'r': value = '\r'
case 't': value = '\t'
case '0': value = 0
case 'x':
value = decode_hex_digit(text[index+1])*16 + decode_hex_digit(text[index+2])
index += 2
case:
}
}