mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
[xml] Slight optimization.
About a 5% speed bump. More rigorous optimization later.
This commit is contained in:
@@ -110,44 +110,51 @@ error :: proc(t: ^Tokenizer, offset: int, msg: string, args: ..any) {
|
|||||||
t.error_count += 1
|
t.error_count += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(optimization_mode="speed")
|
||||||
advance_rune :: proc(using t: ^Tokenizer) {
|
advance_rune :: proc(using t: ^Tokenizer) {
|
||||||
if read_offset < len(src) {
|
#no_bounds_check {
|
||||||
offset = read_offset
|
/*
|
||||||
if ch == '\n' {
|
Already bounds-checked here.
|
||||||
line_offset = offset
|
*/
|
||||||
line_count += 1
|
if read_offset < len(src) {
|
||||||
}
|
offset = read_offset
|
||||||
r, w := rune(src[read_offset]), 1
|
if ch == '\n' {
|
||||||
switch {
|
line_offset = offset
|
||||||
case r == 0:
|
line_count += 1
|
||||||
error(t, t.offset, "illegal character NUL")
|
|
||||||
case r >= utf8.RUNE_SELF:
|
|
||||||
r, w = utf8.decode_rune_in_string(src[read_offset:])
|
|
||||||
if r == utf8.RUNE_ERROR && w == 1 {
|
|
||||||
error(t, t.offset, "illegal UTF-8 encoding")
|
|
||||||
} else if r == utf8.RUNE_BOM && offset > 0 {
|
|
||||||
error(t, t.offset, "illegal byte order mark")
|
|
||||||
}
|
}
|
||||||
|
r, w := rune(src[read_offset]), 1
|
||||||
|
switch {
|
||||||
|
case r == 0:
|
||||||
|
error(t, t.offset, "illegal character NUL")
|
||||||
|
case r >= utf8.RUNE_SELF:
|
||||||
|
r, w = #force_inline utf8.decode_rune_in_string(src[read_offset:])
|
||||||
|
if r == utf8.RUNE_ERROR && w == 1 {
|
||||||
|
error(t, t.offset, "illegal UTF-8 encoding")
|
||||||
|
} else if r == utf8.RUNE_BOM && offset > 0 {
|
||||||
|
error(t, t.offset, "illegal byte order mark")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
read_offset += w
|
||||||
|
ch = r
|
||||||
|
} else {
|
||||||
|
offset = len(src)
|
||||||
|
if ch == '\n' {
|
||||||
|
line_offset = offset
|
||||||
|
line_count += 1
|
||||||
|
}
|
||||||
|
ch = -1
|
||||||
}
|
}
|
||||||
read_offset += w
|
|
||||||
ch = r
|
|
||||||
} else {
|
|
||||||
offset = len(src)
|
|
||||||
if ch == '\n' {
|
|
||||||
line_offset = offset
|
|
||||||
line_count += 1
|
|
||||||
}
|
|
||||||
ch = -1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
peek_byte :: proc(t: ^Tokenizer, offset := 0) -> byte {
|
peek_byte :: proc(t: ^Tokenizer, offset := 0) -> byte {
|
||||||
if t.read_offset+offset < len(t.src) {
|
if t.read_offset+offset < len(t.src) {
|
||||||
return t.src[t.read_offset+offset]
|
#no_bounds_check return t.src[t.read_offset+offset]
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(optimization_mode="speed")
|
||||||
skip_whitespace :: proc(t: ^Tokenizer) {
|
skip_whitespace :: proc(t: ^Tokenizer) {
|
||||||
for {
|
for {
|
||||||
switch t.ch {
|
switch t.ch {
|
||||||
@@ -159,6 +166,7 @@ skip_whitespace :: proc(t: ^Tokenizer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(optimization_mode="speed")
|
||||||
is_letter :: proc(r: rune) -> bool {
|
is_letter :: proc(r: rune) -> bool {
|
||||||
if r < utf8.RUNE_SELF {
|
if r < utf8.RUNE_SELF {
|
||||||
switch r {
|
switch r {
|
||||||
@@ -177,6 +185,7 @@ is_valid_identifier_rune :: proc(r: rune) -> bool {
|
|||||||
case '_', '-', ':': return true
|
case '_', '-', ':': return true
|
||||||
case 'A'..='Z', 'a'..='z': return true
|
case 'A'..='Z', 'a'..='z': return true
|
||||||
case '0'..'9': return true
|
case '0'..'9': return true
|
||||||
|
case -1: return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,6 +214,7 @@ scan_identifier :: proc(t: ^Tokenizer) -> string {
|
|||||||
return string(t.src[offset : t.offset])
|
return string(t.src[offset : t.offset])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(optimization_mode="speed")
|
||||||
scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close := false, multiline := true) -> (value: string, err: Error) {
|
scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close := false, multiline := true) -> (value: string, err: Error) {
|
||||||
err = .None
|
err = .None
|
||||||
in_cdata := false
|
in_cdata := false
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err
|
|||||||
/*
|
/*
|
||||||
Consume peeked `<`
|
Consume peeked `<`
|
||||||
*/
|
*/
|
||||||
tok := scan(t)
|
advance_rune(t)
|
||||||
|
|
||||||
open := scan(t)
|
open := scan(t)
|
||||||
#partial switch open.kind {
|
#partial switch open.kind {
|
||||||
@@ -265,7 +265,7 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err
|
|||||||
skip_element(t) or_return
|
skip_element(t) or_return
|
||||||
}
|
}
|
||||||
case:
|
case:
|
||||||
error(t, t.offset, "Expected \"<?xml\", got \"<?%v\".", tok.text)
|
error(t, t.offset, "Expected \"<?xml\", got \"<?%v\".", next.text)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user