lang-bootstrap/05/idents.b
pommicket d74dc53b0b more parsing tests, fixed more bugs
- we now handle incomplete structs properly
- small fix in for loop printing
2022-02-09 15:50:02 -05:00

178 lines
3.7 KiB
Brainfuck

; an "identifier list" is a list of identifiers and 64-bit values associated with them.
; they are stored as
; null-terminated string
; 64-bit value (unaligned)
; ...
; null-terminated string
; 64-bit value (unaligned)
; 0 byte
function ident_list_create
argument nbytes
local list
list = malloc(nbytes)
return list
function ident_list_clear
argument list
*1list = 0
return
function ident_list_free
argument list
free(list)
return
function ident_list_len
argument list
local len
len = 0
:ilist_len_loop
if *1list == 0 goto ilist_len_ret
list = memchr(list, 0)
list += 9 ; skip null byte and value
len += 1
goto ilist_len_loop
:ilist_len_ret
return len
; idxth value stored in ident list, or 0 if idx >= length
function ident_list_value_at_index
argument list
argument idx
:ilist_vai_loop
if *1list == 0 goto return_0
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
function ident_list_add
argument list
argument ident
argument value
:ilist_add_go_to_end_loop
if *1list == 0 goto ilist_add_found_end
list = memchr(list, 0)
list += 9 ; skip null byte and value
goto ilist_add_go_to_end_loop
:ilist_add_found_end
list = strcpy(list, ident)
list += 1
*8list = value ; UNALIGNED
list += 8
*1list = 0
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
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_loop
list -= 8 ; backtrack to value
return *8list ; UNALIGNED
; 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
; 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
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_lookcheck_loop
if pvalue == 0 goto return_1
list -= 8 ; backtrack to value
*8pvalue = *8list
return 1
function ident_list_print
argument list
:ilist_print_loop
if *1list == 0 goto ilist_print_loop_end
puts(list)
putc(':)
putc(32)
list = memchr(list, 0)
list += 1
putnln(*8list)
list += 8
goto ilist_print_loop
:ilist_print_loop_end
return
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