rewrite to union type, much better
[ccc.git] / parse.y
1 %{
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5
6 #include "ast.h"
7
8 #include "y.tab.h"
9
10 int yylex(void);
11
12 void yyerror(struct ast **result, const char *str)
13 {
14 ast_free(*result);
15 fprintf(stderr, "error: %s\n", str);
16 }
17
18 int yywrap()
19 {
20 return 1;
21 }
22
23 %}
24
25 %union
26 {
27 struct expr *expr;
28 struct stmt *stmt;
29 struct list *list;
30 struct vardecl vardecl;
31 struct decl *decl;
32 char *ident;
33 }
34
35 //%define parse.error verbose
36 %token <ident> IDENT
37 %token <expr> BOOL CHAR INTEGER
38 %token ASSIGN BCLOSE BINAND BINOR BOPEN CCLOSE COMMA CONS COPEN DIVIDE DOT ELSE
39 %token IF INVERSE MINUS MODULO NIL PLUS POWER RETURN SEMICOLON TIMES VAR WHILE
40
41 %parse-param { struct ast **result }
42
43 %right BINOR
44 %right BINAND
45 %nonassoc EQ NEQ LEQ LE GEQ GE
46 %right CONS
47 %left PLUS MINUS
48 %left TIMES DIVIDE MODULO
49 %right POWER
50
51 %type <ast> start
52 %type <expr> expr
53 %type <list> args body decls fargs field fnargs nargs
54 %type <decl> fundecl
55 %type <vardecl> vardecl
56 %type <stmt> stmt
57
58 %%
59
60 start : decls { *result = ast($1); } ;
61 decls
62 : { $$ = NULL; }
63 | decls vardecl SEMICOLON { $$ = list_cons(decl_var($2), $1); }
64 | decls fundecl { $$ = list_cons($2, $1); }
65 ;
66 vardecl
67 : VAR IDENT ASSIGN expr { $$ = vardecl($2, $4); }
68 ;
69 fundecl
70 : IDENT BOPEN args BCLOSE COPEN body CCLOSE
71 { $$ = decl_fun($1, $3, $6); }
72 ;
73 args
74 : { $$ = NULL; }
75 | nargs
76 ;
77 nargs
78 : nargs COMMA IDENT { $$ = list_cons($3, $1); }
79 | IDENT { $$ = list_cons($1, NULL); }
80 ;
81 fargs
82 : { $$ = NULL; }
83 | fnargs
84 ;
85 fnargs
86 : fnargs COMMA expr { $$ = list_cons($3, $1); }
87 | expr { $$ = list_cons($1, NULL); }
88 ;
89 body
90 : { $$ = NULL; }
91 | body stmt { $$ = list_cons($2, $1); }
92 ;
93 stmt
94 : IF BOPEN expr BCLOSE COPEN body CCLOSE ELSE COPEN body CCLOSE
95 { $$ = stmt_if($3, $6, $10); }
96 | WHILE BOPEN expr BCLOSE COPEN body CCLOSE
97 { $$ = stmt_while($3, $6); }
98 | expr SEMICOLON { $$ = stmt_expr($1); }
99 | IDENT ASSIGN expr SEMICOLON { $$ = stmt_assign($1, $3); }
100 | RETURN expr SEMICOLON { $$ = stmt_return($2); }
101 | RETURN SEMICOLON { $$ = stmt_return(NULL); }
102 | vardecl SEMICOLON { $$ = stmt_vardecl($1); }
103 ;
104 field
105 : { $$ = NULL; }
106 | field DOT IDENT { $$ = list_cons($3, $1); }
107 expr
108 : expr BINOR expr { $$ = expr_binop($1, binor, $3); }
109 | expr BINAND expr { $$ = expr_binop($1, binand, $3); }
110 | expr EQ expr { $$ = expr_binop($1, eq, $3); }
111 | expr NEQ expr { $$ = expr_binop($1, neq, $3); }
112 | expr LEQ expr { $$ = expr_binop($1, leq, $3); }
113 | expr LE expr { $$ = expr_binop($1, le, $3); }
114 | expr GEQ expr { $$ = expr_binop($1, geq, $3); }
115 | expr GE expr { $$ = expr_binop($1, ge, $3); }
116 | expr CONS expr { $$ = expr_binop($1, cons, $3); }
117 | expr PLUS expr { $$ = expr_binop($1, plus, $3); }
118 | expr MINUS expr { $$ = expr_binop($1, minus, $3); }
119 | expr TIMES expr { $$ = expr_binop($1, times, $3); }
120 | expr DIVIDE expr { $$ = expr_binop($1, divide, $3); }
121 | expr MODULO expr { $$ = expr_binop($1, modulo, $3); }
122 | expr POWER expr { $$ = expr_binop($1, power, $3); }
123 | MINUS expr { $$ = expr_unop(negate, $2); }
124 | INVERSE expr %prec TIMES { $$ = expr_unop(inverse, $2); }
125 | BOPEN expr COMMA expr BCLOSE { $$ = expr_tuple($2, $4); }
126 | BOPEN expr BCLOSE { $$ = $2; }
127 | IDENT BOPEN fargs BCLOSE { $$ = expr_funcall($1, $3); }
128 | INTEGER
129 | BOOL
130 | CHAR
131 | IDENT field { $$ = expr_ident($1, $2); }
132 | NIL { $$ = expr_nil(); }
133 ;