altos/lisp: Eliminate compiler warning about array bounds at -O3
[fw/altos] / src / lisp / ao_lisp.h
index e90d791ad8dc83576f24a281a337a481105c328a..25d13fa3f7c94a51e14ddbc8ce721f7982cf6aa4 100644 (file)
@@ -118,9 +118,6 @@ ao_lisp_is_const(ao_poly poly) {
        return poly & AO_LISP_CONST;
 }
 
-#define AO_LISP_POOL_BASE      (ao_lisp_pool - 4)
-#define AO_LISP_CONST_BASE     (ao_lisp_const - 4)
-
 #define AO_LISP_IS_CONST(a)    (ao_lisp_const <= ((uint8_t *) (a)) && ((uint8_t *) (a)) < ao_lisp_const + AO_LISP_POOL_CONST)
 #define AO_LISP_IS_POOL(a)     (ao_lisp_pool <= ((uint8_t *) (a)) && ((uint8_t *) (a)) < ao_lisp_pool + AO_LISP_POOL)
 
@@ -156,13 +153,33 @@ struct ao_lisp_val {
 
 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);
 }
 
@@ -173,14 +190,15 @@ ao_lisp_frame_poly(struct ao_lisp_frame *frame) {
 
 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 {
@@ -206,6 +224,7 @@ ao_lisp_stack_poly(struct ao_lisp_stack *stack)
 }
 
 extern struct ao_lisp_stack    *ao_lisp_stack;
+extern struct ao_lisp_stack    *ao_lisp_stack_free_list;
 extern ao_poly                 ao_lisp_v;
 
 #define AO_LISP_FUNC_LAMBDA    0
@@ -213,6 +232,14 @@ extern ao_poly                     ao_lisp_v;
 #define AO_LISP_FUNC_MACRO     2
 #define AO_LISP_FUNC_LEXPR     3
 
+#define AO_LISP_FUNC_FREE_ARGS 0x80
+#define AO_LISP_FUNC_MASK      0x7f
+
+#define AO_LISP_FUNC_F_LAMBDA  (AO_LISP_FUNC_FREE_ARGS | AO_LISP_FUNC_LAMBDA)
+#define AO_LISP_FUNC_F_NLAMBDA (AO_LISP_FUNC_FREE_ARGS | AO_LISP_FUNC_NLAMBDA)
+#define AO_LISP_FUNC_F_MACRO   (AO_LISP_FUNC_FREE_ARGS | AO_LISP_FUNC_MACRO)
+#define AO_LISP_FUNC_F_LEXPR   (AO_LISP_FUNC_FREE_ARGS | AO_LISP_FUNC_LEXPR)
+
 struct ao_lisp_builtin {
        uint8_t         type;
        uint8_t         args;
@@ -390,6 +417,11 @@ ao_lisp_builtin_poly(struct ao_lisp_builtin *b)
 }
 
 /* memory functions */
+
+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
 ao_lisp_mark(const struct ao_lisp_type *type, void *addr);
@@ -412,8 +444,11 @@ ao_lisp_move_memory(const struct ao_lisp_type *type, void **ref);
 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);
@@ -439,6 +474,11 @@ extern const struct ao_lisp_type ao_lisp_cons_type;
 struct ao_lisp_cons *
 ao_lisp_cons_cons(ao_poly car, struct ao_lisp_cons *cdr);
 
+extern struct ao_lisp_cons *ao_lisp_cons_free_list;
+
+void
+ao_lisp_cons_free(struct ao_lisp_cons *cons);
+
 void
 ao_lisp_cons_print(ao_poly);
 
@@ -482,6 +522,9 @@ ao_lisp_atom_print(ao_poly a);
 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);
 
@@ -556,12 +599,22 @@ ao_lisp_read_eval_print(void);
 /* 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);