GCC Rust: Parsing in floats now
[official-gcc.git] / gcc / rust / rs-parser.cc
blobc3c8c2cea35a5bbb7b96f003a5ef189cc16e89af
1 #include "rust.h"
2 #include "y.rs.h"
4 yystype yylval;
5 static int sym;
6 static int __yyerror;
7 extern int yylineno;
9 static void yyerror (const char *, ...);
10 extern int yylex (void);
11 static bool __yyaccept__ (int, bool);
12 static bool yyexpect (int);
14 #ifdef _DEBUG
15 # define yylex_() \
16 yylex (); \
17 do { \
18 char *__token = yytoken_string (sym); \
19 printf ("[%i:%s]\n", sym, __token); \
20 free (__token); \
21 } while (0)
22 #else
23 # define yylex_() yylex ()
24 #endif
26 static std::vector<ALLOCA_> * alloca_modifiers (void);
28 static rdot type (void);
29 static rdot target (void);
30 static rdot suite (void);
31 static rdot else_block (void);
32 static rdot elif_block (void);
33 static rdot if_block (void);
34 static rdot struct_conditional (void);
35 static rdot primary (void);
36 static rdot factor1 (void);
37 static rdot factor2 (void);
38 static rdot expression (void);
40 static vec<rdot, va_gc> * symStack;
41 static const char * token_strings [] = {
42 "impl",
43 "as",
44 "break",
45 "continue",
46 "do",
47 "fn",
48 "let",
49 "mut",
50 "loop",
51 "static",
52 "->",
53 "bool",
54 "int",
55 "uint",
56 "float",
57 "::",
58 "enum",
59 "==",
60 "!=",
61 "<",
62 ">",
63 "<=",
64 ">=",
65 "struct",
66 "while",
67 "if",
68 "else",
69 "self",
70 "match",
71 "=>",
72 "true",
73 "false",
74 "string_literal",
75 "identifier",
76 "integer",
77 "pub",
78 "for",
79 "trait",
80 "else if",
81 "float",
82 "unknown"
85 static char *
86 yytoken_string (int token)
88 char retval [128];
89 memset (retval, 0, 128);
90 if (token >= 258 && token <= 298)
91 strncpy (retval, token_strings [token-258-1], 128);
92 else
93 retval [0] = (char) token;
94 return xstrdup (retval);
97 #define yyaccept(_X) __yyaccept__ (_X, true)
98 #define yyaccept_(_X) __yyaccept__ (_X, false)
99 static
100 bool __yyaccept__ (int s, bool forward)
102 if (sym == s)
104 if (forward)
106 sym = yylex_ ();
108 return true;
110 return false;
113 static
114 bool yyexpect (int s)
116 bool retval = false;
117 if (yyaccept (s) == true)
118 retval = true;
119 else
121 char * e1 = yytoken_string (s);
122 char * e2 = yytoken_string (sym);
123 yyerror ("expected [%s] got [%s]", e1, e2);
124 free (e1);
125 free (e2);
127 return retval;
130 /* Also realy need to make use of location_t and gcc diagnostics .. */
131 /* this is really hacky but its ok for now really need to fix this though */
132 static void __attribute__ ((format (printf, 1, 2)))
133 yyerror (const char * fmt, ...)
135 __yyerror += 1;
136 char * buffer = (char *) alloca (512);
137 memset (buffer, 0, 512);
139 va_list vl;
140 va_start (vl, fmt);
141 vsprintf (buffer, fmt, vl);
142 va_end (vl);
144 char * buffer_message = (char *) alloca (512);
145 memset (buffer_message, 0, 512);
146 snprintf (buffer_message, 512, "syntax error at %i: [%s]", yylineno, buffer);
148 fatal_error ("%s", buffer_message);
151 std::vector<ALLOCA_> * alloca_modifiers (void)
153 std::vector<ALLOCA_> * allocas = new std::vector<ALLOCA_>;
154 while (sym == '~' || sym == '&' || sym == '*')
156 ALLOCA_ mod;
157 switch (sym)
159 case '~':
160 mod = ALLOC_HEAP;
161 break;
162 case '&':
163 mod = ALLOC_REF;
164 break;
165 case '*':
166 mod = ALLOC_DEREF;
167 break;
168 default:
169 break;
171 yyexpect (sym);
172 allocas->push_back (mod);
174 return allocas;
177 rdot type (void)
179 std::vector<ALLOCA_> * mem = alloca_modifiers ();
180 rdot retval = NULL_DOT;
181 if (yyaccept (TYPE_INT))
182 retval = rdot_build_decl1 (RTYPE_INT, NULL_DOT);
183 else if (yyaccept (TYPE_UINT))
184 retval = rdot_build_decl1 (RTYPE_UINT, NULL_DOT);
185 else if (yyaccept (TYPE_FLOAT))
186 retval = rdot_build_decl1 (RTYPE_FLOAT, NULL_DOT);
187 else if (yyaccept (TYPE_BOOL))
188 retval = rdot_build_decl1 (RTYPE_BOOL, NULL_DOT);
189 else if (yyaccept (IDENTIFIER))
191 char * sid = yylval.string;
192 retval = rdot_build_decl1 (RTYPE_USER_STRUCT,
193 rdot_build_identifier (sid));
194 free (sid);
196 else
197 yyerror ("expected a type got [%s]", yytoken_string (sym));
199 RDOT_MMEM_COPY (mem, RDOT_MEM_MODIFIER (retval));
200 delete mem;
202 return retval;
205 rdot target (void)
207 yyexpect (LET);
208 bool qual = true;
209 if (yyaccept (MUT))
210 qual = false;
212 yyexpect (IDENTIFIER);
213 char * tid = yylval.string;
215 rdot ltype = NULL_DOT;
216 if (yyaccept (':'))
217 ltype = type ();
218 if (ltype == NULL_DOT)
219 ltype = rdot_build_decl1 (RTYPE_INFER, NULL_DOT);
221 rdot retval = rdot_build_varDecl (ltype, qual,
222 rdot_build_identifier (tid));
223 free (tid);
224 return retval;
227 void argument_list_ (rdot head)
229 if (yyaccept_ (')'))
230 return;
232 rdot p = expression ();
233 if (head == NULL_DOT)
234 vec_safe_push (symStack, p);
235 else
236 RDOT_CHAIN (head) = p;
238 if (yyaccept (','))
239 argument_list_ (p);
242 rdot argument_list ()
244 rdot retval = NULL_DOT;
245 size_t prev = symStack->length ();
246 argument_list_ (NULL_DOT);
247 size_t next = symStack->length ();
249 if (next > prev)
250 retval = symStack->pop ();
251 return retval;
254 rdot struct_elem ()
256 yyexpect (IDENTIFIER);
257 char * selem = yylval.string;
258 yyexpect (':');
259 rdot expr = expression ();
260 rdot retval = rdot_build_decl2 (D_STRUCT_PARAM,
261 rdot_build_identifier (selem),
262 expr);
263 free (selem);
264 return retval;
267 void struct_init_list_ (rdot head)
269 if (yyaccept_ ('}'))
270 return;
271 rdot e = struct_elem ();
272 if (head == NULL_DOT)
273 vec_safe_push (symStack, e);
274 else
275 RDOT_CHAIN (head) = e;
276 if (yyaccept (','))
277 struct_init_list_ (e);
280 rdot struct_init_list (void)
282 rdot retval = NULL_DOT;
283 size_t prev = symStack->length ();
284 struct_init_list_ (NULL_DOT);
285 size_t next = symStack->length ();
287 if (next > prev)
288 retval = symStack->pop ();
289 return retval;
292 rdot primary (void)
294 rdot retval = NULL_DOT;
295 std::vector<ALLOCA_> * mem = alloca_modifiers ();
296 if (yyaccept (IDENTIFIER))
298 // maybe call...
299 char * pid = yylval.string;
300 if (yyaccept_ ('('))
302 yyexpect ('(');
303 rdot alist = argument_list ();
304 yyexpect (')');
305 retval = rdot_build_decl2 (D_CALL_EXPR,
306 rdot_build_identifier (pid),
307 alist);
309 // struct init
310 else if (yyaccept_ ('{'))
312 yyexpect ('{');
313 rdot sls = struct_init_list ();
314 yyexpect ('}');
315 retval = rdot_build_decl2 (D_STRUCT_INIT,
316 rdot_build_identifier (pid),
317 sls);
319 // just a simple identifier...
320 else
321 retval = rdot_build_identifier (pid);
322 free (pid);
324 else if (yyaccept (INTEGER))
325 retval = rdot_build_integer (yylval.integer);
326 else if (yyaccept (FLOAT))
327 retval = rdot_build_float (yylval.ffloat);
328 else if (yyaccept (STRING))
329 retval = rdot_build_string (yylval.string);
330 else if (yyaccept (XFALSE))
331 retval = rdot_build_bool (false);
332 else if (yyaccept (XTRUE))
333 retval = rdot_build_bool (true);
334 else
335 yyerror ("expected a primary got [%s]", yytoken_string (sym));
337 RDOT_MMEM_COPY (mem, RDOT_MEM_MODIFIER (retval));
338 delete mem;
339 return retval;
342 rdot factor1 (void)
344 rdot retval = NULL_DOT;
345 if (yyaccept (IDENTIFIER))
347 char * pid = yylval.string;
348 if (yyaccept ('='))
350 rdot rhs = expression ();
351 retval = rdot_build_decl2 (D_MODIFY_EXPR, rdot_build_identifier (pid), rhs);
353 else if (yyaccept_ ('('))
355 yyexpect ('(');
356 rdot alist = argument_list ();
357 yyexpect (')');
358 retval = rdot_build_decl2 (D_CALL_EXPR,
359 rdot_build_identifier (pid),
360 alist);
362 // struct init
363 else if (yyaccept_ ('{'))
365 yyexpect ('{');
366 rdot sls = struct_init_list ();
367 yyexpect ('}');
368 retval = rdot_build_decl2 (D_STRUCT_INIT,
369 rdot_build_identifier (pid),
370 sls);
372 else if (yyaccept_ (ACC))
374 yyexpect (ACC);
375 rdot node = factor1 ();
376 retval = rdot_build_decl2 (D_ACC_EXPR, rdot_build_identifier (pid), node);
378 else
380 retval = rdot_build_identifier (yylval.string);
381 if (yyaccept ('.'))
383 rdot rhs = factor2 ();
384 retval = rdot_build_decl2 (D_ATTRIB_REF, retval, rhs);
387 free (pid);
389 else
390 retval = factor2 ();
391 return retval;
394 rdot factor2 (void)
396 rdot retval = NULL_DOT;
397 if (yyaccept ('('))
399 retval = expression ();
400 yyexpect (')');
402 else
404 retval = primary ();
405 if (RDOT_TYPE (retval) == D_IDENTIFIER
406 || RDOT_TYPE (retval) == D_CALL_EXPR)
408 if (yyaccept ('.'))
410 rdot rhs = factor2 ();
411 retval = rdot_build_decl2 (D_ATTRIB_REF, retval, rhs);
415 return retval;
418 opcode_t symToDeclType (int sym)
420 opcode_t retval = D_D_EXPR;
421 switch (sym)
423 case '=':
424 retval = D_MODIFY_EXPR;
425 break;
427 case '+':
428 retval = D_ADD_EXPR;
429 break;
431 case '-':
432 retval = D_MINUS_EXPR;
433 break;
435 case '*':
436 retval = D_MULT_EXPR;
437 break;
439 case '/':
440 retval = D_DIVD_EXPR;
441 break;
443 case '.':
444 retval = D_ATTRIB_REF;
445 break;
447 case EQUAL_EQUAL:
448 retval = D_EQ_EQ_EXPR;
449 break;
451 case NOT_EQUAL:
452 retval = D_NOT_EQ_EXPR;
453 break;
455 case '<':
456 retval = D_LESS_EXPR;
457 break;
459 case LESS_EQUAL:
460 retval = D_LESS_EQ_EXPR;
461 break;
463 case '>':
464 retval = D_GREATER_EXPR;
465 break;
467 case GREATER_EQUAL:
468 retval = D_GREATER_EQ_EXPR;
469 break;
471 default:
472 yyerror ("invalid symbol [%i:%s]",
473 sym, yytoken_string (sym));
474 break;
476 return retval;
479 rdot expression (void)
481 bool head = false;
482 rdot retval = factor1 ();
483 rdot next = NULL_DOT;
484 while (sym == '+' || sym == '-' ||
485 sym == '*' || sym == '/' ||
486 sym == '<' || sym == '>' ||
487 sym == EQUAL_EQUAL || sym == NOT_EQUAL ||
488 sym == LESS_EQUAL || sym == GREATER_EQUAL)
490 opcode_t o = symToDeclType (sym);
491 yyexpect (sym);
492 rdot rhs = factor2 ();
493 if (head == false)
495 retval = next = rdot_build_decl2 (o, retval, rhs);
496 head = true;
498 else
500 rdot prev = RDOT_rhs_TT (next);
501 rdot rhs_expr = rdot_build_decl2 (o, prev, rhs);
502 RDOT_rhs_TT (next) = rhs_expr;
503 next = rhs_expr;
506 return retval;
509 rdot statement ()
511 rdot retval = NULL_DOT;
512 if (yyaccept_ (BREAK))
514 yyexpect (BREAK);
515 retval = rdot_build_decl1 (C_BREAK_STMT, NULL_DOT);
517 else if (yyaccept_ (CONTINUE))
519 yyexpect (CONTINUE);
520 retval = rdot_build_decl1 (C_CONT_STMT, NULL_DOT);
522 else if (yyaccept_ (RETURN))
524 yyexpect (RETURN);
525 retval = rdot_build_decl1 (C_RETURN_STMT, expression ());
527 else if (yyaccept_ (LET))
529 // simple vardecl [let x;]
530 rdot tg = target ();
531 if (yyaccept ('='))
533 retval = rdot_build_decl2 (D_MODIFY_EXPR,
534 tg, expression ());
536 else
537 retval = tg;
539 else
540 retval = expression ();
541 return retval;
544 rdot struct_while_loop ()
546 yyexpect (WHILE);
547 rdot expr = expression ();
548 yyexpect ('{');
549 rdot sb = suite ();
550 yyexpect ('}');
551 return rdot_build_decl2 (D_STRUCT_WHILE, expr, sb);
554 rdot struct_loop ()
556 yyexpect (LOOP);
557 yyexpect ('{');
558 rdot sb = suite ();
559 yyexpect ('}');
560 return rdot_build_decl1 (D_STRUCT_LOOP, sb);
563 rdot if_block (void)
565 yyexpect (IF);
566 rdot expr = expression ();
567 yyexpect ('{');
568 rdot sb = suite ();
569 yyexpect ('}');
570 return rdot_build_decl2 (D_STRUCT_IF, expr, sb);
573 rdot elif_block (void)
575 yyexpect (ELIF);
576 rdot expr = expression ();
577 yyexpect ('{');
578 rdot sb = suite ();
579 yyexpect ('}');
580 return rdot_build_decl2 (D_STRUCT_IF, expr, sb);
583 rdot else_block (void)
585 yyexpect (ELSE);
586 yyexpect ('{');
587 rdot block = suite ();
588 yyexpect ('}');
589 return rdot_build_decl1 (D_STRUCT_ELSE, block);
592 rdot struct_conditional ()
594 rdot iblock = if_block ();
595 rdot eblock = NULL_DOT;
596 rdot elblock = NULL_DOT;
597 rdot curr = NULL_DOT;
598 rdot prev = NULL_DOT;
599 while (yyaccept_ (ELIF))
601 curr = elif_block ();
602 if (elblock == NULL_DOT)
603 elblock = prev = curr;
604 else
606 RDOT_CHAIN (prev) = curr;
607 prev = curr;
610 if (yyaccept_ (ELSE))
611 eblock = else_block ();
612 rdot retval = rdot_build_decl2 (D_STRUCT_IF, iblock, eblock);
613 RDOT_FIELD (retval)= elblock;
614 return retval;
617 void statement_list (rdot head)
619 if (yyaccept_ ('}'))
620 return;
622 rdot st = NULL_DOT;
623 if (yyaccept_ (LOOP))
624 st = struct_loop ();
625 else if (yyaccept_ (WHILE))
626 st = struct_while_loop ();
627 else if (yyaccept_ (IF))
628 st = struct_conditional ();
629 else
631 st = statement ();
632 if (!yyaccept (';'))
633 DOT_RETVAL (st) = true;
635 gcc_assert (st != NULL_DOT);
636 if (head == NULL_DOT)
637 vec_safe_push (symStack, st);
638 else
639 RDOT_CHAIN (head) = st;
640 statement_list (st);
643 rdot suite ()
645 rdot retval = NULL_DOT;
646 size_t prev = symStack->length ();
647 statement_list (NULL);
648 size_t next = symStack->length ();
650 if (next > prev)
651 retval = symStack->pop ();
652 return retval;
655 rdot param (void)
657 yyexpect (IDENTIFIER);
658 char * pid = yylval.string;
659 yyexpect (':');
660 rdot pit = type ();
661 rdot retval = rdot_build_decl2 (D_PARAMETER,
662 rdot_build_identifier (pid),
663 pit);
664 free (pid);
665 return retval;
668 void param_list_ (rdot head)
670 if (yyaccept_ (')'))
671 return;
673 rdot p = param ();
674 if (head == NULL_DOT)
675 vec_safe_push (symStack, p);
676 else
677 RDOT_CHAIN (head) = p;
679 if (yyaccept (','))
680 param_list_ (p);
683 rdot param_list ()
685 rdot retval = NULL_DOT;
686 size_t prev = symStack->length ();
687 param_list_ (NULL_DOT);
688 size_t next = symStack->length ();
690 if (next > prev)
691 retval = symStack->pop ();
692 return retval;
695 /* fndecl := [pub] fn IDENTIFIER ([param_list]) [-> type] { stmt_list } */
696 rdot fndecl ()
698 bool pub = false;
699 if (yyaccept (PUB))
700 pub = true;
701 yyexpect (DEFUN);
702 yyexpect (IDENTIFIER);
703 char * fid = yylval.string;
704 yyexpect ('(');
705 rdot plist = param_list ();
706 yyexpect (')');
707 rdot rtype = NULL_DOT;
708 if (yyaccept (RTYPE))
709 rtype = type ();
710 yyexpect ('{');
711 rdot block = suite ();
712 yyexpect ('}');
713 rdot retval = rdot_build_fndecl (rdot_build_identifier (fid),
714 pub, plist, rtype, block);
715 free (fid);
716 return retval;
719 void struct_layout_ (rdot head)
721 if (yyaccept_ ('}'))
722 return;
724 rdot p = param ();
725 if (head == NULL_DOT)
726 vec_safe_push (symStack, p);
727 else
728 RDOT_CHAIN (head) = p;
730 if (yyaccept (','))
731 struct_layout_ (p);
734 rdot struct_layout ()
736 rdot retval = NULL_DOT;
737 size_t prev = symStack->length ();
738 struct_layout_ (NULL_DOT);
739 size_t next = symStack->length ();
741 if (next > prev)
742 retval = symStack->pop ();
743 return retval;
746 rdot struct_decl ()
748 yyexpect (STRUCT);
749 yyexpect (IDENTIFIER);
750 char * sid = yylval.string;
752 yyexpect ('{');
753 rdot layout = struct_layout ();
754 yyexpect ('}');
755 rdot retval = rdot_build_decl2 (D_STRUCT_TYPE,
756 rdot_build_identifier (sid),
757 layout);
758 free (sid);
759 return retval;
762 void fndecl_block_ (rdot head)
764 if (yyaccept_ ('}'))
765 return;
767 rdot f = fndecl ();
768 if (head == NULL_DOT)
769 vec_safe_push (symStack, f);
770 else
771 RDOT_CHAIN (head) = f;
773 fndecl_block_ (f);
776 rdot fndecl_block (void)
778 rdot retval = NULL_DOT;
779 size_t prev = symStack->length ();
780 fndecl_block_ (NULL_DOT);
781 size_t next = symStack->length ();
783 if (next > prev)
784 retval = symStack->pop ();
785 return retval;
788 rdot impl_block ()
790 rdot retval = NULL_DOT;
791 yyexpect (IMPL);
792 yyexpect (IDENTIFIER);
793 char * iid = yylval.string;
794 rdot rid = rdot_build_identifier (iid);
795 free (iid);
796 if (yyaccept (FOR))
797 yyexpect (IDENTIFIER);
798 yyexpect ('{');
799 rdot fb = fndecl_block ();
800 yyexpect ('}');
801 retval = rdot_build_decl2 (D_STRUCT_IMPL, rid, fb);
802 return retval;
806 decl := fndecl | structdecl | impldecl | enumdecl
808 void decl (void)
810 rdot rdecl = NULL_DOT;
811 if (yyaccept_ (STRUCT))
812 rdecl = struct_decl ();
813 else if (yyaccept_ (IMPL))
814 rdecl = impl_block ();
815 else
816 rdecl = fndecl ();
817 if (rdecl != NULL_DOT)
818 dot_pass_pushDecl (rdecl);
821 int yyparse (void)
823 // kick things off with the first token
824 __yyerror = 0;
825 sym = yylex_ ();
827 vec_alloc (symStack, 0);
828 vec_safe_push (symStack, NULL_DOT);
830 while (sym != 0)
831 decl ();
833 if (symStack->length() > 1)
834 yyerror ("some unpoped symbols on the parse stack!");
836 vec_free (symStack);
837 return __yyerror;