altos/lisp: Clean up OS integration bits, add defun
[fw/altos] / src / lisp / ao_lisp_poly.c
index 1855d945d6a920abbe35fabc0de74ddd17a5747d..bfd75ae3b629a1ad9e235277418f3d528e73d6a1 100644 (file)
 
 #include "ao_lisp.h"
 
-enum math_op { math_plus, math_minus, math_times, math_divide, math_mod };
-
-ao_lisp_poly
-ao_lisp_math(struct ao_lisp_cons *cons, enum math_op op)
-{
-       ao_lisp_poly    ret = AO_LISP_NIL;
-
-       while (cons) {
-               ao_lisp_poly    car = cons->car;
-               uint8_t         rt = ao_lisp_poly_type(ret);
-               uint8_t         ct = ao_lisp_poly_type(car);
-
-               cons = cons->cdr;
-
-               if (rt == AO_LISP_NIL)
-                       ret = car;
-
-               else if (rt == AO_LISP_INT && ct == AO_LISP_INT) {
-                       int     r = ao_lisp_poly_int(ret);
-                       int     c = ao_lisp_poly_int(car);
-
-                       switch(op) {
-                       case math_plus:
-                               r += c;
-                               break;
-                       case math_minus:
-                               r -= c;
-                               break;
-                       case math_times:
-                               r *= c;
-                               break;
-                       case math_divide:
-                               if (c == 0)
-                                       return AO_LISP_NIL;
-                               r /= c;
-                               break;
-                       case math_mod:
-                               if (c == 0)
-                                       return AO_LISP_NIL;
-                               r %= c;
-                               break;
-                       }
-                       ret = ao_lisp_int_poly(r);
-               }
+#if 0
+#define DBG(...) printf (__VA_ARGS__)
+#else
+#define DBG(...)
+#endif
+
+struct ao_lisp_funcs {
+       void (*print)(ao_poly);
+       void (*patom)(ao_poly);
+};
 
-               else if (rt == AO_LISP_STRING && ct == AO_LISP_STRING && op == math_plus)
-                       ret = ao_lisp_string_poly(ao_lisp_string_cat(ao_lisp_poly_string(ret),
-                                                                    ao_lisp_poly_string(car)));
-               else {
-                       /* XXX exception */
-                       return AO_LISP_NIL;
-               }
-       }
-       return ret;
-}
+static const struct ao_lisp_funcs ao_lisp_funcs[AO_LISP_NUM_TYPE] = {
+       [AO_LISP_CONS] = {
+               .print = ao_lisp_cons_print,
+               .patom = ao_lisp_cons_patom,
+       },
+       [AO_LISP_STRING] = {
+               .print = ao_lisp_string_print,
+               .patom = ao_lisp_string_patom,
+       },
+       [AO_LISP_INT] = {
+               .print = ao_lisp_int_print,
+               .patom = ao_lisp_int_print,
+       },
+       [AO_LISP_ATOM] = {
+               .print = ao_lisp_atom_print,
+               .patom = ao_lisp_atom_print,
+       },
+       [AO_LISP_BUILTIN] = {
+               .print = ao_lisp_builtin_print,
+               .patom = ao_lisp_builtin_print,
+       },
+       [AO_LISP_FRAME] = {
+               .print = ao_lisp_frame_print,
+               .patom = ao_lisp_frame_print,
+       },
+       [AO_LISP_LAMBDA] = {
+               .print = ao_lisp_lambda_print,
+               .patom = ao_lisp_lambda_print,
+       },
+};
 
-ao_lisp_poly
-ao_lisp_plus(struct ao_lisp_cons *cons)
+static const struct ao_lisp_funcs *
+funcs(ao_poly p)
 {
-       return ao_lisp_math(cons, math_plus);
-}
+       uint8_t type = ao_lisp_poly_type(p);
 
-ao_lisp_poly
-ao_lisp_minus(struct ao_lisp_cons *cons)
-{
-       return ao_lisp_math(cons, math_minus);
+       if (type < AO_LISP_NUM_TYPE)
+               return &ao_lisp_funcs[type];
+       return NULL;
 }
 
-ao_lisp_poly
-ao_lisp_times(struct ao_lisp_cons *cons)
+void
+ao_lisp_poly_print(ao_poly p)
 {
-       return ao_lisp_math(cons, math_times);
-}
+       const struct ao_lisp_funcs *f = funcs(p);
 
-ao_lisp_poly
-ao_lisp_divide(struct ao_lisp_cons *cons)
-{
-       return ao_lisp_math(cons, math_divide);
+       if (f && f->print)
+               f->print(p);
 }
 
-ao_lisp_poly
-ao_lisp_mod(struct ao_lisp_cons *cons)
+void
+ao_lisp_poly_patom(ao_poly p)
 {
-       return ao_lisp_math(cons, math_mod);
-}
-
-static const struct ao_lisp_builtin builtin_plus = {
-       .type = AO_LISP_BUILTIN,
-       .func = ao_lisp_plus,
-       .name = "+"
-};
+       const struct ao_lisp_funcs *f = funcs(p);
 
-static const struct ao_lisp_atom atom_plus = {
-       .type = AO_LISP_ATOM,
-       .val = AO_LISP_OTHER_POLY(&builtin_plus),
-       .next = AO_LISP_ATOM_CONST,
-       .name = "plus"
-};
-
-/*
-static const struct ao_lisp_builtin builtin_minus = {
-       .type = AO_LISP_BUILTIN,
-       .func = ao_lisp_minus
-};
-
-static const struct ao_lisp_builtin builtin_times = {
-       .type = AO_LISP_BUILTIN,
-       .func = ao_lisp_times
-};
-
-*/
+       if (f && f->patom)
+               f->patom(p);
+}
 
-const struct ao_lisp_atom const *ao_lisp_builtins[] = {
-       &atom_plus,
-       0
-};