blob: 3c2cb3b6dcc66d660a654a8375da5b99bad291e5 [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;
swissChili8cfb7c42021-04-18 21:17:58 -070049 union
50 {
51 struct cons *cons_val;
52 };
swissChili7a6f5eb2021-04-13 16:46:02 -070053 struct alloc_list *next, *prev;
54};
55
56struct istream
57{
58 void *data;
59
60 // These two return -1 on error
61 int (*peek) (struct istream *s);
62 int (*get) (struct istream *s);
63
64 int (*read) (struct istream *s, char *buffer, int size);
swissChilibed80922021-04-13 21:58:05 -070065
66 void (*showpos) (struct istream *s, FILE *out);
swissChili7a6f5eb2021-04-13 16:46:02 -070067};
68
swissChilibed80922021-04-13 21:58:05 -070069bool startswith (struct istream *s, char *pattern);
swissChili7a6f5eb2021-04-13 16:46:02 -070070
swissChili8cfb7c42021-04-18 21:17:58 -070071bool readsym (struct istream *is, value_t *val);
72bool readstr (struct istream *is, value_t *val);
73bool readlist (struct istream *is, value_t *val);
swissChili6eee4f92021-04-20 09:34:30 -070074bool readint (struct istream *is, value_t *val);
swissChili7a6f5eb2021-04-13 16:46:02 -070075
swissChili8cfb7c42021-04-18 21:17:58 -070076value_t intval (int i);
77value_t strval (char *str);
78value_t cons (value_t car, value_t cdr);
79bool read1 (struct istream *is, value_t *val);
80value_t read (struct istream *is);
81value_t readn (struct istream *is);
swissChilibed80922021-04-13 21:58:05 -070082
swissChili8cfb7c42021-04-18 21:17:58 -070083value_t car (value_t v);
84value_t cdr (value_t v);
85value_t *carref (value_t v);
86value_t *cdrref (value_t v);
swissChili7a6f5eb2021-04-13 16:46:02 -070087
swissChili8cfb7c42021-04-18 21:17:58 -070088bool integerp (value_t v);
89bool symbolp (value_t v);
90bool stringp (value_t v);
91bool consp (value_t v);
92bool listp (value_t v);
93bool nilp (value_t v);
94int length (value_t v);
95
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) )