diff options
| author | Felix Perktold <Felix.Perktold@student.uibk.ac.at> | 2025-12-20 21:59:28 +0100 |
|---|---|---|
| committer | Felix Perktold <Felix.Perktold@student.uibk.ac.at> | 2025-12-20 21:59:28 +0100 |
| commit | 5eeb355805e0d5d91981dbe7eacb078f41da0437 (patch) | |
| tree | d4d2a76e7988cf63aa9438d2b42d0a4a4656ee42 /lisp.y | |
init commit
Diffstat (limited to 'lisp.y')
| -rw-r--r-- | lisp.y | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -0,0 +1,59 @@ +%{ +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "lisp.h" + +int yylex(void); +int yyerror(const char *s); + +static int is_integer(double x) { + return floor(x) == x && isfinite(x); +} +%} + +%union { + int ival; + double dval; + const char *strval; + value *val; +} +%token <dval> NUMBER +%token <strval> STRING +%token <ival> LPAREN RPAREN DOT WHITESPACE +%token <ival> PLUS MINUS MULT DIV + +%type <val> sexpr atom sexprs + +%start sexprs + +%% +opt_ws: /* matches no whitespace */ + | WHITESPACE; + +sexprs: sexpr + | sexprs opt_ws sexpr; + +sexpr: atom + | LPAREN opt_ws sexpr opt_ws DOT opt_ws sexpr opt_ws RPAREN + { + $$ = cons($3, $7); + print_val($$); + printf("\n"); + }; + +atom: NUMBER + { + if(is_integer($1)) { + $$ = make_int($1); + } else { + $$ = make_double($1); + } + } + | LPAREN opt_ws RPAREN { $$ = make_nil(); } + | STRING { $$ = make_string($1); }; +%% + +int yyerror(const char *s) { + printf("%s\n",s); +} |
