begun some work on return statement
[ozulis.git] / src / lang / mugiwara / bison-parser / parser.y
blobc4403aebcc4ba1d52fb91c3031281fe83c8976af
1 %glr-parser
2 %pure-parser
3 %locations
4 %start file
5 %defines
6 %error-verbose
8 %lex-param {yyscan_t yyscanner}
9 %parse-param {yyscan_t yyscanner}
10 %parse-param {ast::File *& file}
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <iostream>
18 #include <core/assert.hh>
19 #include <ast/ast.hh>
21 #include "parser.hh"
22 #include "lexer.hh"
24 static void yyerror(YYLTYPE *yyloccp, yyscan_t yyscanner, ast::File *& file, const char *str)
26 if (file)
27 std::cerr << file->path << ":" ;
28 std::cerr << yyloccp->first_line << "." << yyloccp->first_column << "-"
29 << yyloccp->last_line << "." << yyloccp->last_column
30 << ": " << str << std::endl;
33 #define MAKE_BINARY_EXP(Type, Out, Left, Right) \
34 do { \
35 ast::Type * exp = new ast::Type(); \
36 assert(Left); \
37 assert(Right); \
38 exp = new ast::Type(); \
39 exp->left = (Left); \
40 exp->right = (Right); \
41 (Out) = exp; \
42 } while (0)
44 #define MAKE_UNARY_EXP(Type, Out, Exp) \
45 do { \
46 ast::Type * exp = new ast::Type(); \
47 assert(Exp); \
48 exp = new ast::Type(); \
49 exp->exp = (Exp); \
50 (Out) = exp; \
51 } while (0)
53 static ast::Type *
54 createType(const char * name)
56 static const struct {
57 const char * name;
58 bool isSigned;
59 int size;
60 } integerTypes[] = {
61 { "int8", true, 8 },
62 { "uint8", false, 8 },
63 { "int16", true, 16 },
64 { "uint16", false, 16 },
65 { "int32", true, 32 },
66 { "uint32", false, 32 },
67 { "int64", true, 64 },
68 { "uint64", false, 64 },
69 { "int128", true, 128 },
70 { "uint128", false, 128 },
71 { 0 }
74 for (int i = 0; integerTypes[i].name; i++)
75 if (!strcmp(name, integerTypes[i].name))
77 ast::IntegerType * itype = new ast::IntegerType();
78 itype->isSigned = integerTypes[i].isSigned;
79 itype->size = integerTypes[i].size;
80 return itype;
82 if (!strcmp("bool", name))
83 return new ast::BoolType();
84 if (!strcmp("float", name))
85 return new ast::FloatType();
86 if (!strcmp("double", name))
87 return new ast::DoubleType();
88 /// @todo resolve correctly the type
89 return new ast::Type();
94 %union
96 ast::Node * node;
97 std::vector<ast::Node *> * nodes;
98 ast::Function * funcDec;
99 ast::Type * type;
100 std::vector<ast::VarDecl *> * varDecls;
101 ast::VarDecl * varDecl;
102 ast::Block * block;
103 ast::Exp * exp;
104 ast::NumberExp * nbExp;
106 int number;
107 char * string;
108 bool boolean;
111 %token <nbExp> NUMBER
112 %token <string> ID
113 %token EQ SEMICOL DOT DDOT COMMA
114 %token EQEQ LT LTEQ GT GTEQ NEQ
115 %token ADD SUB DIV MUL MOD
116 %token OR AND XOR SHL ASHR LSHR
117 %token NOT BANG OROR ANDAND
118 %token LPAR RPAR LBR RBR
119 %token GOTO CONST CAST RETURN
120 %token IF ELSE WHILE DO FOR
122 %type <nodes> decls
123 %type <node> decl
124 %type <type> type
125 %type <varDecls> var_decls
126 %type <varDecl> var_decl
127 %type <funcDec> func_dec
128 %type <block> block
129 %type <nodes> statements
130 %type <node> statement label_statement goto_statement
131 %type <node> if_statement else_statement while_statement
132 %type <node> do_while_statement return_statement
133 %type <node> exp_statement
134 %type <exp> exp assign_exp oror_exp andand_exp or_exp xor_exp and_exp
135 %type <exp> cmp_exp shift_exp add_exp mul_exp unary_exp
136 %type <boolean> is_const
140 file: decls {
141 file = new ast::File();
142 file->decls = $1;
145 decls: decl decls {
146 assert($1);
147 $$ = $2 ? : new std::vector<ast::Node *> ();
148 $$->push_back($1);
149 } | { $$ = 0; };
151 decl: func_dec {
152 $$ = $1;
155 func_dec: type ID LPAR RPAR block {
156 $$ = new ast::Function();
157 $$->returnType = $1;
158 $$->name = $2;
159 $$->params = new std::vector<ast::Type *>();
160 $$->block = $5;
163 block: LBR var_decls statements RBR {
164 $$ = new ast::Block();
165 $$->varDecls = $2;
166 $$->statements = $3;
169 var_decls: var_decls var_decl SEMICOL {
170 assert($2);
171 $$ = $1 ? : new std::vector<ast::VarDecl *> ();
172 $$->push_back($2);
173 } | /* epsilon */ { $$ = new std::vector<ast::VarDecl *> (); };
175 var_decl: type ID {
176 $$ = new ast::VarDecl();
177 $$->type = $1;
178 $$->name = $2;
181 statements: statements statement {
182 assert($2);
183 $$ = $1 ? : new std::vector<ast::Node *> ();
184 $$->push_back($2);
185 } | /* epsilon */ { $$ = new std::vector<ast::Node *> (); };
187 statement: exp_statement { $$ = $1; }
188 | label_statement { $$ = $1; }
189 | goto_statement { $$ = $1; }
190 | if_statement { $$ = $1; }
191 | while_statement { $$ = $1; }
192 | do_while_statement { $$ = $1; }
193 | return_statement { $$ = $1; }
194 | block { $$ = $1; }
195 | SEMICOL { $$ = new ast::EmptyStatement(); };
197 exp_statement: exp SEMICOL {
198 assert($1);
199 $$ = $1;
202 label_statement: ID DDOT {
203 ast::Label * label = new ast::Label();
204 label->name = $1;
205 $$ = label;
208 goto_statement: GOTO ID SEMICOL {
209 ast::Goto * gt = new ast::Goto();
210 gt->label = $2;
211 $$ = gt;
214 if_statement: IF LPAR exp RPAR statement else_statement {
215 ast::If * ifStmt = new ast::If();
216 assert($3);
217 assert($5);
218 assert($6);
219 ifStmt->cond = $3;
220 ifStmt->trueBlock = $5;
221 ifStmt->falseBlock = $6;
222 $$ = ifStmt;
225 while_statement: WHILE LPAR exp RPAR statement {
226 ast::While * whileStmt = new ast::While;
227 assert($3);
228 assert($5);
229 whileStmt->cond = $3;
230 whileStmt->block = $5;
231 $$ = whileStmt;
234 else_statement: ELSE statement {
235 $$ = $2;
236 } | /* epsylon */ { $$ = new ast::EmptyStatement; };
238 do_while_statement: DO statement WHILE LPAR exp RPAR SEMICOL {
239 ast::DoWhile * doWhileStmt = new ast::DoWhile;
240 assert($2);
241 assert($5);
242 doWhileStmt->cond = $5;
243 doWhileStmt->block = $2;
244 $$ = doWhileStmt;
247 return_statement: RETURN SEMICOL {
248 ast::Return * ret = new ast::Return;
249 $$ = ret;
250 } | RETURN exp SEMICOL {
251 ast::ValuedReturn * ret = new ast::ValuedReturn;
252 ret->exp = $2;
253 $$ = ret;
256 type: is_const ID {
257 $$ = createType($2);
258 $$->isConst = $1;
259 $$->name = $2;
262 is_const: CONST { $$ = true; }
263 | /* espilon */ { $$ = false; };
265 exp: assign_exp {
266 assert($1);
267 $$ = $1;
270 assign_exp: ID EQ oror_exp {
271 ast::AssignExp * exp = new ast::AssignExp();
272 exp->dest = new ast::Symbol();
273 exp->dest->name = $1;
274 exp->value = $3;
275 $$ = exp;
276 } | oror_exp { assert($1); $$ = $1; };
278 oror_exp: oror_exp OROR andand_exp { MAKE_BINARY_EXP(OrOrExp, $$, $1, $3); }
279 | andand_exp { assert($1); $$ = $1; };
281 andand_exp: andand_exp ANDAND or_exp { MAKE_BINARY_EXP(AndAndExp, $$, $1, $3); }
282 | or_exp { assert($1); $$ = $1; };
284 or_exp: or_exp OR xor_exp { MAKE_BINARY_EXP(OrExp, $$, $1, $3); }
285 | xor_exp { assert($1); $$ = $1; };
287 xor_exp: xor_exp XOR and_exp { MAKE_BINARY_EXP(XorExp, $$, $1, $3); }
288 | and_exp { assert($1); $$ = $1; };
290 and_exp: and_exp AND cmp_exp { MAKE_BINARY_EXP(AndExp, $$, $1, $3); }
291 | cmp_exp { assert($1); $$ = $1; };
293 cmp_exp: shift_exp EQEQ shift_exp { MAKE_BINARY_EXP(EqExp, $$, $1, $3); }
294 | shift_exp NEQ shift_exp { MAKE_BINARY_EXP(NeqExp, $$, $1, $3); }
295 | shift_exp LT shift_exp { MAKE_BINARY_EXP(LtExp, $$, $1, $3); }
296 | shift_exp LTEQ shift_exp { MAKE_BINARY_EXP(LtEqExp, $$, $1, $3); }
297 | shift_exp GT shift_exp { MAKE_BINARY_EXP(GtExp, $$, $1, $3); }
298 | shift_exp GTEQ shift_exp { MAKE_BINARY_EXP(GtEqExp, $$, $1, $3); }
299 | shift_exp { assert($1); $$ = $1; };
301 shift_exp: shift_exp SHL add_exp { MAKE_BINARY_EXP(ShlExp, $$, $1, $3); }
302 | shift_exp ASHR add_exp { MAKE_BINARY_EXP(AShrExp, $$, $1, $3); }
303 | shift_exp LSHR add_exp { MAKE_BINARY_EXP(LShrExp, $$, $1, $3); }
304 | add_exp { assert($1); $$ = $1; };
306 add_exp: add_exp ADD mul_exp { MAKE_BINARY_EXP(AddExp, $$, $1, $3); }
307 | add_exp SUB mul_exp { MAKE_BINARY_EXP(SubExp, $$, $1, $3); }
308 | mul_exp { assert($1); $$ = $1; };
310 mul_exp: mul_exp MUL unary_exp { MAKE_BINARY_EXP(MulExp, $$, $1, $3); }
311 | mul_exp DIV unary_exp { MAKE_BINARY_EXP(DivExp, $$, $1, $3); }
312 | mul_exp MOD unary_exp { MAKE_BINARY_EXP(ModExp, $$, $1, $3); }
313 | unary_exp { assert($1); $$ = $1; };
315 unary_exp: NUMBER { $$ = $1; }
316 | ID {
317 ast::IdExp * exp = new ast::IdExp();
318 exp->name = $1;
319 $$ = exp;
320 } | LPAR exp RPAR { assert($2); $$ = $2; }
321 | BANG unary_exp { MAKE_UNARY_EXP(BangExp, $$, $2); }
322 | NOT unary_exp { MAKE_UNARY_EXP(NotExp, $$, $2); }
323 | SUB unary_exp { MAKE_UNARY_EXP(NegExp, $$, $2); }
324 | CAST LPAR type COMMA exp RPAR {
325 ast::CastExp * cast = new ast::CastExp;
326 assert($3);
327 assert($5);
328 cast->type = $3;
329 cast->exp = $5;
330 $$ = cast;
335 #ifdef WITH_MAIN
336 int main(void)
338 void *exp;
339 yyscan_t scanner;
341 yylex_init(&scanner);
342 yyparse(scanner, &exp);
343 return 0;
345 #endif /* WITH_MAIN */