-
Notifications
You must be signed in to change notification settings - Fork 4
/
types.h
216 lines (175 loc) · 6.41 KB
/
types.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
#ifndef __MAL_TYPES__
#define __MAL_TYPES__
#include <gc.h>
#include <stddef.h>
#include "hashmap.h"
typedef struct MalType MalType;
typedef struct MalEnv MalEnv;
struct MalEnv {
size_t num;
struct hashmap data;
MalEnv *outer;
};
enum MalTypeType {
MAL_NIL_TYPE,
MAL_TRUE_TYPE,
MAL_FALSE_TYPE,
MAL_EMPTY_TYPE,
MAL_CONS_TYPE,
MAL_KEYWORD_TYPE,
MAL_NUMBER_TYPE,
MAL_SYMBOL_TYPE,
MAL_VECTOR_TYPE,
MAL_HASHMAP_TYPE,
MAL_STRING_TYPE,
MAL_REGEX_TYPE,
MAL_LAMBDA_TYPE,
MAL_CONTINUATION_TYPE,
MAL_ATOM_TYPE,
MAL_BLANK_LINE_TYPE,
MAL_ERROR_TYPE
};
struct MalType {
enum MalTypeType type;
union {
long long number;
char *symbol;
char *keyword;
struct hashmap hashmap;
MalType *atom_val;
MalType *error_val;
// MAL_CONS_TYPE
struct {
MalType *car;
MalType *cdr;
};
// MAL_VECTOR_TYPE
struct {
size_t vec_len;
size_t vec_cap;
MalType **vec;
};
// MAL_STRING_TYPE
struct {
size_t str_len;
size_t str_cap;
char *str;
};
// MAL_REGEX_TYPE
struct {
size_t regex_len;
char *regex;
};
// MAL_LAMBDA_TYPE, MAL_CONTINUATION_TYPE
struct {
MalType* (*fn)(MalEnv *env, size_t argc, MalType **args);
char *function_name;
MalEnv *env;
size_t argc;
MalType **args;
};
};
int is_macro;
MalType *meta;
};
#define is_primitive(val) ((val)->type == MAL_NIL_TYPE || \
(val)->type == MAL_FALSE_TYPE || \
(val)->type == MAL_TRUE_TYPE || \
(val)->type == MAL_EMPTY_TYPE || \
(val)->type == MAL_KEYWORD_TYPE || \
(val)->type == MAL_NUMBER_TYPE || \
(val)->type == MAL_SYMBOL_TYPE || \
(val)->type == MAL_STRING_TYPE || \
(val)->type == MAL_REGEX_TYPE)
MalType* mal_alloc();
MalType* mal_nil();
int is_nil(MalType *val);
MalType* mal_empty();
int is_empty(MalType *val);
MalType* mal_true();
MalType* mal_false();
#define is_true(val) ((val)->type == MAL_TRUE_TYPE)
#define is_false(val) ((val)->type == MAL_FALSE_TYPE)
#define is_truthy(val) ((val)->type != MAL_NIL_TYPE && (val)->type != MAL_FALSE_TYPE)
#define is_falsey(val) ((val)->type == MAL_NIL_TYPE || (val)->type == MAL_FALSE_TYPE)
MalType* mal_cons(MalType *car, MalType *cdr);
#define is_cons(val) ((val)->type == MAL_CONS_TYPE)
MalType* mal_car(MalType *val);
MalType* mal_cdr(MalType *val);
size_t mal_list_len(MalType *val);
MalType* mal_list_ref(MalType *val, size_t index);
MalType* mal_vector();
#define is_vector(val) ((val)->type == MAL_VECTOR_TYPE)
size_t mal_vector_len(MalType *vector);
MalType* mal_vector_ref(MalType *val, size_t index);
void mal_vector_push(MalType *vector, MalType *value);
MalType* mal_vector_to_list(MalType *val);
MalType* mal_vector_range(MalType *vec, int start, int stop_exclusive);
MalType* mal_car2(MalType *val);
MalType* mal_cdr2(MalType *val);
MalType* mal_hashmap();
#define is_hashmap(val) ((val)->type == MAL_HASHMAP_TYPE)
MalType* mal_hashmap_get(MalType *map, MalType *key);
void mal_hashmap_put(MalType *map, MalType *key, MalType *val);
void mal_hashmap_remove(MalType *map, MalType *key);
size_t mal_hashmap_size(MalType *map);
MalType* mal_hashmap_keys_to_vector(MalType *map);
MalType* mal_string(char *str);
#define is_string(val) ((val)->type == MAL_STRING_TYPE)
void mal_grow_string(MalType *val, size_t capacity);
void mal_grow_string_at_least(MalType *val, size_t min_capacity);
void mal_string_append(MalType *val, char *str);
void mal_string_append_mal_string(MalType *val, MalType *str);
void mal_string_append_char(MalType *val, char c);
void mal_string_append_long_long(MalType *val, long long n);
MalType* mal_string_replace(MalType *val, char *find, char *replace);
MalType* mal_string_replace_all(MalType *orig, char *find, char *replace);
MalType* mal_string_to_list(MalType *orig);
MalType* mal_regex(char *str);
#define is_regex(val) ((val)->type == MAL_REGEX_TYPE)
MalType* mal_keyword(char *name);
#define is_keyword(val) ((val)->type == MAL_KEYWORD_TYPE)
MalType* mal_number(long long number);
#define is_number(val) ((val)->type == MAL_NUMBER_TYPE)
MalType* mal_symbol(char *name);
#define is_symbol(val) ((val)->type == MAL_SYMBOL_TYPE)
MalType* mal_closure(MalType* (*lambda)(MalEnv *env, size_t argc, MalType **args), MalEnv *env);
MalType* mal_builtin_function(MalType* (*lambda)(MalEnv *env, size_t argc, MalType **args), char *function_name, MalEnv *env);
MalType* mal_continuation(MalType* (*fn)(MalEnv *env, size_t argc, MalType **args), MalEnv *env, size_t argc, MalType **args);
MalType* mal_continuation_0(MalType* (*fn)(MalEnv *env, size_t argc, MalType **args), MalEnv *env);
MalType* mal_continuation_1(MalType* (*fn)(MalEnv *env, size_t argc, MalType **args), MalEnv *env, MalType *arg);
#define is_lambda(val) ((val)->type == MAL_LAMBDA_TYPE)
#define is_macro(val) ((val)->is_macro)
#define is_builtin_function(val) ((val)->type == MAL_LAMBDA_TYPE && (val)->function_name)
MalType* mal_atom(MalType *inner_val);
#define is_atom(val) ((val)->type == MAL_ATOM_TYPE)
MalType* mal_blank_line();
#define is_blank_line(val) ((val)->type == MAL_BLANK_LINE_TYPE)
MalType* mal_error();
#define is_error(val) ((val)->type == MAL_ERROR_TYPE)
#define bubble_if_error(val) ({ MalType *v = (val); if (is_error(v)) { return (v); }; v; })
struct list_or_vector_iter {
enum { LIST_ITER, VECTOR_ITER } type;
MalType *cell;
size_t len;
size_t i;
};
size_t list_or_vector_len(MalType *obj);
struct list_or_vector_iter* list_or_vector_iter(MalType *obj);
struct list_or_vector_iter* list_or_vector_iter_next(struct list_or_vector_iter *iter);
int list_or_vector_iter_is_last(struct list_or_vector_iter *iter);
MalType* list_or_vector_iter_get_obj(struct list_or_vector_iter *iter);
int list_or_vector_index_of(MalType *list, MalType *val);
MalType* mal_sprintf(char *format, ...);
#define is_list_like(obj) ((obj)->type == MAL_EMPTY_TYPE || (obj)->type == MAL_CONS_TYPE || (obj)->type == MAL_VECTOR_TYPE)
#define is_pair(obj) ((obj)->type == MAL_CONS_TYPE || ((obj)->type == MAL_VECTOR_TYPE && (obj)->vec_len > 0))
int is_equal(MalType *arg1, MalType *arg2);
int hashmap_is_equal(MalType *arg1, MalType *arg2);
int list_or_vector_is_equal(MalType *arg1, MalType *arg2);
struct codegen {
MalType *top;
MalType *decl;
MalType *body;
};
MalType* trampoline(MalType *result);
#endif