2 Copyright (C) 2017 Keziah Wesley
4 You can redistribute and/or modify this file under the terms of the
5 GNU Affero General Public License as published by the Free Software
6 Foundation, either version 3 of the License, or (at your option) any
9 This file is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Affero General Public License for more details.
14 You should have received a copy of the GNU Affero General Public
15 License along with this file. If not, see
16 <http://www.gnu.org/licenses/>.
29 // Return the number of whitespace characters at the beginning of the input.
31 count_whitespace (const char *p)
51 // Return the number of characters at the beginning of the input
52 // constituting a valid PNAME.
53 // If the input ends with '\', it is incomplete, and -1 is returned.
55 count_pname (const char *p)
57 // rule (1): valid FLOAT / FIX isn't a PNAME.
58 // Caller must try to read as number first!
60 // rule (2): dot can't be first
64 // rule (3): "if you can't type it interactively, it's only valid non-interactively"
65 // (not currently enforced; just don't give your atoms names like ^L)
71 // separators end the PNAME
72 // rule (4): whitespace
73 // rule (5): special characters
97 // escape: next char becomes normal
110 static uint32_t obj_get_fix32(const object *o) {
111 assert(o->type == EVALTYPE_FIX32);
116 // stack[0..len]: objs in current list
117 // stack[len]: parent len
119 read_token (const char *p, reader_stack * st)
121 p += count_whitespace (p);
130 // opener: push current framelen; start new frame
131 // store child type and parent framelen in a pseudo-object together
136 type = EVALTYPE_LIST;
139 type = EVALTYPE_FORM;
142 type = EVALTYPE_VECTOR;
145 assert (0 && "martian opener token?");
147 *--(st->pos) = (object)
149 .fix32.type = type,.fix32.rest = 0,.fix32.val = st->framelen,};
160 type = EVALTYPE_LIST;
163 type = EVALTYPE_FORM;
166 assert (0 && "martian list closer token?");
168 // build list from current stack frame
170 pool_copy_array_rev ((pool_object *) st->pos, st->framelen);
171 // pop frame, push new LIST
172 st->pos += st->framelen;
173 assert (st->pos->type == type);
174 st->framelen = st->pos->fix32.val + 1;
175 // overwrite the frame marker with the collection it became
176 st->pos->list = (list_object)
178 .type = type,.rest = 0,.head = o};
184 // build vector from current stack frame
185 heap_ptr h = heap_copy_array_rev (st->pos, st->framelen);
186 // pop frame, push new VECTOR
187 uint32_t len = st->framelen;
188 st->pos += st->framelen;
189 assert (st->pos->type == EVALTYPE_VECTOR);
190 st->framelen = st->pos->fix32.val + 1;
191 st->pos->vector = new_vector (h, len);
197 // push fix obj, extending frame
198 (--(st->pos))->fix64 = new_fix64 (4);
203 fprintf (stderr, "read unimplemented for char: '%c'\n", *p);
204 assert (0 && "read unimplemented for char");