Commit | Line | Data |
---|---|---|
31690700 JM |
1 | #ifndef __MAL_TYPES__ |
2 | #define __MAL_TYPES__ | |
3 | ||
4 | #include <glib.h> | |
5 | ||
6b3ecaa7 DM |
6 | #ifdef USE_GC |
7 | ||
8 | #include <gc/gc.h> | |
fba3aeb2 JM |
9 | void nop_free(void* ptr); |
10 | void GC_setup(); | |
6b3ecaa7 DM |
11 | char* GC_strdup(const char *src); |
12 | #define MAL_GC_SETUP() GC_setup() | |
13 | #define MAL_GC_MALLOC GC_MALLOC | |
14 | #define MAL_GC_FREE nop_free | |
15 | #define MAL_GC_STRDUP GC_strdup | |
16 | ||
17 | #else | |
18 | ||
19 | #include <string.h> | |
20 | #define MAL_GC_SETUP() | |
21 | #define MAL_GC_MALLOC malloc | |
22 | #define MAL_GC_FREE free | |
23 | #define MAL_GC_STRDUP strdup | |
24 | ||
25 | #endif | |
31690700 JM |
26 | |
27 | struct MalVal; // pre-declare | |
ea81a808 JM |
28 | |
29 | ||
30 | // Env (implentation in env.c) | |
31 | ||
32 | typedef struct Env { | |
33 | struct Env *outer; | |
34 | GHashTable *table; | |
35 | } Env; | |
36 | ||
37 | Env *new_env(Env *outer, struct MalVal* binds, struct MalVal *exprs); | |
b8ee29b2 JM |
38 | Env *env_find(Env *env, struct MalVal *key); |
39 | struct MalVal *env_get(Env *env, struct MalVal *key); | |
40 | Env *env_set(Env *env, struct MalVal *key, struct MalVal *val); | |
ea81a808 JM |
41 | |
42 | ||
43 | // Utility functiosn | |
44 | void g_hash_table_print(GHashTable *hash_table); | |
45 | GHashTable *g_hash_table_copy(GHashTable *src_table); | |
46 | ||
47 | ||
48 | // Errors/exceptions | |
49 | ||
31690700 | 50 | extern struct MalVal *mal_error; |
ea81a808 | 51 | void _error(const char *fmt, ...); |
31690700 JM |
52 | |
53 | #define abort(format, ...) \ | |
54 | { _error(format, ##__VA_ARGS__); return NULL; } | |
55 | ||
56 | #define assert(test, format, ...) \ | |
57 | if (!(test)) { \ | |
58 | _error(format, ##__VA_ARGS__); \ | |
59 | return NULL; \ | |
60 | } | |
61 | ||
62 | #define assert_type(mv, typ, format, ...) \ | |
63 | if (!(mv->type & (typ))) { \ | |
64 | _error(format, ##__VA_ARGS__); \ | |
65 | return NULL; \ | |
66 | } | |
67 | ||
ea81a808 | 68 | |
31690700 JM |
69 | typedef enum { |
70 | MAL_NIL = 1, | |
71 | MAL_TRUE = 2, | |
72 | MAL_FALSE = 4, | |
73 | MAL_INTEGER = 8, | |
74 | MAL_FLOAT = 16, | |
75 | MAL_SYMBOL = 32, | |
76 | MAL_STRING = 64, | |
77 | MAL_LIST = 128, | |
78 | MAL_VECTOR = 256, | |
79 | MAL_HASH_MAP = 512, | |
80 | MAL_ATOM = 1024, | |
81 | MAL_FUNCTION_C = 2048, | |
82 | MAL_FUNCTION_MAL = 4096, | |
83 | } MalType; | |
84 | ||
31690700 JM |
85 | typedef struct MalVal { |
86 | MalType type; | |
87 | struct MalVal *metadata; | |
88 | union { | |
89 | gint64 intnum; | |
90 | gdouble floatnum; | |
91 | char *string; | |
92 | GArray *array; | |
93 | GHashTable *hash_table; | |
94 | struct MalVal *atom_val; | |
95 | void *(*f0) (); | |
96 | void *(*f1) (void*); | |
97 | void *(*f2) (void*,void*); | |
98 | void *(*f3) (void*,void*,void*); | |
99 | void *(*f4) (void*,void*,void*,void*); | |
100 | void *(*f5) (void*,void*,void*,void*,void*); | |
101 | void *(*f6) (void*,void*,void*,void*,void*,void*); | |
102 | void *(*f7) (void*,void*,void*,void*,void*,void*,void*); | |
103 | void *(*f8) (void*,void*,void*,void*,void*,void*,void*,void*); | |
104 | void *(*f9) (void*,void*,void*,void*,void*,void*,void*,void*,void*); | |
105 | void *(*f10)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*); | |
106 | void *(*f11)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
107 | void*); | |
108 | void *(*f12)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
109 | void*,void*); | |
110 | void *(*f13)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
111 | void*,void*,void*); | |
112 | void *(*f14)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
113 | void*,void*,void*,void*); | |
114 | void *(*f15)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
115 | void*,void*,void*,void*,void*); | |
116 | void *(*f16)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
117 | void*,void*,void*,void*,void*,void*); | |
118 | void *(*f17)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
119 | void*,void*,void*,void*,void*,void*,void*); | |
120 | void *(*f18)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
121 | void*,void*,void*,void*,void*,void*,void*,void*); | |
122 | void *(*f19)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
123 | void*,void*,void*,void*,void*,void*,void*,void*,void*); | |
124 | void *(*f20)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*, | |
125 | void*,void*,void*,void*,void*,void*,void*,void*,void*,void*); | |
126 | struct { | |
127 | struct MalVal *(*evaluator)(struct MalVal *, Env *); | |
128 | struct MalVal *args; | |
129 | struct MalVal *body; | |
130 | struct Env *env; | |
131 | } func; | |
132 | } val; | |
133 | int func_arg_cnt; | |
134 | int ismacro; | |
135 | } MalVal; | |
136 | ||
137 | // Constants | |
138 | ||
139 | extern MalVal mal_nil; | |
140 | extern MalVal mal_true; | |
141 | extern MalVal mal_false; | |
142 | ||
143 | ||
144 | // Declare functions used internally (by other C code). | |
145 | // Mal visible functions are "exported" in types_ns | |
146 | ||
147 | MalVal *malval_new(MalType type, MalVal *metadata); | |
b81b2a7e | 148 | void malval_free(MalVal *mv); |
31690700 JM |
149 | MalVal *malval_new_integer(gint64 val); |
150 | MalVal *malval_new_float(gdouble val); | |
151 | MalVal *malval_new_string(char *val); | |
152 | MalVal *malval_new_symbol(char *val); | |
b8ee29b2 | 153 | MalVal *malval_new_keyword(char *val); |
31690700 | 154 | MalVal *malval_new_list(MalType type, GArray *val); |
ea81a808 JM |
155 | MalVal *malval_new_hash_map(GHashTable *val); |
156 | MalVal *malval_new_atom(MalVal *val); | |
8cb5cda4 | 157 | MalVal *malval_new_function(void *(*func)(void *), int arg_cnt); |
31690700 | 158 | |
8cb5cda4 JM |
159 | // Numbers |
160 | #define WRAP_INTEGER_OP(name, op) \ | |
b81b2a7e | 161 | static MalVal *int_ ## name(MalVal *a, MalVal *b) { \ |
8cb5cda4 JM |
162 | return malval_new_integer(a->val.intnum op b->val.intnum); \ |
163 | } | |
164 | #define WRAP_INTEGER_CMP_OP(name, op) \ | |
b81b2a7e | 165 | static MalVal *int_ ## name(MalVal *a, MalVal *b) { \ |
8cb5cda4 JM |
166 | return a->val.intnum op b->val.intnum ? &mal_true : &mal_false; \ |
167 | } | |
168 | ||
169 | // Collections | |
ea81a808 JM |
170 | MalVal *_listX(int count, ...); |
171 | MalVal *_list(MalVal *args); | |
172 | MalVal *_vector(MalVal *args); | |
173 | MalVal *_hash_map(MalVal *args); | |
174 | MalVal *_assoc_BANG(MalVal* hm, MalVal *args); | |
175 | MalVal *_dissoc_BANG(MalVal* hm, MalVal *args); | |
31690700 | 176 | |
ea81a808 | 177 | MalVal *_apply(MalVal *f, MalVal *el); |
31690700 JM |
178 | |
179 | char *_pr_str(MalVal *args, int print_readably); | |
180 | ||
31690700 JM |
181 | MalVal *_slice(MalVal *seq, int start, int end); |
182 | MalVal *_nth(MalVal *seq, int idx); | |
8cb5cda4 JM |
183 | MalVal *_first(MalVal *seq); |
184 | MalVal *_rest(MalVal *seq); | |
185 | MalVal *_last(MalVal *seq); | |
b81b2a7e LB |
186 | int _count(MalVal *obj); |
187 | ||
188 | int _atom_Q(MalVal *exp); | |
189 | int _sequential_Q(MalVal *seq); | |
190 | int _list_Q(MalVal *seq); | |
191 | int _vector_Q(MalVal *seq); | |
192 | int _hash_map_Q(MalVal *seq); | |
193 | int _equal_Q(MalVal *a, MalVal *b); | |
31690700 JM |
194 | |
195 | MalVal *_map2(MalVal *(*func)(void*, void*), MalVal *lst, void *arg2); | |
196 | ||
31690700 | 197 | #endif |