summaryrefslogtreecommitdiff
path: root/src/lisp/ao_lisp_read.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-12-01 10:12:38 +0100
committerKeith Packard <keithp@keithp.com>2017-12-01 11:30:50 +0100
commitcd0bd9791a77868c226d285bf4d57e8c321755d5 (patch)
tree50a96028f0bfd8584663f43d8b286c5bc559e82b /src/lisp/ao_lisp_read.c
parent00bf2ca86b60e6501880011897cea073865c5a03 (diff)
altos/lisp: Add quasiquote
This adds read support for quasiquote syntax, and then adds a quasiquote implementation in lisp Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/lisp/ao_lisp_read.c')
-rw-r--r--src/lisp/ao_lisp_read.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/lisp/ao_lisp_read.c b/src/lisp/ao_lisp_read.c
index c5a238cc..747963ab 100644
--- a/src/lisp/ao_lisp_read.c
+++ b/src/lisp/ao_lisp_read.c
@@ -61,7 +61,7 @@ static const uint16_t lex_classes[128] = {
PRINTABLE|SPECIAL, /* ) */
PRINTABLE, /* * */
PRINTABLE|SIGN, /* + */
- PRINTABLE, /* , */
+ PRINTABLE|SPECIAL, /* , */
PRINTABLE|SIGN, /* - */
PRINTABLE|DOTC|FLOATC, /* . */
PRINTABLE, /* / */
@@ -113,7 +113,7 @@ static const uint16_t lex_classes[128] = {
PRINTABLE, /* ] */
PRINTABLE, /* ^ */
PRINTABLE, /* _ */
- PRINTABLE, /* ` */
+ PRINTABLE|SPECIAL, /* ` */
PRINTABLE, /* a */
PRINTABLE, /* b */
PRINTABLE, /* c */
@@ -314,6 +314,18 @@ _lex(void)
return QUOTE;
case '.':
return DOT;
+ case '`':
+ return QUASIQUOTE;
+ case ',':
+ c = lexc();
+ if (c == '@') {
+ add_token(c);
+ end_token();
+ return UNQUOTE_SPLICING;
+ } else {
+ lex_unget(c);
+ return UNQUOTE;
+ }
}
}
if (lex_class & POUND) {
@@ -562,11 +574,27 @@ ao_lisp_read(void)
v = AO_LISP_NIL;
break;
case QUOTE:
+ case QUASIQUOTE:
+ case UNQUOTE:
+ case UNQUOTE_SPLICING:
if (!push_read_stack(cons, read_state))
return AO_LISP_NIL;
cons++;
read_state = READ_IN_QUOTE;
- v = _ao_lisp_atom_quote;
+ switch (parse_token) {
+ case QUOTE:
+ v = _ao_lisp_atom_quote;
+ break;
+ case QUASIQUOTE:
+ v = _ao_lisp_atom_quasiquote;
+ break;
+ case UNQUOTE:
+ v = _ao_lisp_atom_unquote;
+ break;
+ case UNQUOTE_SPLICING:
+ v = _ao_lisp_atom_unquote2dsplicing;
+ break;
+ }
break;
case CLOSE:
if (!cons) {