summaryrefslogtreecommitdiff
path: root/05/idents.b
blob: 0deaf3588cfad27efe76b4cf084be58e878df27f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
; an "identifier list" is a list of identifiers and 64-bit values associated with them.

function ident_list_create
	argument nbytes
	local list
	list = malloc(nbytes)
	*1list = 255
	return list

function ident_list_add
	argument list
	argument ident
	argument value
	
	; note: we can't just do list = memchr(list, 255) because values
	; might have a 255 byte.
	:ilist_add_go_to_end_loop
		if *1list == 255 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 = 255
	
	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 == 255 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

; 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 == 255 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 == 255 goto ilist_print_loop_end
		puts(list)
		putc(':)
		putc(32)
		list = memchr(list, 0)
		list += 1
		putn(*8list)
		list += 8
		goto ilist_print_loop
	:ilist_print_loop_end
	return