Class variable declarations parsing correctly.
[Jack-Compiler.git] / parse.c
blobd54ff79787aa1f288f4119f6d852ed9452e46de3
1 #include <ctype.h>
2 #include <stdbool.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
7 #include "error.h"
8 #include "jack.h"
9 #include "parse.h"
10 #include "token.h"
12 void parse_class()
14 if(settings.tokens) { printf("<class>\n"); }
16 if(has_more_tokens(pC) == true)
18 pC = advance(pC, pT);
19 tk = token_type(pT);
20 } else {
21 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
24 if(strcmp(pT, "class") == 0 ) {
25 if(settings.tokens) { printf("\t<keyword>%s</keyword>\n", pT); }
26 } else {
27 compiler_error(40, "Incorrect Token Found: Must be 'class'", pS, pC, pT);
30 /* look for class name */
31 if(has_more_tokens(pC) == true)
33 pC = advance(pC, pT);
34 tk = token_type(pT);
35 } else {
36 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
39 if (tk == IDENTIFIER){
40 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
41 } else {
42 compiler_error(44, "Could Not Find Class Name or Subroutine Name at This Location", pS, pC, pT);
45 /* look for '{' symbol */
46 if(has_more_tokens(pC) == true)
48 pC = advance(pC, pT);
49 tk = token_type(pT);
50 } else {
51 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
54 if (tk == SYMBOL){
55 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
56 } else {
57 compiler_error(44, "Could Not Find Class Name or Subroutine Name at This Location", pS, pC, pT);
60 if(has_more_tokens(pC) == true)
62 pC = advance(pC, pT);
63 tk = token_type(pT);
64 } else {
65 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
68 do {
69 parse_class_var_dec();
70 if(has_more_tokens(pC) == true)
72 pC = advance(pC, pT);
73 tk = token_type(pT);
74 } else {
75 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
77 } while (strcmp(pT, "static") == 0 || strcmp(pT, "field") == 0);
79 parse_subroutine();
81 if(settings.tokens) { printf("</class>\n"); }
84 void parse_class_var_dec()
86 if(settings.tokens) { printf("<classVarDec>\n"); }
88 /* look for 'static' or 'field' */
89 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
90 if(has_more_tokens(pC) == true)
92 pC = advance(pC, pT);
93 tk = token_type(pT);
94 } else {
95 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
98 /* look for type */
99 if(tk == IDENTIFIER) {
100 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
101 } else if (tk == KEYWORD) {
102 if(strcmp(pT, "int") == 0 || strcmp(pT, "char") == 0 || strcmp(pT, "boolean") == 0) {
103 if(settings.tokens) { printf("\t<keyword>%s</keyword>\n", pT); }
104 } else {
105 compiler_error(41, "Token Must be Data Type.", pS, pC, pT);
107 } else {
108 compiler_error(41, "Token Must be Data Type", pS, pC, pT);
111 /* look or variable name */
112 if(has_more_tokens(pC) == true)
114 pC = advance(pC, pT);
115 tk = token_type(pT);
116 } else {
117 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
119 if(tk == IDENTIFIER) {
120 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
121 } else {
122 compiler_error(42, "Token Must be Variable Name", pS, pC, pT);
125 /* look for ',' */
126 if(has_more_tokens(pC) == true)
128 pC = advance(pC, pT);
129 tk = token_type(pT);
130 } else {
131 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
134 if(*pT == ',') {
135 do {
136 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
137 if(has_more_tokens(pC) == true)
139 pC = advance(pC, pT);
140 tk = token_type(pT);
141 } else {
142 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
144 if(tk == IDENTIFIER) {
145 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
146 } else {
147 compiler_error(42, "Token Must be Variable Name", pS, pC, pT);
149 if(has_more_tokens(pC) == true)
151 pC = advance(pC, pT);
152 tk = token_type(pT);
153 } else {
154 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
156 } while (*pT == ',');
159 if(*pT == ';') {
160 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
161 } else {
162 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
165 if(settings.tokens) { printf("</classVarDec>\n"); }
168 void parse_subroutine()
170 if(settings.tokens) { printf("<subroutineDec>\n"); }
171 if(has_more_tokens(pC) == true)
173 pC = advance(pC, pT);
174 tk = token_type(pT);
175 if(tk == KEYWORD) {
176 if(strcmp(pT, "constructor") == 0 || strcmp(pT, "function") == 0 || strcmp(pT, "method") == 0)
178 if(settings.tokens) { printf("\t<keyword>%s</keyword>\n", pT); }
179 } else {
180 compiler_error(8, "Incorrect Token Found: Must be 'constructor', 'function', or 'method'", pS, pC, pT);
185 /* look for return type of function */
186 if(has_more_tokens(pC) == true)
188 pC = advance(pC, pT);
189 tk = token_type(pT);
190 if(tk == KEYWORD || tk == IDENTIFIER)
192 if(strcmp(pT, "void") == 0)
194 if(settings.tokens) { printf("\t<keyword>%s</keyword>\n", pT); }
195 } else {
196 if(settings.tokens) { printf("\t<type>%s</type>\n", pT); }
198 } else {
199 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
201 } else {
202 compiler_error(29, "Incorrect Token Type", pS, pC, pT);
205 /* look for subroutine name */
206 if(has_more_tokens(pC) == true)
208 pC = advance(pC, pT);
209 tk = token_type(pT);
210 if(tk == IDENTIFIER)
212 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
213 } else {
214 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
216 } else {
217 compiler_error(10, "Incorrect Token Type. Looking for Keyword or Identifier.", pS, pC, pT);
220 /* look for symbol '(' that specifies beginning of parameter list */
221 if(has_more_tokens(pC) == true)
223 pC = advance(pC, pT);
224 tk = token_type(pT);
225 if(*pT == '(')
227 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
228 parse_params();
229 } else {
230 compiler_error(12, "Parameter List for Function Missing", pS, pC, pT);
232 } else {
233 compiler_error(11, "Name of Function Must be an Identifier", pS, pC, pT);
236 /* look for end of parameter list */
237 if(*pT == ')')
239 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
240 } else {
241 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
244 /* look for opening brace for block */
245 if(has_more_tokens(pC) == true)
247 pC = advance(pC, pT);
248 tk = token_type(pT);
249 if(*pT == '{')
251 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
252 parse_var_dec();
254 } else {
255 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
258 while(strcmp(pT, "let") == 0 || strcmp(pT, "if") == 0 || strcmp(pT, "while") == 0 || strcmp(pT, "do") == 0 || strcmp(pT, "return") == 0)
260 parse_statements();
261 if(has_more_tokens(pC) == true)
263 pC = advance(pC, pT);
264 tk = token_type(pT);
265 } else {
266 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
270 if(settings.tokens) { printf("</subroutineDec>\n"); }
273 void parse_params()
275 if(*pT == '(') { if(settings.tokens) { printf("<parameterList>\n"); } }
277 /* look for datatype in parameter list */
278 if(has_more_tokens(pC) == true)
280 pC = advance(pC, pT);
281 tk = token_type(pT);
282 if(tk == KEYWORD) {
283 if(strcmp(pT, "int") == 0 || strcmp(pT, "char") == 0 || strcmp(pT, "boolean") == 0)
285 if(settings.tokens) { printf("\t<keyword>%s</keyword>\n", pT); }
286 } else {
287 compiler_error(14, "Incorrect Token Type in Parameter List. Looking for Datatype name.", pS, pC, pT);
289 } else if(tk == SYMBOL && *pT == ')') { if(settings.tokens) { printf("</parameterList>\n"); } return; }
290 } else {
291 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
294 /* look for identifier for this parameter */
295 if(has_more_tokens(pC) == true)
297 pC = advance(pC, pT);
298 tk = token_type(pT);
299 if(tk == IDENTIFIER) {
300 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
302 } else {
303 compiler_error(15, "Incorrect Token Type in Parameter List. Looking for Variable Identifier.", pS, pC, pT);
305 } else {
306 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
309 /* are there more parameters? */
310 if(has_more_tokens(pC) == true)
312 pC = advance(pC, pT);
313 tk = token_type(pT);
314 if(*pT == ',') {
315 parse_params();
316 } else if (*pT == ')') { /* exit parse_params */
317 if(settings.tokens) { printf("</parameterList>\n"); }
318 return;
319 } else {
320 compiler_error(16, "Incorrect Token Type in Parameter List. Looking for ',' or ')'", pS, pC, pT);
322 } else {
323 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
327 void parse_var_dec()
329 int i = 0;
330 /* look for token named 'var' */
331 if(has_more_tokens(pC) == true)
333 pC = advance(pC, pT);
334 tk = token_type(pT);
335 if(strcmp(pT, "var") == 0)
337 if(settings.tokens) { printf("<varDec>\n"); }
339 } else { return; }
340 } else {
341 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
344 /* look for variable data type */
345 if(has_more_tokens(pC) == true)
347 pC = advance(pC, pT);
348 tk = token_type(pT);
349 if(strcmp(pT, "int") == 0 || strcmp(pT, "char") == 0 || strcmp(pT, "boolean") == 0 || strcmp(pT, "Array") == 0)
351 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
352 /* look for identifier(s) for variable(s) */
353 do {
354 i = 0;
355 if(has_more_tokens(pC) == true)
357 pC = advance(pC, pT);
358 tk = token_type(pT);
359 if(tk == IDENTIFIER)
361 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
364 } else {
365 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
367 } while (i > 0);
371 /* could also be a custom class name */
372 if(tk == IDENTIFIER)
374 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
375 if(has_more_tokens(pC) == true)
377 pC = advance(pC, pT);
378 tk = token_type(pT);
379 } else {
380 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
382 if(tk == IDENTIFIER)
384 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
388 if(has_more_tokens(pC) == true)
390 pC = advance(pC, pT);
391 tk = token_type(pT);
392 if((tk == SYMBOL) && (*pT == ';' || *pT == ',')) {
393 if(*pT == ',') { i++; }
394 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
395 if(i == 0)
397 parse_var_dec();
399 } else {
400 compiler_error(18, "Improperly Terminated Variable Declaration", pS, pC, pT);
402 } else {
403 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
406 if(settings.tokens) { printf("<varDec>\n"); }
409 void parse_statements()
411 if(strcmp(pT, "let") == 0)
413 parse_let();
414 } else if(strcmp(pT, "if") == 0)
416 parse_if();
417 } else if(strcmp(pT, "while") == 0)
419 parse_while();
420 } else if(strcmp(pT, "do") == 0)
422 parse_do();
423 } else if(strcmp(pT, "return") == 0)
425 parse_return();
429 void parse_do()
431 if(settings.tokens) { printf("<doStatement>\n\t<keyword>do</keyword>\n"); }
432 if(has_more_tokens(pC) == true)
434 pC = advance(pC, pT);
435 tk = token_type(pT);
436 } else {
437 compiler_error(20, "Could Not Complete Do Statement. Incomplete Program", pS, pC, pT);
440 /* must be an identifier */
441 if(tk == IDENTIFIER) {
442 parse_subroutine_call();
443 } else {
444 compiler_error(30, "Subroutine Name Must Be Listed Here", pS, pC, pT);
447 if(settings.tokens) { printf("</doStatement>\n"); }
450 void parse_let()
452 if(settings.tokens) { printf("<letStatement>\n\t<keyword>let</keyword>\n"); }
453 if(has_more_tokens(pC) == true)
455 pC = advance(pC, pT);
456 tk = token_type(pT);
457 } else {
458 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
461 /* look for an identifier - must be a variable name */
462 if(tk == IDENTIFIER)
464 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
465 } else {
466 compiler_error(31, "Could Not Find Identifier At This Location", pS, pC, pT);
469 /* optional '[' for an array offset value */
470 if(has_more_tokens(pC) == true)
472 pC = advance(pC, pT);
473 tk = token_type(pT);
474 } else {
475 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
478 if(*pT == '[')
480 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
481 parse_expression();
484 if(*pT == ']')
486 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
489 /* look for '=' */
490 if(*pT == '=')
492 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
493 } else {
494 compiler_error(32, "Could Not Find '=' Symbol At This Location", pS, pC, pT);
497 /* parse_expression(); */
499 /* look for identifier */
500 if(has_more_tokens(pC) == true)
502 pC = advance(pC, pT);
503 tk = token_type(pT);
504 } else {
505 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
508 if(tk == IDENTIFIER)
510 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
511 } else {
512 compiler_error(20, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
515 /* look for ';' */
516 if(has_more_tokens(pC) == true)
518 pC = advance(pC, pT);
519 tk = token_type(pT);
520 } else {
521 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
524 if(*pT == ';')
526 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
527 } else {
528 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
531 if(settings.tokens) { printf("</letStatement>\n"); }
534 void parse_while()
537 exit_error(0, "Parsing While");
540 void parse_return()
542 if(settings.tokens) { printf("<returnStatement>\n\t<identifier>%s</identifier>\n", pT); }
544 /* look for ';' */
545 if(has_more_tokens(pC) == true)
547 pC = advance(pC, pT);
548 tk = token_type(pT);
549 } else {
550 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
553 if(*pT == ';')
555 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
556 } else {
557 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
559 if(settings.tokens) { printf("</returnStatement>\n"); }
562 void parse_if()
564 exit_error(0, "Parsing If");
567 void parse_expression()
569 do {
570 printf("<expression>%s</expression>\n", pT);
571 if(has_more_tokens(pC) == true)
573 pC = advance(pC, pT);
574 tk = token_type(pT);
575 } else {
576 compiler_error(34, "Could Not Parse Expression. Incomplete Program", pS, pC, pT);
578 } while (*pT != ']' && *pT != ';');
581 void parse_term()
583 if(has_more_tokens(pC) == true)
585 pC = advance(pC, pT);
586 tk = token_type(pT);
587 } else {
588 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
591 switch(*pT)
593 case '[':
594 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
595 parse_term();
596 if(has_more_tokens(pC) == true)
598 pC = advance(pC, pT);
599 tk = token_type(pT);
600 if(*pT == ']')
602 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
603 } else {
604 compiler_error(26, "Improperly Terminated Array Expression. Symbol ']' Required at this Location.", pS, pC, pT);
606 } else {
607 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
609 break;
610 case '(':
611 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
612 parse_expr_lst();
613 break;
614 case '.':
615 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
616 break;
617 default:
618 return;
621 if(strchr(UNARY_OP, *pT) != NULL)
623 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
624 if(has_more_tokens(pC) == true)
626 pC = advance(pC, pT);
627 tk = token_type(pT);
628 parse_term();
629 } else {
630 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
635 void parse_subroutine_call()
637 if(settings.tokens) { printf("<subroutineCall>\n"); }
638 if(tk == IDENTIFIER)
640 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
641 } else {
642 compiler_error(35, "Could Not Find Class Name or Subroutine Name at This Location", pS, pC, pT);
645 if(has_more_tokens(pC) == true)
647 pC = advance(pC, pT);
648 tk = token_type(pT);
649 } else {
650 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
653 if (*pT == '.') {
654 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
655 if(has_more_tokens(pC) == true)
657 pC = advance(pC, pT);
658 tk = token_type(pT);
659 } else {
660 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
662 if(tk == IDENTIFIER)
664 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
665 } else {
666 compiler_error(37, "Could Not Find Method Name or Subroutine Name at This Location", pS, pC, pT);
670 if(*pT != '(') /* this for calls with no class name at beginning */
672 if(has_more_tokens(pC) == true)
674 pC = advance(pC, pT);
675 tk = token_type(pT);
676 } else {
677 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
681 if(*pT == '(')
683 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
684 if(has_more_tokens(pC) == true)
686 pC = advance(pC, pT);
687 tk = token_type(pT);
688 } else {
689 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
691 parse_expr_lst();
693 if(*pT == ')')
695 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
696 if(has_more_tokens(pC) == true)
698 pC = advance(pC, pT);
699 tk = token_type(pT);
700 } else {
701 compiler_error(38, "Could Not Find Symbol ')' At This Location", pS, pC, pT);
704 } else {
705 compiler_error(39, "Could Not Find Symbol '(' At This Location", pS, pC, pT);
708 if(*pT == ';')
710 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
713 if(settings.tokens) { printf("<subroutineCall>\n"); }
716 void parse_expr_lst()
718 while(*pT != ')')
720 if(*pT == ',')
722 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
723 if(has_more_tokens(pC) == true)
725 pC = advance(pC, pT);
726 tk = token_type(pT);
727 } else {
728 compiler_error(24, "Could Not Complete Expression List. Incomplete Program", pS, pC, pT);
730 } else {
731 parse_term();