summaryrefslogtreecommitdiff
path: root/lisp.y
diff options
context:
space:
mode:
Diffstat (limited to 'lisp.y')
-rw-r--r--lisp.y13
1 files changed, 10 insertions, 3 deletions
diff --git a/lisp.y b/lisp.y
index c2ca8f5..a15b451 100644
--- a/lisp.y
+++ b/lisp.y
@@ -23,7 +23,7 @@ static int is_integer(double x) {
%token <ival> LPAREN RPAREN DOT WHITESPACE
%token <ival> PLUS MINUS MULT DIV
-%type <val> sexpr atom
+%type <val> sexpr atom list list_items
%start sexprs
@@ -32,9 +32,10 @@ opt_ws: /* matches no whitespace */
| WHITESPACE;
sexprs: sexpr { print_val($1); printf("\n"); }
- | sexprs opt_ws sexpr { print_val($3); };
+ | sexprs opt_ws sexpr { print_val($3); printf("\n"); };
sexpr: atom
+ | list
| LPAREN opt_ws sexpr opt_ws DOT opt_ws sexpr opt_ws RPAREN
{
$$ = cons($3, $7);
@@ -42,6 +43,13 @@ sexpr: atom
printf("\n");
};
+list: LPAREN opt_ws list_items opt_ws RPAREN
+ { $$ = $3; };
+
+list_items: /* empty list */ { $$ = make_nil(); }
+ | sexpr opt_ws list_items { $$ = cons($1, $3); }
+ | sexpr WHITESPACE DOT WHITESPACE sexpr { $$ = cons($1, $5); };
+
atom: NUMBER
{
if(is_integer($1)) {
@@ -50,7 +58,6 @@ atom: NUMBER
$$ = make_double($1);
}
}
- | LPAREN opt_ws RPAREN { $$ = make_nil(); }
| STRING { $$ = make_string($1); };
%%