2022-01-24 20:53:37 -05:00
|
|
|
; an "identifier list" is a list of identifiers and 64-bit values associated with them.
|
2022-01-26 18:00:47 -05:00
|
|
|
; they are stored as
|
|
|
|
; null-terminated string
|
|
|
|
; 64-bit value (unaligned)
|
|
|
|
; ...
|
|
|
|
; null-terminated string
|
|
|
|
; 64-bit value (unaligned)
|
|
|
|
; 0 byte
|
2022-01-18 16:29:48 -05:00
|
|
|
|
|
|
|
function ident_list_create
|
|
|
|
argument nbytes
|
|
|
|
local list
|
|
|
|
list = malloc(nbytes)
|
|
|
|
return list
|
|
|
|
|
2022-01-26 14:54:23 -05:00
|
|
|
function ident_list_clear
|
|
|
|
argument list
|
2022-01-26 18:00:47 -05:00
|
|
|
*1list = 0
|
2022-01-26 14:54:23 -05:00
|
|
|
return
|
|
|
|
|
|
|
|
function ident_list_free
|
|
|
|
argument list
|
|
|
|
free(list)
|
|
|
|
return
|
|
|
|
|
|
|
|
function ident_list_len
|
|
|
|
argument list
|
|
|
|
local len
|
|
|
|
len = 0
|
|
|
|
:ilist_len_loop
|
2022-01-26 18:00:47 -05:00
|
|
|
if *1list == 0 goto ilist_len_ret
|
2022-01-26 14:54:23 -05:00
|
|
|
list = memchr(list, 0)
|
|
|
|
list += 9 ; skip null byte and value
|
|
|
|
len += 1
|
|
|
|
goto ilist_len_loop
|
|
|
|
:ilist_len_ret
|
|
|
|
return len
|
|
|
|
|
2022-02-02 14:07:08 -05:00
|
|
|
; idxth value stored in ident list, or 0 if idx >= length
|
2022-01-26 14:54:23 -05:00
|
|
|
function ident_list_value_at_index
|
|
|
|
argument list
|
|
|
|
argument idx
|
|
|
|
:ilist_vai_loop
|
2022-01-26 18:00:47 -05:00
|
|
|
if *1list == 0 goto return_0
|
2022-01-26 14:54:23 -05:00
|
|
|
list = memchr(list, 0)
|
|
|
|
list += 1
|
|
|
|
if idx <= 0 goto ilist_vai_ret
|
|
|
|
list += 8
|
|
|
|
idx -= 1
|
|
|
|
goto ilist_vai_loop
|
|
|
|
:ilist_vai_ret
|
|
|
|
return *8list
|
|
|
|
|
|
|
|
|
2022-01-18 16:29:48 -05:00
|
|
|
function ident_list_add
|
|
|
|
argument list
|
|
|
|
argument ident
|
|
|
|
argument value
|
|
|
|
|
2022-01-25 17:50:00 -05:00
|
|
|
:ilist_add_go_to_end_loop
|
2022-01-26 18:00:47 -05:00
|
|
|
if *1list == 0 goto ilist_add_found_end
|
2022-01-25 17:50:00 -05:00
|
|
|
list = memchr(list, 0)
|
|
|
|
list += 9 ; skip null byte and value
|
|
|
|
goto ilist_add_go_to_end_loop
|
|
|
|
:ilist_add_found_end
|
2022-01-18 16:29:48 -05:00
|
|
|
list = strcpy(list, ident)
|
|
|
|
list += 1
|
|
|
|
*8list = value ; UNALIGNED
|
|
|
|
list += 8
|
2022-01-26 18:00:47 -05:00
|
|
|
*1list = 0
|
2022-01-18 16:29:48 -05:00
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
; return the value associated with this identifier, or 0 if none is
|
|
|
|
function ident_list_lookup
|
|
|
|
argument list
|
|
|
|
argument ident
|
|
|
|
local b
|
|
|
|
:ilist_lookup_loop
|
2022-01-26 18:00:47 -05:00
|
|
|
if *1list == 0 goto return_0
|
2022-01-18 16:29:48 -05:00
|
|
|
b = str_equals(list, ident)
|
|
|
|
list = memchr(list, 0)
|
2022-01-25 17:50:00 -05:00
|
|
|
list += 9 ; skip null byte and value
|
2022-01-18 16:29:48 -05:00
|
|
|
if b == 0 goto ilist_lookup_loop
|
2022-01-25 17:50:00 -05:00
|
|
|
list -= 8 ; backtrack to value
|
2022-01-18 16:29:48 -05:00
|
|
|
return *8list ; UNALIGNED
|
|
|
|
|
2022-02-09 15:50:02 -05:00
|
|
|
; return a pointer to the value associated with ident, or 0 if none is
|
|
|
|
function ident_list_lookup_pointer
|
|
|
|
argument list
|
|
|
|
argument ident
|
|
|
|
local b
|
|
|
|
:ilist_lookup_pointer_loop
|
|
|
|
if *1list == 0 goto return_0
|
|
|
|
b = str_equals(list, ident)
|
|
|
|
list = memchr(list, 0)
|
|
|
|
list += 9 ; skip null byte and value
|
|
|
|
if b == 0 goto ilist_lookup_pointer_loop
|
|
|
|
list -= 8 ; backtrack to value
|
|
|
|
return list
|
|
|
|
|
|
|
|
; if list contains ident, change its value to `value`. otherwise, add ident with the given value.
|
|
|
|
function ident_list_set
|
|
|
|
argument list
|
|
|
|
argument ident
|
|
|
|
argument value
|
|
|
|
local p
|
|
|
|
p = ident_list_lookup_pointer(list, ident)
|
|
|
|
if p == 0 goto ident_list_set_add
|
|
|
|
*8p = value
|
|
|
|
return
|
|
|
|
:ident_list_set_add
|
|
|
|
ident_list_add(list, ident, value)
|
|
|
|
return
|
|
|
|
|
2022-01-24 20:53:37 -05:00
|
|
|
; if identifier in list, sets *pvalue to its value (if pvalue is not null) and returns 1
|
|
|
|
; otherwise, returns 0
|
|
|
|
function ident_list_lookup_check
|
|
|
|
argument list
|
|
|
|
argument ident
|
|
|
|
argument pvalue
|
|
|
|
local b
|
|
|
|
:ilist_lookcheck_loop
|
2022-01-26 18:00:47 -05:00
|
|
|
if *1list == 0 goto return_0
|
2022-01-24 20:53:37 -05:00
|
|
|
b = str_equals(list, ident)
|
|
|
|
list = memchr(list, 0)
|
2022-01-25 17:50:00 -05:00
|
|
|
list += 9 ; skip null byte and value
|
2022-01-24 20:53:37 -05:00
|
|
|
if b == 0 goto ilist_lookcheck_loop
|
|
|
|
if pvalue == 0 goto return_1
|
2022-01-25 17:50:00 -05:00
|
|
|
list -= 8 ; backtrack to value
|
2022-01-24 20:53:37 -05:00
|
|
|
*8pvalue = *8list
|
|
|
|
return 1
|
|
|
|
|
2022-01-18 16:29:48 -05:00
|
|
|
function ident_list_print
|
|
|
|
argument list
|
|
|
|
:ilist_print_loop
|
2022-01-26 18:00:47 -05:00
|
|
|
if *1list == 0 goto ilist_print_loop_end
|
2022-01-18 16:29:48 -05:00
|
|
|
puts(list)
|
|
|
|
putc(':)
|
|
|
|
putc(32)
|
|
|
|
list = memchr(list, 0)
|
|
|
|
list += 1
|
2022-01-28 15:07:23 -05:00
|
|
|
putnln(*8list)
|
2022-01-18 16:29:48 -05:00
|
|
|
list += 8
|
|
|
|
goto ilist_print_loop
|
|
|
|
:ilist_print_loop_end
|
|
|
|
return
|
2022-01-28 15:07:23 -05:00
|
|
|
|
|
|
|
function ident_list_printx64
|
|
|
|
argument list
|
|
|
|
:ilist_printx64_loop
|
|
|
|
if *1list == 0 goto ilist_printx64_loop_end
|
|
|
|
puts(list)
|
|
|
|
putc(':)
|
|
|
|
putc(32)
|
|
|
|
list = memchr(list, 0)
|
|
|
|
list += 1
|
|
|
|
putx64ln(*8list)
|
|
|
|
list += 8
|
|
|
|
goto ilist_printx64_loop
|
|
|
|
:ilist_printx64_loop_end
|
|
|
|
return
|
|
|
|
|
|
|
|
function ident_list_printx32
|
|
|
|
argument list
|
|
|
|
:ilist_printx32_loop
|
|
|
|
if *1list == 0 goto ilist_printx32_loop_end
|
|
|
|
puts(list)
|
|
|
|
putc(':)
|
|
|
|
putc(32)
|
|
|
|
list = memchr(list, 0)
|
|
|
|
list += 1
|
|
|
|
putx32ln(*8list)
|
|
|
|
list += 8
|
|
|
|
goto ilist_printx32_loop
|
|
|
|
:ilist_printx32_loop_end
|
|
|
|
return
|
|
|
|
|