blob: 58e58e7d710b9cc4074cad5b9a1c4e229aa415d9 [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
swissChili7a6f5eb2021-04-13 16:46:02 -070010struct alloc_list *first_a = NULL, *last_a = NULL;
11
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{
swissChili53472e82021-05-08 16:06:32 -070030 struct cons *c = malloc_aligned(sizeof(struct cons));
swissChili7a6f5eb2021-04-13 16:46:02 -070031
swissChilibed80922021-04-13 21:58:05 -070032 c->car = car;
33 c->cdr = cdr;
34
swissChili53472e82021-05-08 16:06:32 -070035 struct alloc_list *item = malloc(sizeof(struct alloc_list));
swissChili7a6f5eb2021-04-13 16:46:02 -070036 item->type = T_CONS;
swissChili8cfb7c42021-04-18 21:17:58 -070037 item->cons_val = c;
swissChili7a6f5eb2021-04-13 16:46:02 -070038
swissChili53472e82021-05-08 16:06:32 -070039 if (last_a)
swissChili7a6f5eb2021-04-13 16:46:02 -070040 {
41 item->prev = last_a;
42 last_a->next = item;
43 item->next = NULL;
44 }
45 else
46 {
47 item->prev = item->next = NULL;
48 first_a = last_a = item;
49 }
50
swissChilib3ca4fb2021-04-20 10:33:00 -070051 value_t v = (value_t)c;
swissChili8cfb7c42021-04-18 21:17:58 -070052 v |= CONS_TAG;
swissChili7a6f5eb2021-04-13 16:46:02 -070053
54 return v;
55}
56
swissChili53472e82021-05-08 16:06:32 -070057void skipws(struct istream *is)
swissChili7a6f5eb2021-04-13 16:46:02 -070058{
swissChili53472e82021-05-08 16:06:32 -070059 while (isspace(is->peek(is)))
60 is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -070061}
62
swissChili53472e82021-05-08 16:06:32 -070063bool isallowedchar(char c)
swissChili7a6f5eb2021-04-13 16:46:02 -070064{
swissChilibed80922021-04-13 21:58:05 -070065 return (c >= '#' && c <= '\'') || (c >= '*' && c <= '/') ||
66 (c >= '>' && c <= '@');
swissChili7a6f5eb2021-04-13 16:46:02 -070067}
68
swissChili53472e82021-05-08 16:06:32 -070069bool issymstart(char c)
swissChili7a6f5eb2021-04-13 16:46:02 -070070{
swissChili53472e82021-05-08 16:06:32 -070071 return isalpha(c) || isallowedchar(c);
swissChili7a6f5eb2021-04-13 16:46:02 -070072}
73
swissChili53472e82021-05-08 16:06:32 -070074bool issym(char c)
swissChili7a6f5eb2021-04-13 16:46:02 -070075{
swissChili53472e82021-05-08 16:06:32 -070076 return isalpha(c) || isallowedchar(c) || isdigit(c);
swissChili7a6f5eb2021-04-13 16:46:02 -070077}
78
swissChili53472e82021-05-08 16:06:32 -070079bool readsym(struct istream *is, value_t *val)
swissChili7a6f5eb2021-04-13 16:46:02 -070080{
swissChili53472e82021-05-08 16:06:32 -070081 skipws(is);
swissChili7a6f5eb2021-04-13 16:46:02 -070082
swissChili53472e82021-05-08 16:06:32 -070083 if (!issymstart(is->peek(is)))
swissChili7a6f5eb2021-04-13 16:46:02 -070084 return false;
85
86 int size = 8;
swissChili53472e82021-05-08 16:06:32 -070087 char *s = malloc_aligned(size);
swissChili7a6f5eb2021-04-13 16:46:02 -070088
swissChili53472e82021-05-08 16:06:32 -070089 s[0] = is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -070090
swissChili53472e82021-05-08 16:06:32 -070091 for (int i = 1;; i++)
swissChili7a6f5eb2021-04-13 16:46:02 -070092 {
swissChili53472e82021-05-08 16:06:32 -070093 if (issym(is->peek(is)))
swissChili7a6f5eb2021-04-13 16:46:02 -070094 {
swissChili53472e82021-05-08 16:06:32 -070095 if (i >= size)
swissChili7a6f5eb2021-04-13 16:46:02 -070096 {
97 size *= 2;
swissChili53472e82021-05-08 16:06:32 -070098 s = realloc_aligned(s, size);
swissChili7a6f5eb2021-04-13 16:46:02 -070099 }
100
swissChili53472e82021-05-08 16:06:32 -0700101 s[i] = is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700102 }
103 else
104 {
swissChili53472e82021-05-08 16:06:32 -0700105 s[i] = 0;
swissChilib3ca4fb2021-04-20 10:33:00 -0700106 *val = (value_t)s;
swissChili8cfb7c42021-04-18 21:17:58 -0700107 *val |= SYMBOL_TAG;
swissChili7a6f5eb2021-04-13 16:46:02 -0700108
109 return true;
110 }
111 }
112}
113
swissChili53472e82021-05-08 16:06:32 -0700114bool readstr(struct istream *is, value_t *val)
swissChili7a6f5eb2021-04-13 16:46:02 -0700115{
swissChili53472e82021-05-08 16:06:32 -0700116 skipws(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700117
swissChili53472e82021-05-08 16:06:32 -0700118 if (is->peek(is) != '"')
swissChili7a6f5eb2021-04-13 16:46:02 -0700119 return false;
120
121 bool escape = false;
122 int size = 8;
swissChili53472e82021-05-08 16:06:32 -0700123 char *s = malloc_aligned(size);
swissChili7a6f5eb2021-04-13 16:46:02 -0700124
swissChili53472e82021-05-08 16:06:32 -0700125 (void)is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700126
swissChili53472e82021-05-08 16:06:32 -0700127 for (int i = 0;; i++)
swissChili7a6f5eb2021-04-13 16:46:02 -0700128 {
swissChili53472e82021-05-08 16:06:32 -0700129 if (is->peek(is) != '"')
swissChili7a6f5eb2021-04-13 16:46:02 -0700130 {
swissChili53472e82021-05-08 16:06:32 -0700131 if (i >= size)
swissChili7a6f5eb2021-04-13 16:46:02 -0700132 {
swissChilibed80922021-04-13 21:58:05 -0700133 size *= 2;
swissChili53472e82021-05-08 16:06:32 -0700134 s = realloc_aligned(s, size);
swissChili7a6f5eb2021-04-13 16:46:02 -0700135 }
swissChilibed80922021-04-13 21:58:05 -0700136
swissChili53472e82021-05-08 16:06:32 -0700137 char c = is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700138
swissChili53472e82021-05-08 16:06:32 -0700139 if (escape && c == 'n')
swissChili7a6f5eb2021-04-13 16:46:02 -0700140 c = '\n';
swissChili53472e82021-05-08 16:06:32 -0700141 else if (escape && c == '\\')
swissChili7a6f5eb2021-04-13 16:46:02 -0700142 c = '\\';
143
swissChili53472e82021-05-08 16:06:32 -0700144 if (c == '\\' && !escape)
swissChili7a6f5eb2021-04-13 16:46:02 -0700145 {
146 escape = true;
147 i--; // will be incremented again, UGLY.
148 }
149 else
150 {
151 escape = false;
swissChili53472e82021-05-08 16:06:32 -0700152 s[i] = c;
swissChili7a6f5eb2021-04-13 16:46:02 -0700153 }
154 }
155 else
156 {
swissChili53472e82021-05-08 16:06:32 -0700157 is->get(is);
swissChili7a6f5eb2021-04-13 16:46:02 -0700158
swissChilib3ca4fb2021-04-20 10:33:00 -0700159 *val = (value_t)s;
swissChili8cfb7c42021-04-18 21:17:58 -0700160 *val |= STRING_TAG;
swissChili7a6f5eb2021-04-13 16:46:02 -0700161
162 return true;
163 }
164 }
165}
166
swissChili53472e82021-05-08 16:06:32 -0700167void printval(value_t v, int depth)
swissChili7a6f5eb2021-04-13 16:46:02 -0700168{
swissChili53472e82021-05-08 16:06:32 -0700169 for (int i = 0; i < depth; i++)
170 printf(" ");
swissChili7a6f5eb2021-04-13 16:46:02 -0700171
swissChili53472e82021-05-08 16:06:32 -0700172 if (symbolp(v))
swissChili7a6f5eb2021-04-13 16:46:02 -0700173 {
swissChili53472e82021-05-08 16:06:32 -0700174 printf("'%s\n", (char *)(v ^ SYMBOL_TAG));
swissChili8cfb7c42021-04-18 21:17:58 -0700175 }
swissChili53472e82021-05-08 16:06:32 -0700176 else if (stringp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700177 {
swissChili53472e82021-05-08 16:06:32 -0700178 printf("\"%s\"\n", (char *)(v ^ STRING_TAG));
swissChili8cfb7c42021-04-18 21:17:58 -0700179 }
swissChili53472e82021-05-08 16:06:32 -0700180 else if (integerp(v))
swissChili6eee4f92021-04-20 09:34:30 -0700181 {
swissChili53472e82021-05-08 16:06:32 -0700182 printf("%d\n", v >> 2);
swissChili6eee4f92021-04-20 09:34:30 -0700183 }
swissChili53472e82021-05-08 16:06:32 -0700184 else if (consp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700185 {
swissChili53472e82021-05-08 16:06:32 -0700186 if (listp(v))
swissChilibed80922021-04-13 21:58:05 -0700187 {
swissChili53472e82021-05-08 16:06:32 -0700188 printf("list:\n");
swissChilibed80922021-04-13 21:58:05 -0700189
swissChili53472e82021-05-08 16:06:32 -0700190 for (value_t n = v; !nilp(n); n = cdr(n))
swissChilibed80922021-04-13 21:58:05 -0700191 {
swissChili53472e82021-05-08 16:06:32 -0700192 printval(car(n), depth + 1);
swissChilibed80922021-04-13 21:58:05 -0700193 }
194 }
195 else
196 {
swissChili53472e82021-05-08 16:06:32 -0700197 printf("cons:\n");
198 printval(car(v), depth + 1);
199 printval(cdr(v), depth + 1);
swissChilibed80922021-04-13 21:58:05 -0700200 }
swissChili8cfb7c42021-04-18 21:17:58 -0700201 }
swissChili53472e82021-05-08 16:06:32 -0700202 else if (nilp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700203 {
swissChili53472e82021-05-08 16:06:32 -0700204 printf("nil\n");
swissChili8cfb7c42021-04-18 21:17:58 -0700205 }
206 else
207 {
swissChili53472e82021-05-08 16:06:32 -0700208 printf("<unknown %d>\n", v);
swissChili7a6f5eb2021-04-13 16:46:02 -0700209 }
210}
211
swissChili53472e82021-05-08 16:06:32 -0700212bool readlist(struct istream *is, value_t *val)
swissChilibed80922021-04-13 21:58:05 -0700213{
swissChili53472e82021-05-08 16:06:32 -0700214 skipws(is);
swissChilibed80922021-04-13 21:58:05 -0700215
swissChili53472e82021-05-08 16:06:32 -0700216 if (is->peek(is) != '(')
swissChilibed80922021-04-13 21:58:05 -0700217 return false;
218
swissChili53472e82021-05-08 16:06:32 -0700219 is->get(is);
swissChilibed80922021-04-13 21:58:05 -0700220
swissChili53472e82021-05-08 16:06:32 -0700221 *val = readn(is);
swissChilibed80922021-04-13 21:58:05 -0700222
swissChili53472e82021-05-08 16:06:32 -0700223 if (is->peek(is) != ')')
swissChilibed80922021-04-13 21:58:05 -0700224 {
swissChili53472e82021-05-08 16:06:32 -0700225 is->showpos(is, stderr);
226 err("Unterminated list");
swissChilibed80922021-04-13 21:58:05 -0700227 return false;
228 }
swissChili53472e82021-05-08 16:06:32 -0700229 is->get(is);
swissChilibed80922021-04-13 21:58:05 -0700230
231 return true;
232}
233
swissChili53472e82021-05-08 16:06:32 -0700234bool readint(struct istream *is, value_t *val)
swissChili6eee4f92021-04-20 09:34:30 -0700235{
236 int number = 0;
237
swissChili53472e82021-05-08 16:06:32 -0700238 if (!isdigit(is->peek(is)))
swissChili6eee4f92021-04-20 09:34:30 -0700239 return false;
240
swissChili53472e82021-05-08 16:06:32 -0700241 while (isdigit(is->peek(is)))
swissChili6eee4f92021-04-20 09:34:30 -0700242 {
243 number *= 10;
swissChili53472e82021-05-08 16:06:32 -0700244 number += is->get(is) - '0';
swissChili6eee4f92021-04-20 09:34:30 -0700245 }
246
swissChili53472e82021-05-08 16:06:32 -0700247 *val = intval(number);
swissChili6eee4f92021-04-20 09:34:30 -0700248 return true;
249}
250
swissChili53472e82021-05-08 16:06:32 -0700251bool read1(struct istream *is, value_t *val)
swissChili7a6f5eb2021-04-13 16:46:02 -0700252{
swissChili53472e82021-05-08 16:06:32 -0700253 if (readsym(is, val))
swissChili7a6f5eb2021-04-13 16:46:02 -0700254 return true;
255
swissChili53472e82021-05-08 16:06:32 -0700256 if (readstr(is, val))
swissChili7a6f5eb2021-04-13 16:46:02 -0700257 return true;
258
swissChili53472e82021-05-08 16:06:32 -0700259 if (readint(is, val))
swissChili6eee4f92021-04-20 09:34:30 -0700260 return true;
261
swissChili53472e82021-05-08 16:06:32 -0700262 if (readlist(is, val))
swissChilibed80922021-04-13 21:58:05 -0700263 return true;
264
swissChili7a6f5eb2021-04-13 16:46:02 -0700265 return false;
266}
267
swissChili53472e82021-05-08 16:06:32 -0700268value_t readn(struct istream *is)
swissChilibed80922021-04-13 21:58:05 -0700269{
swissChili8cfb7c42021-04-18 21:17:58 -0700270 value_t first = nil;
271 value_t *last = &first;
swissChilibed80922021-04-13 21:58:05 -0700272
swissChili8cfb7c42021-04-18 21:17:58 -0700273 value_t read_val;
swissChilibed80922021-04-13 21:58:05 -0700274
swissChili53472e82021-05-08 16:06:32 -0700275 while (read1(is, &read_val))
swissChilibed80922021-04-13 21:58:05 -0700276 {
swissChili53472e82021-05-08 16:06:32 -0700277 *last = cons(read_val, nil);
278 last = cdrref(*last);
swissChilibed80922021-04-13 21:58:05 -0700279 }
280
281 return first;
282}
283
swissChili53472e82021-05-08 16:06:32 -0700284bool startswith(struct istream *s, char *pattern)
swissChili7a6f5eb2021-04-13 16:46:02 -0700285{
swissChili53472e82021-05-08 16:06:32 -0700286 char *check = strdup(pattern);
287 s->read(s, check, strlen(pattern));
swissChili7a6f5eb2021-04-13 16:46:02 -0700288
swissChili53472e82021-05-08 16:06:32 -0700289 bool res = strcmp(check, pattern) == 0;
290 free(check);
swissChili7a6f5eb2021-04-13 16:46:02 -0700291
292 return res;
293}
swissChilibed80922021-04-13 21:58:05 -0700294
swissChili53472e82021-05-08 16:06:32 -0700295value_t strval(char *str)
swissChilibed80922021-04-13 21:58:05 -0700296{
swissChili8cfb7c42021-04-18 21:17:58 -0700297 value_t v;
298
swissChili53472e82021-05-08 16:06:32 -0700299 char *a = malloc_aligned(strlen(str) + 1);
swissChilib3ca4fb2021-04-20 10:33:00 -0700300 v = (value_t)a;
swissChili8cfb7c42021-04-18 21:17:58 -0700301 v |= STRING_TAG;
swissChilibed80922021-04-13 21:58:05 -0700302
303 return v;
304}
305
swissChili53472e82021-05-08 16:06:32 -0700306bool integerp(value_t v)
swissChilibed80922021-04-13 21:58:05 -0700307{
swissChili8cfb7c42021-04-18 21:17:58 -0700308 return (v & INT_MASK) == INT_TAG;
309}
swissChilibed80922021-04-13 21:58:05 -0700310
swissChili53472e82021-05-08 16:06:32 -0700311bool symbolp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700312{
313 return (v & HEAP_MASK) == SYMBOL_TAG;
314}
315
swissChili53472e82021-05-08 16:06:32 -0700316bool stringp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700317{
318 return (v & HEAP_MASK) == STRING_TAG;
319}
320
swissChili53472e82021-05-08 16:06:32 -0700321bool consp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700322{
323 return (v & HEAP_MASK) == CONS_TAG;
324}
325
swissChili53472e82021-05-08 16:06:32 -0700326bool listp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700327{
328 value_t next = v;
329
swissChili53472e82021-05-08 16:06:32 -0700330 while (consp(next))
swissChilibed80922021-04-13 21:58:05 -0700331 {
swissChili53472e82021-05-08 16:06:32 -0700332 next = cdr(next);
swissChilibed80922021-04-13 21:58:05 -0700333 }
334
swissChili53472e82021-05-08 16:06:32 -0700335 return nilp(next);
swissChilibed80922021-04-13 21:58:05 -0700336}
337
swissChili53472e82021-05-08 16:06:32 -0700338value_t car(value_t v)
swissChilibed80922021-04-13 21:58:05 -0700339{
swissChili53472e82021-05-08 16:06:32 -0700340 if (!consp(v))
swissChilibed80922021-04-13 21:58:05 -0700341 return nil;
342
swissChili53472e82021-05-08 16:06:32 -0700343 return *carref(v);
swissChilibed80922021-04-13 21:58:05 -0700344}
345
swissChili53472e82021-05-08 16:06:32 -0700346value_t cdr(value_t v)
swissChilibed80922021-04-13 21:58:05 -0700347{
swissChili53472e82021-05-08 16:06:32 -0700348 if (!consp(v))
swissChilibed80922021-04-13 21:58:05 -0700349 return nil;
350
swissChili53472e82021-05-08 16:06:32 -0700351 return *cdrref(v);
swissChilibed80922021-04-13 21:58:05 -0700352}
353
swissChili53472e82021-05-08 16:06:32 -0700354value_t *carref(value_t v)
swissChilibed80922021-04-13 21:58:05 -0700355{
swissChili53472e82021-05-08 16:06:32 -0700356 if (!consp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700357 return NULL;
358
swissChilib3ca4fb2021-04-20 10:33:00 -0700359 struct cons *c = (void *)(v ^ CONS_TAG);
swissChili8cfb7c42021-04-18 21:17:58 -0700360 return &c->car;
swissChilibed80922021-04-13 21:58:05 -0700361}
swissChilica107a02021-04-14 12:07:30 -0700362
swissChili53472e82021-05-08 16:06:32 -0700363value_t *cdrref(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700364{
swissChili53472e82021-05-08 16:06:32 -0700365 if (!consp(v))
swissChili8cfb7c42021-04-18 21:17:58 -0700366 return NULL;
367
swissChilib3ca4fb2021-04-20 10:33:00 -0700368 struct cons *c = (void *)(v ^ CONS_TAG);
swissChili8cfb7c42021-04-18 21:17:58 -0700369 return &c->cdr;
370}
371
swissChili53472e82021-05-08 16:06:32 -0700372bool nilp(value_t v)
swissChili8cfb7c42021-04-18 21:17:58 -0700373{
374 return v == nil;
375}
376
swissChili53472e82021-05-08 16:06:32 -0700377int length(value_t v)
swissChilica107a02021-04-14 12:07:30 -0700378{
379 int i = 0;
380
swissChili53472e82021-05-08 16:06:32 -0700381 for (; !nilp(v); v = cdr(v))
swissChilica107a02021-04-14 12:07:30 -0700382 i++;
383
384 return i;
385}
swissChilib3ca4fb2021-04-20 10:33:00 -0700386
swissChili53472e82021-05-08 16:06:32 -0700387value_t elt(value_t v, int index)
swissChilib3ca4fb2021-04-20 10:33:00 -0700388{
swissChili53472e82021-05-08 16:06:32 -0700389 for (int i = 0; i < index; i++)
swissChilib3ca4fb2021-04-20 10:33:00 -0700390 {
swissChili53472e82021-05-08 16:06:32 -0700391 v = cdr(v);
swissChilib3ca4fb2021-04-20 10:33:00 -0700392 }
393
swissChili53472e82021-05-08 16:06:32 -0700394 return car(v);
swissChilib3ca4fb2021-04-20 10:33:00 -0700395}
swissChili8fc5e2f2021-04-22 13:45:10 -0700396
swissChili53472e82021-05-08 16:06:32 -0700397bool symstreq(value_t sym, char *str)
swissChili8fc5e2f2021-04-22 13:45:10 -0700398{
swissChili53472e82021-05-08 16:06:32 -0700399 if ((sym & HEAP_MASK) != SYMBOL_TAG)
swissChili8fc5e2f2021-04-22 13:45:10 -0700400 return false;
401
swissChili53472e82021-05-08 16:06:32 -0700402 return strcmp((char *)(sym ^ SYMBOL_TAG), str) == 0;
swissChili8fc5e2f2021-04-22 13:45:10 -0700403}