summaryrefslogtreecommitdiff
path: root/05/idents.b
blob: 11155d744d36307651f18a6ab7fa990ac5a217b6 (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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
; 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

; 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