-
Notifications
You must be signed in to change notification settings - Fork 0
/
clojure.h
343 lines (303 loc) · 9.7 KB
/
clojure.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <math.h>
#include <gc.h>
#include <stdarg.h>
#include <ctype.h>
#include <editline/readline.h>
//type 15种类型 同像性
enum{
one, //void 0
MALTYPE_SYMBOL, //1
MALTYPE_KEYWORD, //2
MALTYPE_INTEGER, //3
MALTYPE_FLOAT, //4
MALTYPE_STRING, //5
MALTYPE_TRUE, //6
MALTYPE_FALSE, //7
MALTYPE_NIL, //8
MALTYPE_LIST, //9
MALTYPE_VECTOR, //10
MALTYPE_HASHMAP, //11
MALTYPE_FUNCTION, //12 // native function
MALTYPE_CLOSURE, //13 // user custom function
MALTYPE_ERROR, //14
MALTYPE_ATOM //15
};
#define UNREADABLY 0
#define READABLY 1
// special form (special symbol)
#define SYMBOL_DEFBANG "def!"
#define SYMBOL_LETSTAR "let*"
#define SYMBOL_DO "do"
#define SYMBOL_IF "if"
#define SYMBOL_FNSTAR "fn*"
#define SYMBOL_QUOTE "quote"
#define SYMBOL_QUASIQUOTE "quasiquote"
#define SYMBOL_QUASIQUOTEEXPAND "quasiquoteexpand"
#define SYMBOL_UNQUOTE "unquote"
#define SYMBOL_SPLICE_UNQUOTE "splice-unquote"
#define SYMBOL_DEFMACROBANG "defmacro!"
#define SYMBOL_MACROEXPAND "macroexpand"
#define SYMBOL_TRYSTAR "try*"
#define SYMBOL_CATCHSTAR "catch*"
#define PROMPT_STRING "user> "
#define STRING_BUFFER_SIZE 256
#define PRINT_NIL "nil"
#define PRINT_TRUE "true"
#define PRINT_FALSE "false"
#define INTEGER_BUFFER_SIZE 16
#define SYMBOL_BUFFER_SIZE 32
#define FUNCTION_BUFFER_SIZE 256
// #define STRING_BUFFER_SIZE 256
#define LIST_BUFFER_SIZE 10240
#define ERROR_BUFFER_SIZE 128
// token type
#define TOKEN_SPECIAL_CHARACTER 1 //9种符号 ( { [ ' ` ~ @ ~@ ^
#define TOKEN_STRING 2
#define TOKEN_INTEGER 3
#define TOKEN_FLOAT 4
#define TOKEN_SYMBOL 5
#define TOKEN_COMMENT 6
#define TOKEN_KEYWORD 7
#define TOKEN_TRUE 8
#define TOKEN_FALSE 9
#define TOKEN_NIL 10
#define SYMBOL_NIL "nil"
#define SYMBOL_TRUE "true"
#define SYMBOL_FALSE "false"
#define SYMBOL_QUOTE "quote"
#define SYMBOL_QUASIQUOTE "quasiquote"
#define SYMBOL_UNQUOTE "unquote"
#define SYMBOL_SPLICE_UNQUOTE "splice-unquote"
#define SYMBOL_DEREF "deref"
#define SYMBOL_WITH_META "with-meta"
/* simplify references to void pointers */
typedef void *gptr;
/* linked list is constructed of pairs */
typedef struct pair {
gptr data;
struct pair *next;
} pair;
/* a list is just a pointer to the pair at the head of the list */
typedef pair *list;
/* a hashmap is just a list with alternating key/value pairs */
typedef pair *hashmap;
typedef struct ns {
hashmap mappings;
} ns;
typedef struct Env {
struct Env *outer;
hashmap data;
} Env;
typedef struct maltype maltype;
typedef struct MalClosure {
Env *env;
maltype *parameters;
maltype *more_symbol;
maltype *definition;
} MalClosure;
/*四个字段
vector mal_vector; TODO: implement a real vector
hashmap mal_hashmap; TODO: implement a real hashmap */
struct maltype {
int type;
int is_macro;
maltype *metadata;
union MalValue {
long mal_integer;
double mal_float;
char *mal_symbol;
char *mal_string;
char *mal_keyword;
list mal_list;
maltype *(*mal_function)(list);
MalClosure *mal_closure;
maltype *mal_atom;
maltype *mal_error;
} value;
};
typedef struct Token {
int type;
char *data;
char *error;
} Token;
typedef struct Reader {
long position; // current position in the array
long token_count; // number of tokens in the array
long max_tokens; // maximum number of tokens the array can hold
Token **token_data; // pointer to an array of Tokens
char *error; // error message
} Reader;
/* interface */
list list_make(gptr data_ptr);
list list_push(list lst, gptr data_ptr);
gptr list_peek(list lst);
gptr list_nth(list lst, int n);
gptr list_first(list lst);
list list_rest(list lst);
list list_pop(list lst);
list list_reverse(list lst);
long list_count(list lst);
list list_concatenate(list lst1, list lst2);
list list_copy(list lst);
long list_findf(list lst, char *keystring, char *(*fn)(gptr));
hashmap hashmap_make(char *keystring, gptr data_ptr);
hashmap hashmap_put(hashmap map, char *keystring, gptr data_ptr);
gptr hashmap_get(hashmap map, char *keystring);
gptr hashmap_getf(hashmap map, char *keystring, char *(*fn)(gptr));
hashmap hashmap_updatef(hashmap map, char *keystring, gptr value, char *(*fn)(gptr));
Env *env_make(Env *outer, list binds, list exprs, maltype *variadic_symbol);
Env *env_set(Env *current, maltype *symbol, maltype *value);
Env *env_set_C_fn(Env *current, char *symbol_name, maltype *(*fn)(list));
maltype *env_get(Env *current, maltype *symbol);
Env *env_find(Env *current, maltype *symbol);
maltype *make_symbol(char *value);
maltype *make_integer(long value);
maltype *make_float(double value);
maltype *make_keyword(char *value);
maltype *make_string(char *value);
maltype *make_list(list value);
maltype *make_vector(list value);
maltype *make_hashmap(list value);
maltype *make_true();
maltype *make_false();
maltype *make_nil();
maltype *make_atom(maltype *value);
maltype *make_error(char *msg);
maltype *make_error_fmt(char *fmt, ...);
maltype *wrap_error(maltype *value);
maltype *make_function(maltype *(*fn)(list args));
maltype *make_closure(Env *env, maltype *parameters, maltype *definition, maltype *more_symbol);
maltype *copy_type(maltype *value);
int is_sequential(maltype *val);
int is_self_evaluating(maltype *val);
int is_list(maltype *val);
int is_vector(maltype *val);
int is_hashmap(maltype *val);
int is_nil(maltype *val);
int is_string(maltype *val);
int is_integer(maltype *val);
int is_float(maltype *val);
int is_number(maltype *val);
int is_true(maltype *val);
int is_false(maltype *val);
int is_symbol(maltype *val);
int is_keyword(maltype *val);
int is_atom(maltype *val);
int is_error(maltype *val);
int is_callable(maltype *val);
int is_function(maltype *val);
int is_closure(maltype *val);
int is_macro(maltype *val);
int is_macro_call(maltype * ast, Env * env);
maltype *macroexpand(maltype * ast, Env * env);
maltype *regularise_parameters(list * params, maltype * *more);
maltype *quasiquote(maltype * ast);
maltype *quasiquote_list(maltype * ast);
maltype *quasiquote_vector(maltype * ast);
ns *ns_make_core();
maltype *as_str(list args, int readably, char *separator);
maltype *print(list args, int readably, char *separator);
char *get_fn(gptr data);
maltype *equal_lists(maltype *lst1, maltype *lst2);
maltype *equal_hashmaps(maltype *map1, maltype *map2);
/* reader object */
Reader *reader_make(long token_capacity);
Reader *reader_append(Reader *reader, Token *token);
Token *reader_peek(const Reader *reader);
Token *reader_next(Reader *reader);
Token *reader_get_at(const Reader *reader, long i);
void reader_print(Reader *reader);
/* tokenizing the input */
Reader *tokenize(char *token_string);
char *read_specil_token(char *current, Token **ptoken, int n);
char *read_string_token(char *current, Token **ptoken);
char *read_comment_token(char *current, Token **ptoken);
// char* read_integer_token(char* current, Token** ptoken);
char *read_number_token(char *current, Token **ptoken);
char *read_symbol_token(char *current, Token **ptoken);
char *read_keyword_token(char *current, Token **ptoken);
/* reading the tokens into types */
maltype *read_str(char *token_string);
maltype *read_form(Reader *reader);
maltype *read_atom(Reader *reader);
maltype *read_list(Reader *reader);
maltype *read_vector(Reader *reader);
maltype *read_hashmap(Reader *reader);
/* utility functions */
char *read_terminated_token(char *current, Token **ptoken, int type);
maltype *read_matched_delimiters(Reader *reader, char start_delimiter, char end_delimiter);
maltype *make_symbol_list(Reader *reader, char *symbol_name);
Token *token_allocate(char *str, long num_chars, int type, char *error);
char *unescape_string(char *str, long length);
char *pr_str(maltype *mal_val, int readably);
char *pr_str_list(list lst, int readably, char *start_delimiter, char *end_delimiter, char *separator);
char *escape_string(char *str);
char *snprintfbuf(long initial_size, char *fmt, ...);
// ns core native fn
/* forward references to main file */
maltype *apply(maltype *fn, list args);
/* core ns functions */
maltype *mal_add(list);
maltype *mal_sub(list);
maltype *mal_mul(list);
maltype *mal_div(list);
maltype *mal_prn(list);
maltype *mal_println(list);
maltype *mal_pr_str(list);
maltype *mal_str(list);
maltype *mal_read_string(list);
maltype *mal_slurp(list);
maltype *mal_list(list);
maltype *mal_list_questionmark(list);
maltype *mal_empty_questionmark(list);
maltype *mal_count(list);
maltype *mal_cons(list);
maltype *mal_concat(list);
maltype *mal_nth(list);
maltype *mal_first(list);
maltype *mal_rest(list);
maltype *mal_equals(list);
maltype *mal_lessthan(list);
maltype *mal_lessthanorequalto(list);
maltype *mal_greaterthan(list);
maltype *mal_greaterthanorequalto(list);
maltype *mal_atom(list);
maltype *mal_atom_questionmark(list);
maltype *mal_deref(list);
maltype *mal_reset_bang(list);
maltype *mal_swap_bang(list);
maltype *mal_throw(list);
maltype *mal_apply(list);
maltype *mal_map(list);
maltype *mal_nil_questionmark(list);
maltype *mal_true_questionmark(list);
maltype *mal_false_questionmark(list);
maltype *mal_symbol_questionmark(list);
maltype *mal_keyword_questionmark(list);
maltype *mal_symbol(list);
maltype *mal_keyword(list);
maltype *mal_vec(list);
maltype *mal_vector(list);
maltype *mal_vector_questionmark(list);
maltype *mal_sequential_questionmark(list);
maltype *mal_hash_map(list);
maltype *mal_map_questionmark(list);
maltype *mal_assoc(list);
maltype *mal_dissoc(list);
maltype *mal_get(list);
maltype *mal_contains_questionmark(list);
maltype *mal_keys(list);
maltype *mal_vals(list);
maltype *mal_string_questionmark(list);
maltype *mal_number_questionmark(list);
maltype *mal_fn_questionmark(list);
maltype *mal_macro_questionmark(list);
maltype *mal_time_ms(list);
maltype *mal_conj(list);
maltype *mal_seq(list);
maltype *mal_meta(list);
maltype *mal_with_meta(list);