struct ao_lisp_frame {
uint8_t type;
- uint8_t num;
- ao_poly next;
+ uint8_t _num;
+ ao_poly prev;
struct ao_lisp_val vals[];
};
+#define AO_LISP_FRAME_NUM_MASK 0x7f
+
+/* Set when the frame escapes the lambda */
+#define AO_LISP_FRAME_MARK 0x80
+
+static inline int ao_lisp_frame_num(struct ao_lisp_frame *f) {
+ if (f->_num == 0xff)
+ ao_lisp_abort();
+ return f->_num & AO_LISP_FRAME_NUM_MASK;
+}
+
+static inline int ao_lisp_frame_marked(struct ao_lisp_frame *f) {
+ if (f->_num == 0xff)
+ ao_lisp_abort();
+ return f->_num & AO_LISP_FRAME_MARK;
+}
+
static inline struct ao_lisp_frame *
ao_lisp_poly_frame(ao_poly poly) {
+ struct ao_lisp_frame *frame = ao_lisp_ref(poly);
+ if (frame && frame->_num == 0xff)
+ ao_lisp_abort();
return ao_lisp_ref(poly);
}
enum eval_state {
eval_sexpr, /* Evaluate an sexpr */
- eval_val,
- eval_formal,
- eval_exec,
- eval_cond,
- eval_cond_test,
- eval_progn,
- eval_while,
- eval_while_test,
+ eval_val, /* Value computed */
+ eval_formal, /* Formal computed */
+ eval_exec, /* Start a lambda evaluation */
+ eval_cond, /* Start next cond clause */
+ eval_cond_test, /* Check cond condition */
+ eval_progn, /* Start next progn entry */
+ eval_while, /* Start while condition */
+ eval_while_test, /* Check while condition */
+ eval_macro, /* Finished with macro generation */
};
struct ao_lisp_stack {
/* memory functions */
-extern int ao_lisp_collects;
+extern int ao_lisp_collects[2];
+extern int ao_lisp_freed[2];
+extern int ao_lisp_loops[2];
/* returns 1 if the object was already marked */
int
void *
ao_lisp_alloc(int size);
-void
-ao_lisp_collect(void);
+#define AO_LISP_COLLECT_FULL 1
+#define AO_LISP_COLLECT_INCREMENTAL 0
+
+int
+ao_lisp_collect(uint8_t style);
void
ao_lisp_cons_stash(int id, struct ao_lisp_cons *cons);
struct ao_lisp_atom *
ao_lisp_atom_intern(char *name);
+ao_poly *
+ao_lisp_atom_ref(struct ao_lisp_frame *frame, ao_poly atom);
+
ao_poly
ao_lisp_atom_get(ao_poly atom);
/* frame */
extern const struct ao_lisp_type ao_lisp_frame_type;
+#define AO_LISP_FRAME_FREE 4
+
+extern struct ao_lisp_frame *ao_lisp_frame_free_list[AO_LISP_FRAME_FREE];
+
+ao_poly
+ao_lisp_frame_mark(struct ao_lisp_frame *frame);
+
ao_poly *
ao_lisp_frame_ref(struct ao_lisp_frame *frame, ao_poly atom);
struct ao_lisp_frame *
ao_lisp_frame_new(int num);
+void
+ao_lisp_frame_free(struct ao_lisp_frame *frame);
+
int
ao_lisp_frame_add(struct ao_lisp_frame **frame, ao_poly atom, ao_poly val);