1 REM Types library for mal in BBC BASIC
3 REM This library should be the only thing that understands the
4 REM implementation of mal data types in BBC BASIC. All other
5 REM code should use routines in this library to access them.
7 REM As far as other code is concerned, a mal object is just an
8 REM opaque 32-bit integer, which might be a pointer, or might not.
10 REM Following the 8-bit BASIC implementation, we currently have two
11 REM arrays, Z%() containing most objects and S$() containing strings
12 REM (referenced from Z%()).
14 REM See ../basic/mem.in.bas for data representations.
18 DIM Z%(10000), S$(10000)
23 Z%(2) = 1+32: REM false
24 Z%(4) = 1+32: Z%(5) = 1: REM true
25 Z%(6) = 6+32: REM empty list
26 Z%(12) = 8+32: REM empty hashmap
50 DEF FNis_boolean(val%)
53 DEF FNalloc_boolean(bval%)
57 DEF FNunbox_boolean(val%)
58 IF NOT FNis_boolean(val%) THEN ERROR &40E80911, "Not a boolean"
59 IF Z%(val% + 1) THEN =TRUE
67 DEF FNalloc_int(ival%)
75 IF NOT FNis_int(val%) THEN ERROR &40E80912, "Not an integer"
83 DEF FNalloc_symbol(sval$)
93 DEF FNunbox_symbol(val%)
94 IF NOT FNis_symbol(val%) THEN ERROR &40E80915, "Not a symbol"
102 DEF FNalloc_pair(car%, cdr%)
117 IF NOT FNis_list(val%) THEN ERROR &40E80916, "Can't get car of non-list"
118 IF Z%(val% + 1) = 0 THEN ERROR &40E80920, "Can't get car of empty list"
122 IF NOT FNis_list(val%) THEN ERROR &40E80916, "Can't get cdr of non-list"
123 IF Z%(val% + 1) = 0 THEN ERROR &40E80920, "Can't get cdr of empty list"
128 WHILE NOT FNis_empty(val%)
129 val% = FNlist_cdr(val%)
134 DEF PROClist_to_array(val%, a%())
135 REM a%() must already be correctly dimensioned.
137 WHILE NOT FNis_empty(val%)
138 a%(i%) = FNlist_car(val%)
139 val% = FNlist_cdr(val%)
144 REM ** Core functions **
146 DEF FNis_corefn(val%)
149 DEF FNalloc_corefn(fn%)
152 Z%(val% + 0) = 32 + 9
156 DEF FNunbox_corefn(val%)
157 IF NOT FNis_corefn(val%) THEN ERROR &40E80919, "Not a core function"
162 REM To defer implementing mal strings for a bit, hashmap keys are
163 REM currently BASIC strings rather than arbitrary values.
168 DEF FNalloc_hashmap_entry(key$, val%, next%)
175 Z%(entry% + 0) = 32 + 8
176 Z%(entry% + 1) = next%
178 Z%(entry% + 3) = val%
181 DEF FNis_hashmap(val%)
184 DEF FNhashmap_get(map%, key$)
185 IF NOT FNis_hashmap(map%) THEN ERROR &40E80918, "Can't get item from a non-hashmap"
186 IF map% = FNempty_hashmap THEN =FNnil
187 IF S$(Z%(map% + 2)) = key$ THEN =Z%(map% + 3)
188 =FNhashmap_get(Z%(map% + 1), key$)