blob: b78182847fba22c1d525a7e71b73ce104e08a3e4 [file] [log] [blame]
swissChili7a6f5eb2021-04-13 16:46:02 -07001#pragma once
2
3#include <stdbool.h>
swissChilibed80922021-04-13 21:58:05 -07004#include <stdio.h>
swissChili7a6f5eb2021-04-13 16:46:02 -07005
6enum type
7{
8 T_INT = 0,
9 T_FLOAT,
10 T_NIL,
11 T_SYMBOL,
12 T_STRING,
13 T_VECTOR,
14 T_CLASS,
15 T_CONS,
16};
17
swissChili8cfb7c42021-04-18 21:17:58 -070018#define INT_MASK 0b11
19#define INT_TAG 0b00
20
21#define CHAR_MASK 0xff
22#define CHAR_TAG 0b00001111
23
24#define BOOL_MASK 0b1111111
25#define BOOL_TAG 0b0011111
26
27#define HEAP_MASK 0b111
28
29#define CONS_TAG 0b001
30#define VECTOR_TAG 0b010
swissChili6eee4f92021-04-20 09:34:30 -070031#define STRING_TAG 0b011
swissChili8cfb7c42021-04-18 21:17:58 -070032#define SYMBOL_TAG 0b101
33#define CLOSURE_TAG 0b110
swissChili7a6f5eb2021-04-13 16:46:02 -070034
35struct cons;
36
swissChili8cfb7c42021-04-18 21:17:58 -070037typedef unsigned int value_t;
swissChili7a6f5eb2021-04-13 16:46:02 -070038
39struct cons
40{
41 int magic;
42 int marked; // must be reserved
swissChili8cfb7c42021-04-18 21:17:58 -070043 value_t car, cdr;
swissChili7a6f5eb2021-04-13 16:46:02 -070044};
45
46struct alloc_list
47{
48 int type;
swissChilib3ca4fb2021-04-20 10:33:00 -070049 union {
swissChili8cfb7c42021-04-18 21:17:58 -070050 struct cons *cons_val;
51 };
swissChili7a6f5eb2021-04-13 16:46:02 -070052 struct alloc_list *next, *prev;
53};
54
55struct istream
56{
57 void *data;
58
59 // These two return -1 on error
60 int (*peek) (struct istream *s);
61 int (*get) (struct istream *s);
62
63 int (*read) (struct istream *s, char *buffer, int size);
swissChilibed80922021-04-13 21:58:05 -070064
65 void (*showpos) (struct istream *s, FILE *out);
swissChili7a6f5eb2021-04-13 16:46:02 -070066};
67
swissChilibed80922021-04-13 21:58:05 -070068bool startswith (struct istream *s, char *pattern);
swissChili7a6f5eb2021-04-13 16:46:02 -070069
swissChili8cfb7c42021-04-18 21:17:58 -070070bool readsym (struct istream *is, value_t *val);
71bool readstr (struct istream *is, value_t *val);
72bool readlist (struct istream *is, value_t *val);
swissChili6eee4f92021-04-20 09:34:30 -070073bool readint (struct istream *is, value_t *val);
swissChili7a6f5eb2021-04-13 16:46:02 -070074
swissChili8cfb7c42021-04-18 21:17:58 -070075value_t intval (int i);
76value_t strval (char *str);
77value_t cons (value_t car, value_t cdr);
78bool read1 (struct istream *is, value_t *val);
79value_t read (struct istream *is);
80value_t readn (struct istream *is);
swissChilibed80922021-04-13 21:58:05 -070081
swissChili8cfb7c42021-04-18 21:17:58 -070082value_t car (value_t v);
83value_t cdr (value_t v);
84value_t *carref (value_t v);
85value_t *cdrref (value_t v);
swissChili7a6f5eb2021-04-13 16:46:02 -070086
swissChili8cfb7c42021-04-18 21:17:58 -070087bool integerp (value_t v);
88bool symbolp (value_t v);
89bool stringp (value_t v);
90bool consp (value_t v);
91bool listp (value_t v);
92bool nilp (value_t v);
93int length (value_t v);
swissChilib3ca4fb2021-04-20 10:33:00 -070094value_t elt (value_t v, int index);
swissChili8cfb7c42021-04-18 21:17:58 -070095
96void printval (value_t v, int depth);
swissChili7a6f5eb2021-04-13 16:46:02 -070097
98struct istream *new_stristream (char *str, int length);
99// same as above but null terminated
100struct istream *new_stristream_nt (char *str);
swissChilibed80922021-04-13 21:58:05 -0700101void del_stristream (struct istream *stristream);
102
103void err (const char *msg);
104
swissChili8cfb7c42021-04-18 21:17:58 -0700105extern value_t nil;
swissChilica107a02021-04-14 12:07:30 -0700106
107#define FOREACH(item, list) \
108 for ( ; listp (list); ) \
swissChili8cfb7c42021-04-18 21:17:58 -0700109 for ( value_t item = car (list), _foreach_current = list; \
swissChilica107a02021-04-14 12:07:30 -0700110 !nilp (_foreach_current); \
111 _foreach_current = cdr (_foreach_current), \
swissChili8cfb7c42021-04-18 21:17:58 -0700112 item = car (_foreach_current) )