/
runt.h
437 lines (344 loc) · 12 KB
/
runt.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
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
#ifndef RUNT_H
#define RUNT_H
#define RUNT_KILOBYTE 1000
#define RUNT_MEGABYTE (RUNT_KILOBYTE * 1000)
#define RUNT_GIGABYTE (RUNT_MEGABYTE * 1000)
#define RUNT_STACK_SIZE 32
#define RUNT_REGISTER_SIZE 16
#define RUNT_MODE_PROC 1
#define RUNT_MODE_INTERACTIVE 2
#define RUNT_MODE_KEYWORD 4
#define RUNT_MODE_RUNNING 8
#define RUNT_MODE_VERBOSE 16
#define RUNT_MODE_PANIC 32
#define RUNT_MODE_END 64
#define RUNT_DICT_SIZE 128
#define RUNT_ERROR_CHECK(A) if(A == RUNT_NOT_OK) return RUNT_NOT_OK;
#define RUNT_ERROR_CHECK_VERBOSE(VM, A, STR) if(A == RUNT_NOT_OK) {\
runt_print(VM, STR);\
return RUNT_NOT_OK;\
}
#include <stdarg.h> /* a not-so-obvious header to include */
enum {
RUNT_NOT_OK = 0,
RUNT_OK,
RUNT_CONTINUE,
RUNT_ON,
RUNT_OFF,
RUNT_NIL = 0,
RUNT_FLOAT,
RUNT_STRING,
RUNT_CPTR,
RUNT_WORD,
RUNT_PROC,
RUNT_CELL,
RUNT_LIST,
RUNT_HEX,
RUNT_PLUGIN,
RUNT_END = 100 /* custom types can be numbered starting after RUNT_END */
};
typedef struct runt_vm runt_vm;
typedef struct runt_entry runt_entry;
typedef int runt_int;
typedef float runt_float;
typedef int runt_type;
typedef unsigned int runt_uint;
typedef struct {
runt_type type;
void *ud;
runt_uint pos;
} runt_ptr;
typedef runt_int (*runt_proc)(runt_vm *, runt_ptr);
typedef void (*runt_printer)(runt_vm *, const char *fmt, va_list);
typedef struct {
runt_proc fun;
runt_ptr p;
runt_uint psize;
runt_uint id;
} runt_cell;
typedef runt_int (*runt_copy_proc)(runt_vm *, runt_cell *, runt_cell *);
typedef struct {
runt_type t;
runt_ptr p;
runt_float f;
} runt_stacklet;
typedef struct {
runt_stacklet stack[RUNT_STACK_SIZE];
runt_int pos;
runt_int size;
runt_int bias;
} runt_stack;
typedef struct runt_list {
runt_int size;
runt_entry *top;
runt_entry *last;
} runt_list;
struct runt_entry {
runt_cell *cell;
runt_copy_proc copy;
runt_ptr p;
runt_uint size;
runt_uint c;
runt_uint m;
runt_list *list;
runt_entry *next;
runt_entry *prev;
runt_entry *last_word_defined;
};
typedef struct runt_dict {
runt_int nwords;
runt_list list[RUNT_DICT_SIZE];
struct runt_dict *last;
} runt_dict;
typedef struct {
unsigned char *data;
runt_uint size;
runt_uint used;
runt_uint mark;
} runt_memory_pool;
typedef struct {
runt_cell *cells;
runt_uint size;
runt_uint used;
runt_uint mark;
} runt_cell_pool;
struct runt_vm {
runt_stack stack;
runt_cell_pool cell_pool;
runt_memory_pool memory_pool;
runt_dict *dict;
runt_dict idict;
runt_uint status;
/* runt_cell *proc; */
runt_proc zproc;
runt_ptr nil;
/* the base cell for floats */
runt_cell *f_cell;
/* the base cell for strings */
runt_cell *s_cell;
/* a cell that does nothing */
runt_cell empty;
/* recursion level */
runt_uint level;
/* cell position */
runt_uint pos;
/* list of plugin handles */
runt_list plugins;
/* what to write output to */
FILE *fp;
/* command line arguments */
char **argv;
int argc;
int argpos;
runt_entry *last_word_defined;
runt_uint nwords;
runt_int (*loader)(runt_vm*);
runt_printer print;
/* list of destructors */
runt_list dtors;
/* registers */
runt_stacklet reg[RUNT_REGISTER_SIZE];
/* anonymous function */
runt_entry *anon;
/* last cell called */
runt_cell *last_cell_called;
};
/* Main */
runt_int runt_init(runt_vm *vm);
runt_int runt_reinit(runt_vm *vm);
runt_int runt_load_minimal(runt_vm *vm);
runt_int runt_load_stdlib(runt_vm *vm);
void runt_seppuku(runt_vm *vm);
runt_int runt_is_alive(runt_vm *vm);
runt_int runt_load_plugin(runt_vm *vm, const char *filename);
runt_int runt_close_plugins(runt_vm *vm);
runt_int runt_add_destructor(runt_vm *vm, runt_proc proc, runt_ptr ptr);
void runt_print(runt_vm *vm, const char *fmt, ...);
void runt_filehandle(runt_vm *vm, FILE *handle);
FILE *runt_filehandle_get(runt_vm *vm);
void runt_print_default(runt_vm *vm, const char *fmt, va_list ap);
void runt_print_set(runt_vm *vm, runt_printer printer);
int runt_vm_alloc(runt_vm *vm, runt_uint ncells, runt_uint memsize);
int runt_vm_free(runt_vm *vm);
runt_cell * runt_last_cell_called(runt_vm *vm);
const char * runt_last_word_called(runt_vm *vm);
/* Pools */
runt_int runt_cell_pool_set(runt_vm *vm, runt_cell *cells, runt_uint size);
runt_int runt_cell_pool_init(runt_vm *vm);
runt_uint runt_cell_pool_size(runt_vm *vm);
runt_uint runt_cell_pool_used(runt_vm *vm);
void runt_cell_pool_clear(runt_vm *vm);
void runt_cell_pool_list(runt_vm *vm);
runt_int runt_cell_pool_get_cell(runt_vm *vm, runt_uint id, runt_cell **cell);
runt_int runt_memory_pool_set(runt_vm *vm, unsigned char *buf, runt_uint size);
runt_uint runt_malloc(runt_vm *vm, size_t size, void **ud);
runt_int runt_memory_pool_get(runt_vm *vm, runt_uint id, void **ud);
runt_uint runt_memory_pool_size(runt_vm *vm);
runt_uint runt_memory_pool_used(runt_vm *vm);
void runt_memory_pool_clear(runt_vm *vm);
void runt_mark_set(runt_vm *vm);
void runt_pmark_set(runt_vm *vm);
runt_uint runt_mark_free(runt_vm *vm);
runt_uint runt_pmark_free(runt_vm *vm);
/* Cell Operations */
runt_uint runt_cell_new(runt_vm *vm, runt_cell **cell);
runt_int runt_cell_malloc(runt_vm *vm, runt_cell **cell);
runt_int runt_cell_link(runt_vm *vm, runt_cell *src, runt_cell *dest);
runt_int runt_cell_bind(runt_vm *vm, runt_cell *cell, runt_proc proc);
runt_int runt_cell_data(runt_vm *vm, runt_cell *cell, runt_ptr p);
runt_int runt_cell_call(runt_vm *vm, runt_cell *cell);
runt_int runt_cell_exec(runt_vm *vm, runt_cell *cell);
runt_int runt_cell_id_exec(runt_vm *vm, runt_uint id);
/*TODO: rename to runt_cell_pool_undo */
runt_int runt_cell_undo(runt_vm *vm);
void runt_cell_clear(runt_vm *vm, runt_cell *cell);
runt_int runt_cell_get_psize(runt_vm *vm, runt_cell *cell);
runt_int runt_cell_id_get(runt_vm *vm, runt_uint id, runt_cell **cell);
runt_int runt_cell_destructor(runt_vm *vm, runt_cell *cell);
runt_int runt_cell_from_stack(runt_vm *vm, runt_stacklet *s, runt_cell **cell);
/* Stack Operations */
runt_stacklet * runt_pop(runt_vm *vm);
runt_int runt_ppop(runt_vm *vm, runt_stacklet **s);
runt_stacklet * runt_push(runt_vm *vm);
runt_int runt_ppush(runt_vm *vm, runt_stacklet **s);
runt_stacklet * runt_peak(runt_vm *vm);
runt_int runt_ppeak(runt_vm *vm, runt_stacklet **s);
runt_int runt_ppeakn(runt_vm *vm, runt_stacklet **s, runt_int pos);
void runt_unpop(runt_vm *vm);
runt_float runt_stack_float(runt_vm *vm, runt_stacklet *stack);
runt_int runt_stack_bias_pos(runt_vm *vm, runt_stack *stack);
runt_int runt_stack_pos(runt_vm *vm, runt_stack *stack);
void runt_stack_dec(runt_vm *vm, runt_stack *stack);
void runt_stack_dec_n(runt_vm *vm, runt_stack *stack, runt_uint n);
void runt_stack_inc(runt_vm *vm, runt_stack *stack);
void runt_stack_init(runt_vm *vm, runt_stack *stack);
void runt_stack_bias(runt_vm *vm, runt_stack *stack, runt_int bias);
void runt_stack_unbias(runt_vm *vm, runt_stack *stack);
void runt_stacklet_copy(runt_vm *vm, runt_stacklet *src, runt_stacklet *dst);
void runt_stacklet_init(runt_vm *vm, runt_stacklet *s);
int runt_stack_dup(runt_vm *vm);
int runt_stack_swap(runt_vm *vm);
/* Pointers */
/* TODO: reconsider naming conventions for conversion functions */
runt_ptr runt_mk_ptr(runt_type type, void *ud);
runt_int runt_ref_to_cptr(runt_vm *vm, runt_uint ref, void **ud);
runt_cell * runt_to_cell(runt_ptr p);
runt_float * runt_to_float(runt_ptr p);
runt_ptr runt_mk_float(runt_vm *vm, runt_float ival);
const char * runt_to_string(runt_ptr p);
runt_ptr runt_mk_string(runt_vm *vm, const char *str, runt_uint size);
void * runt_to_cptr(runt_ptr p);
runt_ptr runt_mk_cptr(runt_vm *vm, void *cptr);
runt_list * runt_to_list(runt_ptr p);
runt_ptr runt_mk_list(runt_vm *vm, runt_list *lst);
runt_int runt_mk_cptr_cell(runt_vm *vm, void *cptr);
runt_uint runt_mk_float_cell(runt_vm *vm,
const char *name,
runt_uint size,
runt_float *flt);
/* Dictionary */
runt_uint runt_entry_create(runt_vm *vm, runt_cell *cell, runt_entry **entry);
void runt_entry_set_copy_proc(runt_entry *entry, runt_copy_proc copy);
runt_int runt_entry_copy(runt_vm *vm, runt_entry *entry, runt_cell *dest);
runt_int runt_entry_exec(runt_vm *vm, runt_entry *entry);
runt_int runt_word(runt_vm *vm,
const char *name,
runt_int size,
runt_entry *entry);
runt_int runt_word_dict(runt_vm *vm,
const char *name,
runt_int size,
runt_entry *entry,
runt_dict *dict);
runt_int runt_word_search(runt_vm *vm,
const char *name,
runt_int size,
runt_entry **entry);
runt_int runt_word_search_dict(runt_vm *vm,
const char *name,
runt_int size,
runt_entry **entry,
runt_dict *dict);
runt_int runt_word_oops(runt_vm *vm);
void runt_list_init(runt_list *lst);
runt_int runt_list_append(runt_list *lst, runt_entry *ent);
runt_int runt_list_prepend(runt_list *lst, runt_entry *ent);
runt_int runt_list_append_ptr(runt_vm *vm, runt_list *lst, runt_ptr p);
runt_int runt_list_append_cell(runt_vm *vm, runt_list *lst, runt_cell *cell);
runt_int runt_list_prepend_cell(runt_vm *vm, runt_list *lst, runt_cell *cell);
runt_int runt_list_size(runt_list *lst);
runt_entry * runt_list_top(runt_list *lst);
runt_int runt_list_pop(runt_vm *vm, runt_list *lst);
void runt_dictionary_init(runt_vm *vm);
void runt_dict_init(runt_vm *vm, runt_dict *dict);
runt_dict * runt_dictionary_get(runt_vm *vm);
void runt_dictionary_set(runt_vm *vm, runt_dict *dict);
runt_int runt_dictionary_clear(runt_vm *vm);
runt_int runt_dict_clear(runt_vm *vm, runt_dict *dict);
runt_uint runt_dictionary_size(runt_vm *vm);
runt_uint runt_dict_size(runt_vm *vm, runt_dict *dict);
runt_dict * runt_dictionary_swap(runt_vm *vm);
runt_uint runt_dictionary_new(runt_vm *vm, runt_dict **pdict);
runt_uint runt_word_define(runt_vm *vm,
const char *name,
runt_uint size,
runt_proc proc);
runt_int runt_word_last_defined(runt_vm *vm,
runt_entry *ent,
runt_uint c,
runt_uint m);
runt_uint runt_word_define_with_copy(runt_vm *vm,
const char *name,
runt_uint size,
runt_proc proc,
runt_copy_proc copy);
runt_int runt_keyword_define(runt_vm *vm,
const char *name,
runt_uint size,
runt_proc proc,
runt_cell **pcell);
runt_int runt_keyword_define_with_copy(runt_vm *vm,
const char *name,
runt_uint size,
runt_proc proc,
runt_copy_proc copy,
runt_cell **pcell);
runt_int runt_data(runt_vm *vm,
const char *name,
runt_uint size,
runt_ptr p);
runt_int runt_data_search(runt_vm *vm, const char *name, runt_ptr *p);
runt_int runt_word_bind_ptr(runt_vm *vm, runt_uint id, runt_ptr p);
runt_int runt_parse_file(runt_vm *vm, const char *filename);
runt_int runt_parse_filehandle(runt_vm *vm, FILE *fp);
runt_int runt_proc_search(runt_vm *vm,
runt_proc p,
runt_entry **entry);
const char * runt_entry_get_name(runt_entry *entry);
/* Lexing, Parsing, and Compiling */
runt_int runt_compile(runt_vm *vm, const char *str);
runt_int runt_tokenize(runt_vm *vm,
const char *str,
runt_uint size,
runt_uint *pos,
runt_uint *wsize,
runt_uint *next);
runt_type runt_lex(runt_vm *vm,
const char *str,
runt_uint pos,
runt_uint size);
runt_float runt_atof(const char *str, runt_uint pos, runt_uint size);
runt_int runt_set_state(runt_vm *vm, runt_uint mode, runt_uint state);
runt_uint runt_get_state(runt_vm *vm, runt_uint mode);
/* Procedures */
runt_int runt_proc_begin(runt_vm *vm, runt_cell *proc);
runt_int runt_proc_end(runt_vm *vm);
/* Register System */
void runt_registers_init(runt_vm *vm);
runt_int runt_register_get(runt_vm *vm, runt_int r, runt_stacklet **s);
runt_int runt_register_set(runt_vm *vm, runt_int r, runt_stacklet *s);
/* Standard Library Procedures */
runt_int runt_load_basic(runt_vm *vm);
runt_int irunt_begin(int argc, char *argv[], runt_int (*loader)(runt_vm *));
size_t runt_getline(char **lineptr, size_t *n, FILE *stream);
#endif