work on type inference some more
[ccc.git] / parse.y
1 %{
2 #include <stdio.h>
3
4 #include "ast.h"
5 #include "list.h"
6 #include "parse.h"
7
8 int yylex(void);
9 extern YYLTYPE yylloc;
10
11 void yyerror(struct ast **result, const char *str)
12 {
13 (void)result;
14 fprintf(stderr, "%d-%d: %s\n", yylloc.first_line, yylloc.last_column, str);
15 }
16
17 int yywrap()
18 {
19 return 1;
20 }
21
22 %}
23
24 %define parse.lac full
25 %define parse.error verbose
26
27 %union {
28 struct expr *expr;
29 struct stmt *stmt;
30 struct list *list;
31 struct vardecl *vardecl;
32 struct fundecl *fundecl;
33 struct type *type;
34 char *ident;
35 }
36
37 %locations
38 %token <ident> IDENT
39 %token <expr> BOOL CHAR INTEGER STRING
40 %token ARROW ASSIGN BCLOSE BINAND BINOR BOPEN CCLOSE COMMA CONS COPEN DIVIDE
41 %token DOT ELSE ERROR IF INVERSE MINUS MODULO NIL PLUS POWER RETURN SEMICOLON
42 %token SCLOSE SOPEN TIMES TBOOL TCHAR TINT TVOID VAR WHILE
43
44 %parse-param { struct ast **result }
45
46 %right BINOR
47 %right BINAND
48 %nonassoc EQ NEQ LEQ LE GEQ GE
49 %right CONS
50 %left PLUS MINUS
51 %left TIMES DIVIDE MODULO
52 %right POWER
53
54 %type <ast> start
55 %type <expr> expr
56 %type <list> args body decls fargs field fnargs nargs funtype bbody
57 %type <stmt> stmt
58 %type <type> type ftype
59 %type <vardecl> vardecl
60 %type <fundecl> fundecl
61
62 %%
63
64 start : decls { *result = ast($1); } ;
65 decls
66 : /* empty */ { $$ = NULL; }
67 | decls vardecl { $$ = list_cons(decl_var($2), $1); }
68 | decls fundecl { $$ = list_cons(decl_fun($2), $1); }
69 ;
70 vardecl
71 : VAR IDENT ASSIGN expr SEMICOLON { $$ = vardecl(NULL, $2, $4); }
72 | type IDENT ASSIGN expr SEMICOLON { $$ = vardecl($1, $2, $4); }
73 ;
74 fundecl
75 : IDENT BOPEN args BCLOSE COPEN body CCLOSE
76 { $$ = fundecl($1, $3, NULL, NULL, $6); }
77 | IDENT BOPEN args BCLOSE CONS CONS funtype ARROW ftype COPEN body CCLOSE
78 { $$ = fundecl($1, $3, $7, $9, $11); }
79 ;
80 funtype
81 : /* empty */ { $$ = NULL; }
82 | funtype ftype { $$ = list_cons($2, $1); }
83 ;
84 /* don't allow vardecls to be fully polymorph, this complicates parsing a lot */
85 type
86 : BOPEN ftype COMMA ftype BCLOSE { $$ = type_tuple($2, $4); }
87 | SOPEN ftype SCLOSE { $$ = type_list($2); }
88 | TBOOL { $$ = type_basic(btbool); }
89 | TCHAR { $$ = type_basic(btchar); }
90 | TINT { $$ = type_basic(btint); }
91 | TVOID { $$ = type_basic(btvoid); }
92 ;
93 ftype
94 : type
95 | IDENT { $$ = type_var($1); }
96 ;
97 args
98 : /* empty */ { $$ = NULL; }
99 | nargs
100 ;
101 nargs
102 : nargs COMMA IDENT { $$ = list_cons($3, $1); }
103 | IDENT { $$ = list_cons($1, NULL); }
104 ;
105 fargs
106 : /* empty */ { $$ = NULL; }
107 | fnargs
108 ;
109 fnargs
110 : fnargs COMMA expr { $$ = list_cons($3, $1); }
111 | expr { $$ = list_cons($1, NULL); }
112 ;
113 body
114 : /* empty */ { $$ = NULL; }
115 | body stmt { $$ = list_cons($2, $1); }
116 ;
117 field
118 : /* empty */ { $$ = NULL; }
119 | field DOT IDENT { $$ = list_cons($3, $1); }
120 ;
121 bbody
122 : COPEN body CCLOSE { $$ = $2; }
123 | stmt { $$ = list_cons($1, NULL); }
124 ;
125 stmt
126 : IF BOPEN expr BCLOSE bbody { $$ = stmt_if($3, $5, NULL); }
127 | IF BOPEN expr BCLOSE bbody ELSE bbody { $$ = stmt_if($3, $5, $7); }
128 | WHILE BOPEN expr BCLOSE bbody { $$ = stmt_while($3, $5); }
129 | IDENT field ASSIGN expr SEMICOLON { $$ = stmt_assign($1, $2, $4); }
130 | RETURN expr SEMICOLON { $$ = stmt_return($2); }
131 | RETURN SEMICOLON { $$ = stmt_return(NULL); }
132 | vardecl { $$ = stmt_vardecl($1); }
133 | expr SEMICOLON { $$ = stmt_expr($1); }
134 ;
135 expr
136 : expr BINOR expr { $$ = expr_binop($1, binor, $3); }
137 | expr BINAND expr { $$ = expr_binop($1, binand, $3); }
138 | expr EQ expr { $$ = expr_binop($1, eq, $3); }
139 | expr NEQ expr { $$ = expr_binop($1, neq, $3); }
140 | expr LEQ expr { $$ = expr_binop($1, leq, $3); }
141 | expr LE expr { $$ = expr_binop($1, le, $3); }
142 | expr GEQ expr { $$ = expr_binop($1, geq, $3); }
143 | expr GE expr { $$ = expr_binop($1, ge, $3); }
144 | expr CONS expr { $$ = expr_binop($1, cons, $3); }
145 | expr PLUS expr { $$ = expr_binop($1, plus, $3); }
146 | expr MINUS expr { $$ = expr_binop($1, minus, $3); }
147 | expr TIMES expr { $$ = expr_binop($1, times, $3); }
148 | expr DIVIDE expr { $$ = expr_binop($1, divide, $3); }
149 | expr MODULO expr { $$ = expr_binop($1, modulo, $3); }
150 | expr POWER expr { $$ = expr_binop($1, power, $3); }
151 | MINUS expr %prec TIMES { $$ = expr_unop(negate, $2); }
152 | INVERSE expr %prec TIMES { $$ = expr_unop(inverse, $2); }
153 | IDENT BOPEN fargs BCLOSE field { $$ = expr_funcall($1, $3, $5); }
154 | BOPEN expr COMMA expr BCLOSE { $$ = expr_tuple($2, $4); }
155 | BOPEN expr BCLOSE { $$ = $2; }
156 | INTEGER
157 | BOOL
158 | CHAR
159 | STRING
160 | IDENT field { $$ = expr_ident($1, $2); }
161 | NIL { $$ = expr_nil(); }
162 ;