blob: 675cc967463b633dfb705609ddfac6d2e91e7f8f [file] [log] [blame]
swissChili7a6f5eb2021-04-13 16:46:02 -07001#pragma once
2
swissChili923b5362021-05-09 20:31:43 -07003#include "istream.h"
swissChili7a6f5eb2021-04-13 16:46:02 -07004#include <stdbool.h>
swissChilibed80922021-04-13 21:58:05 -07005#include <stdio.h>
swissChili7a6f5eb2021-04-13 16:46:02 -07006
swissChili8cfb7c42021-04-18 21:17:58 -07007#define INT_MASK 0b11
8#define INT_TAG 0b00
9
10#define CHAR_MASK 0xff
11#define CHAR_TAG 0b00001111
12
13#define BOOL_MASK 0b1111111
14#define BOOL_TAG 0b0011111
15
16#define HEAP_MASK 0b111
17
18#define CONS_TAG 0b001
19#define VECTOR_TAG 0b010
swissChili6eee4f92021-04-20 09:34:30 -070020#define STRING_TAG 0b011
swissChili8cfb7c42021-04-18 21:17:58 -070021#define SYMBOL_TAG 0b101
22#define CLOSURE_TAG 0b110
swissChili7a6f5eb2021-04-13 16:46:02 -070023
24struct cons;
25
swissChili2999dd12021-07-02 14:19:53 -070026/// Represents a Lisp value
swissChili8cfb7c42021-04-18 21:17:58 -070027typedef unsigned int value_t;
swissChili7a6f5eb2021-04-13 16:46:02 -070028
29struct cons
30{
swissChili8cfb7c42021-04-18 21:17:58 -070031 value_t car, cdr;
swissChili2999dd12021-07-02 14:19:53 -070032
33 /// Line of the input file from where this was parsed, 0 if it was created
34 /// in Lisp.
35 int line;
36
37 /// Description of where the cons was parsed from, or NULL if generated in
38 /// code.
39 char *name;
swissChili7a6f5eb2021-04-13 16:46:02 -070040};
41
swissChilif1ba8c12021-07-02 18:45:38 -070042struct closure
43{
44 int num_args;
45 void *function;
46
47 /// This will be passed in edi.
48 value_t data[];
49};
50
swissChilib8fd4712021-06-23 15:32:04 -070051/// Default pool (no pool)
52#define NO_POOL 0
53
54/**
55 * The max used pool number, don't touch this.
56 */
57extern unsigned char max_pool;
58
59/**
60 * Current allocation pool, default 0 (no pool)
61 */
62extern unsigned char current_pool;
swissChilie9fec8b2021-06-22 13:59:33 -070063
64// It is integral that this be 16 bytes long so that whatever follows it is
65// still aligned to 4 bits.
swissChili9e57da42021-06-15 22:22:46 -070066struct alloc
swissChili7a6f5eb2021-04-13 16:46:02 -070067{
swissChilib8fd4712021-06-23 15:32:04 -070068 /**
69 * One of the type tags, eg CONS_TAG, etc
70 */
swissChilie9fec8b2021-06-22 13:59:33 -070071 unsigned int type_tag; // 4
72 struct alloc *prev, *next; // + 8
swissChilib8fd4712021-06-23 15:32:04 -070073 /**
74 * Zero if this is not part of a release pool, pool number otherwise.
75 */
76 unsigned char pool; // + 1
77 /**
78 * Reserved for the GC.
79 */
80 unsigned int mark : 24; // + 2 = 16
swissChili9e57da42021-06-15 22:22:46 -070081
82 // Whatever else
83};
84
swissChilie9fec8b2021-06-22 13:59:33 -070085extern struct alloc *first_a, *last_a;
86
swissChili9e57da42021-06-15 22:22:46 -070087struct cons_alloc
88{
89 struct alloc alloc;
90 struct cons cons;
swissChili7a6f5eb2021-04-13 16:46:02 -070091};
92
swissChilif1ba8c12021-07-02 18:45:38 -070093struct closure_alloc
94{
95 struct alloc alloc;
96 struct closure closure;
97};
98
swissChilib8fd4712021-06-23 15:32:04 -070099/**
100 * Create a new allocation pool.
101 */
102unsigned char make_pool();
103
104/**
105 * Set the allocation pull
106 * @returns the old pool, you should reset this later with pop_pool.
107 */
108unsigned char push_pool(unsigned char pool);
109
110/**
111 * Set the allocation pool and throw away the old value.
112 */
113void pop_pool(unsigned char pool);
114
115/**
116 * @returns true if pool is still alive (in scope).
117 */
118bool pool_alive(unsigned char pool);
119
swissChili53472e82021-05-08 16:06:32 -0700120bool startswith(struct istream *s, char *pattern);
swissChili7a6f5eb2021-04-13 16:46:02 -0700121
swissChili53472e82021-05-08 16:06:32 -0700122bool readsym(struct istream *is, value_t *val);
123bool readstr(struct istream *is, value_t *val);
124bool readlist(struct istream *is, value_t *val);
125bool readint(struct istream *is, value_t *val);
swissChili7a6f5eb2021-04-13 16:46:02 -0700126
swissChilib6c858c2021-06-30 21:12:43 -0700127/**
128 * Read a quoted form, including `'` (quote) `\`` (backquote) and `,` (unquote)
129 * @returns true if read successfully, and sets `val`.
130 */
131bool readquote(struct istream *is, value_t *val);
132
swissChili53472e82021-05-08 16:06:32 -0700133value_t intval(int i);
134value_t strval(char *str);
swissChilib6c858c2021-06-30 21:12:43 -0700135value_t symval(char *str);
swissChili53472e82021-05-08 16:06:32 -0700136value_t cons(value_t car, value_t cdr);
137bool read1(struct istream *is, value_t *val);
138value_t read(struct istream *is);
139value_t readn(struct istream *is);
swissChilibed80922021-04-13 21:58:05 -0700140
swissChili53472e82021-05-08 16:06:32 -0700141value_t car(value_t v);
142value_t cdr(value_t v);
143value_t *carref(value_t v);
144value_t *cdrref(value_t v);
swissChili7a6f5eb2021-04-13 16:46:02 -0700145
swissChilif1ba8c12021-07-02 18:45:38 -0700146int cons_line(value_t val);
147char *cons_file(value_t val);
148
swissChili53472e82021-05-08 16:06:32 -0700149bool integerp(value_t v);
150bool symbolp(value_t v);
151bool stringp(value_t v);
152bool consp(value_t v);
153bool listp(value_t v);
154bool nilp(value_t v);
swissChili9e57da42021-06-15 22:22:46 -0700155bool heapp(value_t v);
swissChili53472e82021-05-08 16:06:32 -0700156int length(value_t v);
157value_t elt(value_t v, int index);
swissChili8cfb7c42021-04-18 21:17:58 -0700158
swissChili53472e82021-05-08 16:06:32 -0700159void printval(value_t v, int depth);
swissChili7a6f5eb2021-04-13 16:46:02 -0700160
swissChili53472e82021-05-08 16:06:32 -0700161void err(const char *msg);
swissChilibed80922021-04-13 21:58:05 -0700162
swissChili53472e82021-05-08 16:06:32 -0700163bool symstreq(value_t sym, char *str);
swissChilica107a02021-04-14 12:07:30 -0700164
swissChili8fc5e2f2021-04-22 13:45:10 -0700165extern value_t nil;
swissChili923b5362021-05-09 20:31:43 -0700166extern value_t t;