blob: 50da78a0f46399e7a4a3141ae613705a4fbb916c [file] [log] [blame]
swissChili7a6f5eb2021-04-13 16:46:02 -07001#include "lisp.h"
swissChili8cfb7c42021-04-18 21:17:58 -07002#include "plat/plat.h"
3
swissChili7a6f5eb2021-04-13 16:46:02 -07004#include <ctype.h>
5#include <stdbool.h>
6#include <stdio.h>
swissChilibed80922021-04-13 21:58:05 -07007#include <stdlib.h>
8#include <string.h>
swissChili7a6f5eb2021-04-13 16:46:02 -07009
swissChili9e57da42021-06-15 22:22:46 -070010struct alloc *first_a = NULL, *last_a = NULL;
swissChili7a6f5eb2021-04-13 16:46:02 -070011
swissChili8cfb7c42021-04-18 21:17:58 -070012value_t nil = 0b00101111; // magic ;)
swissChili923b5362021-05-09 20:31:43 -070013value_t t = 1 << 3;
swissChilibed80922021-04-13 21:58:05 -070014
swissChili53472e82021-05-08 16:06:32 -070015void err(const char *msg)
swissChilibed80922021-04-13 21:58:05 -070016{
swissChili53472e82021-05-08 16:06:32 -070017 fprintf(stderr, "ERROR: %s\n", msg);
18 exit(1);
swissChilibed80922021-04-13 21:58:05 -070019}
20
swissChili53472e82021-05-08 16:06:32 -070021value_t intval(int i)
swissChili7a6f5eb2021-04-13 16:46:02 -070022{
swissChili8cfb7c42021-04-18 21:17:58 -070023 i <<= 2;
24 i |= INT_TAG;
25 return i;
26}
27
swissChili53472e82021-05-08 16:06:32 -070028value_t cons(value_t car, value_t cdr)
swissChili8cfb7c42021-04-18 21:17:58 -070029{
swissChili9e57da42021-06-15 22:22:46 -070030 struct cons_alloc *item = malloc_aligned(sizeof(struct cons_alloc));
31 struct cons *c = &item->cons;
swissChili7a6f5eb2021-04-13 16:46:02 -070032
swissChilibed80922021-04-13 21:58:05 -070033 c->car = car;
34 c->cdr = cdr;
35
swissChili9e57da42021-06-15 22:22:46 -070036 item->alloc.type_tag = T_CONS;
swissChili7a6f5eb2021-04-13 16:46:02 -070037
swissChili53472e82021-05-08 16:06:32 -070038 if (last_a)
swissChili7a6f5eb2021-04-13 16:46:02 -070039 {
swissChili9e57da42021-06-15 22:22:46 -070040 item->alloc.prev = last_a;
swissChili7a6f5eb2021-04-13 16:46:02 -070041 last_a->next = item;
swissChili9e57da42021-06-15 22:22:46 -070042 item->alloc.next = NULL;
swissChili7a6f5eb2021-04-13 16:46:02 -070043 }
44 else
45 {
swissChili9e57da42021-06-15 22:22:46 -070046 item->alloc.prev = item->alloc.next = NULL;
swissChili7a6f5eb2021-04-13 16:46:02 -070047 first_a = last_a = item;
48 }
49
swissChilib3ca4fb2021-04-20 10:33:00 -070050 value_t v = (value_t)c;
swissChili8cfb7c42021-04-18 21:17:58 -070051 v |= CONS_TAG;
swissChili7a6f5eb2021-04-13 16:46:02 -070052
53 return v;
54}
55
swissChili53472e82021-05-08 16:06:32 -070056void skipws(struct istream *is)
swissChili7a6f5eb2021-04-13 16:46:02 -070057{
swissChili53472e82021-05-08 16:06:32 -070058 while (isspace(is->peek(is)))
59 is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -070060}
61
swissChili53472e82021-05-08 16:06:32 -070062bool isallowedchar(char c)
swissChili7a6f5eb2021-04-13 16:46:02 -070063{
swissChilibed80922021-04-13 21:58:05 -070064 return (c >= '#' && c <= '\'') || (c >= '*' && c <= '/') ||
65 (c >= '>' && c <= '@');
swissChili7a6f5eb2021-04-13 16:46:02 -070066}
67
swissChili53472e82021-05-08 16:06:32 -070068bool issymstart(char c)
swissChili7a6f5eb2021-04-13 16:46:02 -070069{
swissChili53472e82021-05-08 16:06:32 -070070 return isalpha(c) || isallowedchar(c);
swissChili7a6f5eb2021-04-13 16:46:02 -070071}
72
swissChili53472e82021-05-08 16:06:32 -070073bool issym(char c)
swissChili7a6f5eb2021-04-13 16:46:02 -070074{
swissChili53472e82021-05-08 16:06:32 -070075 return isalpha(c) || isallowedchar(c) || isdigit(c);
swissChili7a6f5eb2021-04-13 16:46:02 -070076}
77
swissChili53472e82021-05-08 16:06:32 -070078bool readsym(struct istream *is, value_t *val)
swissChili7a6f5eb2021-04-13 16:46:02 -070079{
swissChili53472e82021-05-08 16:06:32 -070080 skipws(is);
swissChili7a6f5eb2021-04-13 16:46:02 -070081
swissChili53472e82021-05-08 16:06:32 -070082 if (!issymstart(is->peek(is)))
swissChili7a6f5eb2021-04-13 16:46:02 -070083 return false;
84
85 int size = 8;
swissChili53472e82021-05-08 16:06:32 -070086 char *s = malloc_aligned(size);
swissChili7a6f5eb2021-04-13 16:46:02 -070087
swissChili53472e82021-05-08 16:06:32 -070088 s[0] = is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -070089
swissChili53472e82021-05-08 16:06:32 -070090 for (int i = 1;; i++)
swissChili7a6f5eb2021-04-13 16:46:02 -070091 {
swissChili53472e82021-05-08 16:06:32 -070092 if (issym(is->peek(is)))
swissChili7a6f5eb2021-04-13 16:46:02 -070093 {
swissChili53472e82021-05-08 16:06:32 -070094 if (i >= size)
swissChili7a6f5eb2021-04-13 16:46:02 -070095 {
96 size *= 2;
swissChili53472e82021-05-08 16:06:32 -070097 s = realloc_aligned(s, size);
swissChili7a6f5eb2021-04-13 16:46:02 -070098 }
99
swissChili53472e82021-05-08 16:06:32 -0700100 s[i] = is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700101 }
102 else
103 {
swissChili53472e82021-05-08 16:06:32 -0700104 s[i] = 0;
swissChilib3ca4fb2021-04-20 10:33:00 -0700105 *val = (value_t)s;
swissChili8cfb7c42021-04-18 21:17:58 -0700106 *val |= SYMBOL_TAG;
swissChili7a6f5eb2021-04-13 16:46:02 -0700107
108 return true;
109 }
110 }
111}
112
swissChili53472e82021-05-08 16:06:32 -0700113bool readstr(struct istream *is, value_t *val)
swissChili7a6f5eb2021-04-13 16:46:02 -0700114{
swissChili53472e82021-05-08 16:06:32 -0700115 skipws(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700116
swissChili53472e82021-05-08 16:06:32 -0700117 if (is->peek(is) != '"')
swissChili7a6f5eb2021-04-13 16:46:02 -0700118 return false;
119
120 bool escape = false;
121 int size = 8;
swissChili53472e82021-05-08 16:06:32 -0700122 char *s = malloc_aligned(size);
swissChili7a6f5eb2021-04-13 16:46:02 -0700123
swissChili53472e82021-05-08 16:06:32 -0700124 (void)is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700125
swissChili53472e82021-05-08 16:06:32 -0700126 for (int i = 0;; i++)
swissChili7a6f5eb2021-04-13 16:46:02 -0700127 {
swissChili53472e82021-05-08 16:06:32 -0700128 if (is->peek(is) != '"')
swissChili7a6f5eb2021-04-13 16:46:02 -0700129 {
swissChili53472e82021-05-08 16:06:32 -0700130 if (i >= size)
swissChili7a6f5eb2021-04-13 16:46:02 -0700131 {
swissChilibed80922021-04-13 21:58:05 -0700132 size *= 2;
swissChili53472e82021-05-08 16:06:32 -0700133 s = realloc_aligned(s, size);
swissChili7a6f5eb2021-04-13 16:46:02 -0700134 }
swissChilibed80922021-04-13 21:58:05 -0700135
swissChili53472e82021-05-08 16:06:32 -0700136 char c = is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700137
swissChili53472e82021-05-08 16:06:32 -0700138 if (escape && c == 'n')
swissChili7a6f5eb2021-04-13 16:46:02 -0700139 c = '\n';
swissChili53472e82021-05-08 16:06:32 -0700140 else if (escape && c == '\\')
swissChili7a6f5eb2021-04-13 16:46:02 -0700141 c = '\\';
142
swissChili53472e82021-05-08 16:06:32 -0700143 if (c == '\\' && !escape)
swissChili7a6f5eb2021-04-13 16:46:02 -0700144 {
145 escape = true;
146 i--; // will be incremented again, UGLY.
147 }
148 else
149 {
150 escape = false;
swissChili53472e82021-05-08 16:06:32 -0700151 s[i] = c;
swissChili7a6f5eb2021-04-13 16:46:02 -0700152 }
153 }
154 else
155 {
swissChili53472e82021-05-08 16:06:32 -0700156 is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700157
swissChilib3ca4fb2021-04-20 10:33:00 -0700158 *val = (value_t)s;
swissChili8cfb7c42021-04-18 21:17:58 -0700159 *val |= STRING_TAG;
swissChili7a6f5eb2021-04-13 16:46:02 -0700160
161 return true;
162 }
163 }
164}
165
swissChili53472e82021-05-08 16:06:32 -0700166void printval(value_t v, int depth)
swissChili7a6f5eb2021-04-13 16:46:02 -0700167{
swissChili53472e82021-05-08 16:06:32 -0700168 for (int i = 0; i < depth; i++)
169 printf(" ");
swissChili7a6f5eb2021-04-13 16:46:02 -0700170
swissChili53472e82021-05-08 16:06:32 -0700171 if (symbolp(v))
swissChili7a6f5eb2021-04-13 16:46:02 -0700172 {
swissChili53472e82021-05-08 16:06:32 -0700173 printf("'%s\n", (char *)(v ^ SYMBOL_TAG));
swissChili8cfb7c42021-04-18 21:17:58 -0700174 }
swissChili53472e82021-05-08 16:06:32 -0700175 else if (stringp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700176 {
swissChili53472e82021-05-08 16:06:32 -0700177 printf("\"%s\"\n", (char *)(v ^ STRING_TAG));
swissChili8cfb7c42021-04-18 21:17:58 -0700178 }
swissChili53472e82021-05-08 16:06:32 -0700179 else if (integerp(v))
swissChili6eee4f92021-04-20 09:34:30 -0700180 {
swissChili53472e82021-05-08 16:06:32 -0700181 printf("%d\n", v >> 2);
swissChili6eee4f92021-04-20 09:34:30 -0700182 }
swissChili53472e82021-05-08 16:06:32 -0700183 else if (consp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700184 {
swissChili53472e82021-05-08 16:06:32 -0700185 if (listp(v))
swissChilibed80922021-04-13 21:58:05 -0700186 {
swissChili53472e82021-05-08 16:06:32 -0700187 printf("list:\n");
swissChilibed80922021-04-13 21:58:05 -0700188
swissChili53472e82021-05-08 16:06:32 -0700189 for (value_t n = v; !nilp(n); n = cdr(n))
swissChilibed80922021-04-13 21:58:05 -0700190 {
swissChili53472e82021-05-08 16:06:32 -0700191 printval(car(n), depth + 1);
swissChilibed80922021-04-13 21:58:05 -0700192 }
193 }
194 else
195 {
swissChili53472e82021-05-08 16:06:32 -0700196 printf("cons:\n");
197 printval(car(v), depth + 1);
198 printval(cdr(v), depth + 1);
swissChilibed80922021-04-13 21:58:05 -0700199 }
swissChili8cfb7c42021-04-18 21:17:58 -0700200 }
swissChili53472e82021-05-08 16:06:32 -0700201 else if (nilp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700202 {
swissChili53472e82021-05-08 16:06:32 -0700203 printf("nil\n");
swissChili8cfb7c42021-04-18 21:17:58 -0700204 }
205 else
206 {
swissChili53472e82021-05-08 16:06:32 -0700207 printf("<unknown %d>\n", v);
swissChili7a6f5eb2021-04-13 16:46:02 -0700208 }
209}
210
swissChili53472e82021-05-08 16:06:32 -0700211bool readlist(struct istream *is, value_t *val)
swissChilibed80922021-04-13 21:58:05 -0700212{
swissChili53472e82021-05-08 16:06:32 -0700213 skipws(is);
swissChilibed80922021-04-13 21:58:05 -0700214
swissChili53472e82021-05-08 16:06:32 -0700215 if (is->peek(is) != '(')
swissChilibed80922021-04-13 21:58:05 -0700216 return false;
217
swissChili53472e82021-05-08 16:06:32 -0700218 is->get(is);
swissChilibed80922021-04-13 21:58:05 -0700219
swissChili53472e82021-05-08 16:06:32 -0700220 *val = readn(is);
swissChilibed80922021-04-13 21:58:05 -0700221
swissChili53472e82021-05-08 16:06:32 -0700222 if (is->peek(is) != ')')
swissChilibed80922021-04-13 21:58:05 -0700223 {
swissChili53472e82021-05-08 16:06:32 -0700224 is->showpos(is, stderr);
225 err("Unterminated list");
swissChilibed80922021-04-13 21:58:05 -0700226 return false;
227 }
swissChili53472e82021-05-08 16:06:32 -0700228 is->get(is);
swissChilibed80922021-04-13 21:58:05 -0700229
230 return true;
231}
232
swissChili53472e82021-05-08 16:06:32 -0700233bool readint(struct istream *is, value_t *val)
swissChili6eee4f92021-04-20 09:34:30 -0700234{
235 int number = 0;
236
swissChili53472e82021-05-08 16:06:32 -0700237 if (!isdigit(is->peek(is)))
swissChili6eee4f92021-04-20 09:34:30 -0700238 return false;
239
swissChili53472e82021-05-08 16:06:32 -0700240 while (isdigit(is->peek(is)))
swissChili6eee4f92021-04-20 09:34:30 -0700241 {
242 number *= 10;
swissChili53472e82021-05-08 16:06:32 -0700243 number += is->get(is) - '0';
swissChili6eee4f92021-04-20 09:34:30 -0700244 }
245
swissChili53472e82021-05-08 16:06:32 -0700246 *val = intval(number);
swissChili6eee4f92021-04-20 09:34:30 -0700247 return true;
248}
249
swissChili53472e82021-05-08 16:06:32 -0700250bool read1(struct istream *is, value_t *val)
swissChili7a6f5eb2021-04-13 16:46:02 -0700251{
swissChili53472e82021-05-08 16:06:32 -0700252 if (readsym(is, val))
swissChili7a6f5eb2021-04-13 16:46:02 -0700253 return true;
254
swissChili53472e82021-05-08 16:06:32 -0700255 if (readstr(is, val))
swissChili7a6f5eb2021-04-13 16:46:02 -0700256 return true;
257
swissChili53472e82021-05-08 16:06:32 -0700258 if (readint(is, val))
swissChili6eee4f92021-04-20 09:34:30 -0700259 return true;
260
swissChili53472e82021-05-08 16:06:32 -0700261 if (readlist(is, val))
swissChilibed80922021-04-13 21:58:05 -0700262 return true;
263
swissChili7a6f5eb2021-04-13 16:46:02 -0700264 return false;
265}
266
swissChili53472e82021-05-08 16:06:32 -0700267value_t readn(struct istream *is)
swissChilibed80922021-04-13 21:58:05 -0700268{
swissChili8cfb7c42021-04-18 21:17:58 -0700269 value_t first = nil;
270 value_t *last = &first;
swissChilibed80922021-04-13 21:58:05 -0700271
swissChili8cfb7c42021-04-18 21:17:58 -0700272 value_t read_val;
swissChilibed80922021-04-13 21:58:05 -0700273
swissChili53472e82021-05-08 16:06:32 -0700274 while (read1(is, &read_val))
swissChilibed80922021-04-13 21:58:05 -0700275 {
swissChili53472e82021-05-08 16:06:32 -0700276 *last = cons(read_val, nil);
277 last = cdrref(*last);
swissChilibed80922021-04-13 21:58:05 -0700278 }
279
280 return first;
281}
282
swissChili53472e82021-05-08 16:06:32 -0700283bool startswith(struct istream *s, char *pattern)
swissChili7a6f5eb2021-04-13 16:46:02 -0700284{
swissChili53472e82021-05-08 16:06:32 -0700285 char *check = strdup(pattern);
286 s->read(s, check, strlen(pattern));
swissChili7a6f5eb2021-04-13 16:46:02 -0700287
swissChili53472e82021-05-08 16:06:32 -0700288 bool res = strcmp(check, pattern) == 0;
289 free(check);
swissChili7a6f5eb2021-04-13 16:46:02 -0700290
291 return res;
292}
swissChilibed80922021-04-13 21:58:05 -0700293
swissChili53472e82021-05-08 16:06:32 -0700294value_t strval(char *str)
swissChilibed80922021-04-13 21:58:05 -0700295{
swissChili8cfb7c42021-04-18 21:17:58 -0700296 value_t v;
297
swissChili53472e82021-05-08 16:06:32 -0700298 char *a = malloc_aligned(strlen(str) + 1);
swissChilib3ca4fb2021-04-20 10:33:00 -0700299 v = (value_t)a;
swissChili8cfb7c42021-04-18 21:17:58 -0700300 v |= STRING_TAG;
swissChilibed80922021-04-13 21:58:05 -0700301
302 return v;
303}
304
swissChili53472e82021-05-08 16:06:32 -0700305bool integerp(value_t v)
swissChilibed80922021-04-13 21:58:05 -0700306{
swissChili8cfb7c42021-04-18 21:17:58 -0700307 return (v & INT_MASK) == INT_TAG;
308}
swissChilibed80922021-04-13 21:58:05 -0700309
swissChili53472e82021-05-08 16:06:32 -0700310bool symbolp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700311{
312 return (v & HEAP_MASK) == SYMBOL_TAG;
313}
314
swissChili53472e82021-05-08 16:06:32 -0700315bool stringp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700316{
317 return (v & HEAP_MASK) == STRING_TAG;
318}
319
swissChili53472e82021-05-08 16:06:32 -0700320bool consp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700321{
322 return (v & HEAP_MASK) == CONS_TAG;
323}
324
swissChili9e57da42021-06-15 22:22:46 -0700325bool heapp(value_t v)
326{
327 return consp(v) || stringp(v) || symbolp(v);
328}
329
swissChili53472e82021-05-08 16:06:32 -0700330bool listp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700331{
332 value_t next = v;
333
swissChili53472e82021-05-08 16:06:32 -0700334 while (consp(next))
swissChilibed80922021-04-13 21:58:05 -0700335 {
swissChili53472e82021-05-08 16:06:32 -0700336 next = cdr(next);
swissChilibed80922021-04-13 21:58:05 -0700337 }
338
swissChili53472e82021-05-08 16:06:32 -0700339 return nilp(next);
swissChilibed80922021-04-13 21:58:05 -0700340}
341
swissChili53472e82021-05-08 16:06:32 -0700342value_t car(value_t v)
swissChilibed80922021-04-13 21:58:05 -0700343{
swissChili53472e82021-05-08 16:06:32 -0700344 if (!consp(v))
swissChilibed80922021-04-13 21:58:05 -0700345 return nil;
346
swissChili53472e82021-05-08 16:06:32 -0700347 return *carref(v);
swissChilibed80922021-04-13 21:58:05 -0700348}
349
swissChili53472e82021-05-08 16:06:32 -0700350value_t cdr(value_t v)
swissChilibed80922021-04-13 21:58:05 -0700351{
swissChili53472e82021-05-08 16:06:32 -0700352 if (!consp(v))
swissChilibed80922021-04-13 21:58:05 -0700353 return nil;
354
swissChili53472e82021-05-08 16:06:32 -0700355 return *cdrref(v);
swissChilibed80922021-04-13 21:58:05 -0700356}
357
swissChili53472e82021-05-08 16:06:32 -0700358value_t *carref(value_t v)
swissChilibed80922021-04-13 21:58:05 -0700359{
swissChili53472e82021-05-08 16:06:32 -0700360 if (!consp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700361 return NULL;
362
swissChilib3ca4fb2021-04-20 10:33:00 -0700363 struct cons *c = (void *)(v ^ CONS_TAG);
swissChili8cfb7c42021-04-18 21:17:58 -0700364 return &c->car;
swissChilibed80922021-04-13 21:58:05 -0700365}
swissChilica107a02021-04-14 12:07:30 -0700366
swissChili53472e82021-05-08 16:06:32 -0700367value_t *cdrref(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700368{
swissChili53472e82021-05-08 16:06:32 -0700369 if (!consp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700370 return NULL;
371
swissChilib3ca4fb2021-04-20 10:33:00 -0700372 struct cons *c = (void *)(v ^ CONS_TAG);
swissChili8cfb7c42021-04-18 21:17:58 -0700373 return &c->cdr;
374}
375
swissChili53472e82021-05-08 16:06:32 -0700376bool nilp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700377{
378 return v == nil;
379}
380
swissChili53472e82021-05-08 16:06:32 -0700381int length(value_t v)
swissChilica107a02021-04-14 12:07:30 -0700382{
383 int i = 0;
384
swissChili53472e82021-05-08 16:06:32 -0700385 for (; !nilp(v); v = cdr(v))
swissChilica107a02021-04-14 12:07:30 -0700386 i++;
387
388 return i;
389}
swissChilib3ca4fb2021-04-20 10:33:00 -0700390
swissChili53472e82021-05-08 16:06:32 -0700391value_t elt(value_t v, int index)
swissChilib3ca4fb2021-04-20 10:33:00 -0700392{
swissChili53472e82021-05-08 16:06:32 -0700393 for (int i = 0; i < index; i++)
swissChilib3ca4fb2021-04-20 10:33:00 -0700394 {
swissChili53472e82021-05-08 16:06:32 -0700395 v = cdr(v);
swissChilib3ca4fb2021-04-20 10:33:00 -0700396 }
397
swissChili53472e82021-05-08 16:06:32 -0700398 return car(v);
swissChilib3ca4fb2021-04-20 10:33:00 -0700399}
swissChili8fc5e2f2021-04-22 13:45:10 -0700400
swissChili53472e82021-05-08 16:06:32 -0700401bool symstreq(value_t sym, char *str)
swissChili8fc5e2f2021-04-22 13:45:10 -0700402{
swissChili53472e82021-05-08 16:06:32 -0700403 if ((sym & HEAP_MASK) != SYMBOL_TAG)
swissChili8fc5e2f2021-04-22 13:45:10 -0700404 return false;
405
swissChili53472e82021-05-08 16:06:32 -0700406 return strcmp((char *)(sym ^ SYMBOL_TAG), str) == 0;
swissChili8fc5e2f2021-04-22 13:45:10 -0700407}