return c;
}
+static inline void
+ao_lisp_os_flush(void)
+{
+ flush();
+}
+
static inline void
ao_lisp_abort(void)
{
#define _ao_lisp_atom_cdr _atom("cdr")
#define _ao_lisp_atom_cons _atom("cons")
#define _ao_lisp_atom_last _atom("last")
+#define _ao_lisp_atom_length _atom("length")
#define _ao_lisp_atom_cond _atom("cond")
#define _ao_lisp_atom_lambda _atom("lambda")
#define _ao_lisp_atom_led _atom("led")
#define _ao_lisp_atom_delay _atom("delay")
+#define _ao_lisp_atom_pack _atom("pack")
+#define _ao_lisp_atom_unpack _atom("unpack")
+#define _ao_lisp_atom_flush _atom("flush")
#define _ao_lisp_atom_eval _atom("eval")
#define _ao_lisp_atom_read _atom("read")
#define _ao_lisp_atom_eof _atom("eof")
builtin_cdr,
builtin_cons,
builtin_last,
+ builtin_length,
builtin_quote,
builtin_set,
builtin_setq,
builtin_greater,
builtin_less_equal,
builtin_greater_equal,
+ builtin_pack,
+ builtin_unpack,
+ builtin_flush,
builtin_delay,
builtin_led,
_builtin_last
void
ao_lisp_cons_patom(ao_poly);
+int
+ao_lisp_cons_length(struct ao_lisp_cons *cons);
+
/* string */
extern const struct ao_lisp_type ao_lisp_string_type;
char *
ao_lisp_string_cat(char *a, char *b);
+ao_poly
+ao_lisp_string_pack(struct ao_lisp_cons *cons);
+
+ao_poly
+ao_lisp_string_unpack(char *a);
+
void
ao_lisp_string_print(ao_poly s);
[builtin_cdr] = _ao_lisp_atom_cdr,
[builtin_cons] = _ao_lisp_atom_cons,
[builtin_last] = _ao_lisp_atom_last,
+ [builtin_length] = _ao_lisp_atom_length,
[builtin_quote] = _ao_lisp_atom_quote,
[builtin_set] = _ao_lisp_atom_set,
[builtin_setq] = _ao_lisp_atom_setq,
[builtin_greater] = _ao_lisp_atom_3e,
[builtin_less_equal] = _ao_lisp_atom_3c3d,
[builtin_greater_equal] = _ao_lisp_atom_3e3d,
+ [builtin_pack] = _ao_lisp_atom_pack,
+ [builtin_unpack] = _ao_lisp_atom_unpack,
+ [builtin_flush] = _ao_lisp_atom_flush,
[builtin_delay] = _ao_lisp_atom_delay,
[builtin_led] = _ao_lisp_atom_led,
};
return AO_LISP_NIL;
}
+ao_poly
+ao_lisp_length(struct ao_lisp_cons *cons)
+{
+ if (!ao_lisp_check_argc(_ao_lisp_atom_last, cons, 1, 1))
+ return AO_LISP_NIL;
+ if (!ao_lisp_check_argt(_ao_lisp_atom_last, cons, 0, AO_LISP_CONS, 1))
+ return AO_LISP_NIL;
+ return ao_lisp_int_poly(ao_lisp_cons_length(ao_lisp_poly_cons(ao_lisp_arg(cons, 0))));
+}
+
ao_poly
ao_lisp_quote(struct ao_lisp_cons *cons)
{
return ao_lisp_compare(cons, builtin_greater_equal);
}
+ao_poly
+ao_lisp_pack(struct ao_lisp_cons *cons)
+{
+ if (!ao_lisp_check_argc(_ao_lisp_atom_pack, cons, 1, 1))
+ return AO_LISP_NIL;
+ if (!ao_lisp_check_argt(_ao_lisp_atom_pack, cons, 0, AO_LISP_CONS, 1))
+ return AO_LISP_NIL;
+ return ao_lisp_string_pack(ao_lisp_poly_cons(ao_lisp_arg(cons, 0)));
+}
+
+ao_poly
+ao_lisp_unpack(struct ao_lisp_cons *cons)
+{
+ if (!ao_lisp_check_argc(_ao_lisp_atom_unpack, cons, 1, 1))
+ return AO_LISP_NIL;
+ if (!ao_lisp_check_argt(_ao_lisp_atom_unpack, cons, 0, AO_LISP_STRING, 0))
+ return AO_LISP_NIL;
+ return ao_lisp_string_unpack(ao_lisp_poly_string(ao_lisp_arg(cons, 0)));
+}
+
+ao_poly
+ao_lisp_flush(struct ao_lisp_cons *cons)
+{
+ if (!ao_lisp_check_argc(_ao_lisp_atom_flush, cons, 0, 0))
+ return AO_LISP_NIL;
+ ao_lisp_os_flush();
+ return _ao_lisp_atom_t;
+}
+
ao_poly
ao_lisp_led(struct ao_lisp_cons *cons)
{
[builtin_cdr] = ao_lisp_cdr,
[builtin_cons] = ao_lisp_cons,
[builtin_last] = ao_lisp_last,
+ [builtin_length] = ao_lisp_length,
[builtin_quote] = ao_lisp_quote,
[builtin_set] = ao_lisp_set,
[builtin_setq] = ao_lisp_setq,
[builtin_greater] = ao_lisp_greater,
[builtin_less_equal] = ao_lisp_less_equal,
[builtin_greater_equal] = ao_lisp_greater_equal,
+ [builtin_pack] = ao_lisp_pack,
+ [builtin_unpack] = ao_lisp_unpack,
+ [builtin_flush] = ao_lisp_flush,
[builtin_led] = ao_lisp_led,
[builtin_delay] = ao_lisp_delay,
};
cons = ao_lisp_poly_cons(cons->cdr);
}
}
+
+int
+ao_lisp_cons_length(struct ao_lisp_cons *cons)
+{
+ int len = 0;
+ while (cons) {
+ len++;
+ cons = ao_lisp_poly_cons(cons->cdr);
+ }
+ return len;
+}
.move = lambda_move,
};
-static int
-ao_lisp_cons_length(struct ao_lisp_cons *cons)
-{
- int len = 0;
- while (cons) {
- len++;
- cons = ao_lisp_poly_cons(cons->cdr);
- }
- return len;
-}
-
void
ao_lisp_lambda_print(ao_poly poly)
{
"cdr", AO_LISP_FUNC_LAMBDA, builtin_cdr,
"cons", AO_LISP_FUNC_LAMBDA, builtin_cons,
"last", AO_LISP_FUNC_LAMBDA, builtin_last,
+ "length", AO_LISP_FUNC_LAMBDA, builtin_length,
"quote", AO_LISP_FUNC_NLAMBDA, builtin_quote,
"set", AO_LISP_FUNC_LAMBDA, builtin_set,
"setq", AO_LISP_FUNC_MACRO, builtin_setq,
">", AO_LISP_FUNC_LEXPR, builtin_greater,
"<=", AO_LISP_FUNC_LEXPR, builtin_less_equal,
">=", AO_LISP_FUNC_LEXPR, builtin_greater_equal,
+ "pack", AO_LISP_FUNC_LAMBDA, builtin_pack,
+ "unpack", AO_LISP_FUNC_LAMBDA, builtin_unpack,
+ "flush", AO_LISP_FUNC_LAMBDA, builtin_flush,
"delay", AO_LISP_FUNC_LAMBDA, builtin_delay,
"led", AO_LISP_FUNC_LEXPR, builtin_led,
};
return getchar();
}
+static inline void
+ao_lisp_os_flush() {
+ fflush(stdout);
+}
+
static inline void
ao_lisp_abort(void)
{
(void) addr;
}
+const struct ao_lisp_type ao_lisp_string_type = {
+ .mark = string_mark,
+ .size = string_size,
+ .move = string_move,
+};
+
char *
ao_lisp_string_new(int len) {
char *a = ao_lisp_alloc(len + 1);
return r;
}
-const struct ao_lisp_type ao_lisp_string_type = {
- .mark = string_mark,
- .size = string_size,
- .move = string_move,
-};
+ao_poly
+ao_lisp_string_pack(struct ao_lisp_cons *cons)
+{
+ int len = ao_lisp_cons_length(cons);
+ char *r = ao_lisp_alloc(len + 1);
+ char *s = r;
+
+ while (cons) {
+ if (ao_lisp_poly_type(cons->car) != AO_LISP_INT)
+ return ao_lisp_error(AO_LISP_INVALID, "non-int passed to pack");
+ *s++ = ao_lisp_poly_int(cons->car);
+ cons = ao_lisp_poly_cons(cons->cdr);
+ }
+ *s++ = 0;
+ return ao_lisp_string_poly(r);
+}
+
+ao_poly
+ao_lisp_string_unpack(char *a)
+{
+ struct ao_lisp_cons *cons = NULL, *tail = NULL;
+ int c;
+
+ ao_lisp_root_add(&ao_lisp_cons_type, &cons);
+ ao_lisp_root_add(&ao_lisp_cons_type, &tail);
+ while ((c = *a++)) {
+ struct ao_lisp_cons *n = ao_lisp_cons_cons(ao_lisp_int_poly(c), NULL);
+ if (!n) {
+ cons = NULL;
+ break;
+ }
+ if (tail)
+ tail->cdr = ao_lisp_cons_poly(n);
+ else
+ cons = n;
+ tail = n;
+ }
+ ao_lisp_root_clear(&cons);
+ ao_lisp_root_clear(&tail);
+ return ao_lisp_cons_poly(cons);
+}
void
ao_lisp_string_print(ao_poly p)
extern int ao_lisp_getc(void);
+static inline void
+ao_lisp_os_flush() {
+ fflush(stdout);
+}
+
static inline void
ao_lisp_abort(void)
{