Variable declarations working in all forms.
[Jack-Compiler.git] / parse.c
blob61c808750f8a96802e9d4d5da5d0aa52ac370ef3
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 while(strcmp(pT, "static") == 0 || strcmp(pT, "field") == 0)
70 parse_class_var_dec();
71 if(has_more_tokens(pC) == true)
73 pC = advance(pC, pT);
74 tk = token_type(pT);
75 } else {
76 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
80 parse_subroutine();
82 if(settings.tokens) { printf("</class>\n"); }
85 void parse_class_var_dec()
87 if(settings.tokens) { printf("<classVarDec>\n"); }
89 /* look for 'static' or 'field' */
90 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
91 if(has_more_tokens(pC) == true)
93 pC = advance(pC, pT);
94 tk = token_type(pT);
95 } else {
96 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
99 /* look for type */
100 if(tk == IDENTIFIER) {
101 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
102 } else if (tk == KEYWORD) {
103 if(strcmp(pT, "int") == 0 || strcmp(pT, "char") == 0 || strcmp(pT, "boolean") == 0) {
104 if(settings.tokens) { printf("\t<keyword>%s</keyword>\n", pT); }
105 } else {
106 compiler_error(41, "Token Must be Data Type.", pS, pC, pT);
108 } else {
109 compiler_error(41, "Token Must be Data Type", pS, pC, pT);
112 /* look or variable name */
113 if(has_more_tokens(pC) == true)
115 pC = advance(pC, pT);
116 tk = token_type(pT);
117 } else {
118 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
120 if(tk == IDENTIFIER) {
121 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
122 } else {
123 compiler_error(42, "Token Must be Variable Name", pS, pC, pT);
126 /* look for ',' */
127 if(has_more_tokens(pC) == true)
129 pC = advance(pC, pT);
130 tk = token_type(pT);
131 } else {
132 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
135 if(*pT == ',') {
136 do {
137 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
138 if(has_more_tokens(pC) == true)
140 pC = advance(pC, pT);
141 tk = token_type(pT);
142 } else {
143 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
145 if(tk == IDENTIFIER) {
146 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
147 } else {
148 compiler_error(42, "Token Must be Variable Name", pS, pC, pT);
150 if(has_more_tokens(pC) == true)
152 pC = advance(pC, pT);
153 tk = token_type(pT);
154 } else {
155 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
157 } while (*pT == ',');
160 if(*pT == ';') {
161 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
162 } else {
163 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
166 if(settings.tokens) { printf("</classVarDec>\n"); }
169 void parse_subroutine()
171 if(settings.tokens) { printf("<subroutineDec>\n"); }
173 if(tk == KEYWORD) {
174 if(strcmp(pT, "constructor") == 0 || strcmp(pT, "function") == 0 || strcmp(pT, "method") == 0)
176 if(settings.tokens) { printf("\t<keyword>%s</keyword>\n", pT); }
177 } else {
178 compiler_error(8, "Incorrect Token Found: Must be 'constructor', 'function', or 'method'", pS, pC, pT);
182 /* look for return type of function */
183 if(has_more_tokens(pC) == true)
185 pC = advance(pC, pT);
186 tk = token_type(pT);
187 if(tk == KEYWORD || tk == IDENTIFIER)
189 if(strcmp(pT, "void") == 0)
191 if(settings.tokens) { printf("\t<keyword>%s</keyword>\n", pT); }
192 } else {
193 if(settings.tokens) { printf("\t<type>%s</type>\n", pT); }
195 } else {
196 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
198 } else {
199 compiler_error(29, "Incorrect Token Type", pS, pC, pT);
202 /* look for subroutine name */
203 if(has_more_tokens(pC) == true)
205 pC = advance(pC, pT);
206 tk = token_type(pT);
207 if(tk == IDENTIFIER)
209 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
210 } else {
211 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
213 } else {
214 compiler_error(10, "Incorrect Token Type. Looking for Keyword or Identifier.", pS, pC, pT);
217 /* look for symbol '(' that specifies beginning of parameter list */
218 if(has_more_tokens(pC) == true)
220 pC = advance(pC, pT);
221 tk = token_type(pT);
222 if(*pT == '(')
224 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
225 parse_params();
226 } else {
227 compiler_error(12, "Parameter List for Function Missing", pS, pC, pT);
229 } else {
230 compiler_error(11, "Name of Function Must be an Identifier", pS, pC, pT);
233 /* look for end of parameter list */
234 if(*pT == ')')
236 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
237 } else {
238 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
241 /* look for opening brace for block */
242 if(has_more_tokens(pC) == true)
244 pC = advance(pC, pT);
245 tk = token_type(pT);
246 if(*pT == '{')
248 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
249 if(has_more_tokens(pC) == true)
251 pC = advance(pC, pT);
252 tk = token_type(pT);
253 } else {
254 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
256 parse_var_dec();
258 } else {
259 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
262 while(strcmp(pT, "let") == 0 || strcmp(pT, "if") == 0 || strcmp(pT, "while") == 0 || strcmp(pT, "do") == 0 || strcmp(pT, "return") == 0)
264 parse_statements();
265 if(has_more_tokens(pC) == true)
267 pC = advance(pC, pT);
268 tk = token_type(pT);
269 } else {
270 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
274 if(settings.tokens) { printf("</subroutineDec>\n"); }
277 void parse_params()
279 if(*pT == '(') { if(settings.tokens) { printf("<parameterList>\n"); } }
281 /* look for datatype in parameter list */
282 if(has_more_tokens(pC) == true)
284 pC = advance(pC, pT);
285 tk = token_type(pT);
286 if(tk == KEYWORD) {
287 if(strcmp(pT, "int") == 0 || strcmp(pT, "char") == 0 || strcmp(pT, "boolean") == 0)
289 if(settings.tokens) { printf("\t<keyword>%s</keyword>\n", pT); }
290 } else {
291 compiler_error(14, "Incorrect Token Type in Parameter List. Looking for Datatype name.", pS, pC, pT);
293 } else if(tk == SYMBOL && *pT == ')') { if(settings.tokens) { printf("</parameterList>\n"); } return; }
294 } else {
295 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
298 /* look for identifier for this parameter */
299 if(has_more_tokens(pC) == true)
301 pC = advance(pC, pT);
302 tk = token_type(pT);
303 if(tk == IDENTIFIER) {
304 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
306 } else {
307 compiler_error(15, "Incorrect Token Type in Parameter List. Looking for Variable Identifier.", pS, pC, pT);
309 } else {
310 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
313 /* are there more parameters? */
314 if(has_more_tokens(pC) == true)
316 pC = advance(pC, pT);
317 tk = token_type(pT);
318 if(*pT == ',') {
319 parse_params();
320 } else if (*pT == ')') { /* exit parse_params */
321 if(settings.tokens) { printf("</parameterList>\n"); }
322 return;
323 } else {
324 compiler_error(16, "Incorrect Token Type in Parameter List. Looking for ',' or ')'", pS, pC, pT);
326 } else {
327 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
331 void parse_var_dec()
333 /* look for token named 'var' */
334 if(strcmp(pT, "var") == 0)
336 if(settings.tokens) { printf("<varDec>\n\t<symbol>%s</symbol>\n", pT); }
337 } else { return; }
339 /* look for variable data type */
340 if(has_more_tokens(pC) == true)
342 pC = advance(pC, pT);
343 tk = token_type(pT);
344 if(strcmp(pT, "int") == 0 || strcmp(pT, "char") == 0 || strcmp(pT, "boolean") == 0 || strcmp(pT, "Array") == 0)
346 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
348 } else if (tk == IDENTIFIER) { /* could also be a custom class name */
349 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
350 } else {
351 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
355 /* look for identifier(s) for variable(s) */
356 do {
357 if(has_more_tokens(pC) == true)
359 pC = advance(pC, pT);
360 tk = token_type(pT);
361 } else {
362 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
364 if(tk == IDENTIFIER)
366 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
369 if(has_more_tokens(pC) == true)
371 pC = advance(pC, pT);
372 tk = token_type(pT);
373 } else {
374 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
376 if(tk == SYMBOL)
378 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
380 } while (*pT == ',');
382 if(has_more_tokens(pC) == true)
384 pC = advance(pC, pT);
385 tk = token_type(pT);
386 } else {
387 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
389 parse_var_dec();
392 void parse_statements()
394 if(strcmp(pT, "let") == 0)
396 parse_let();
397 } else if(strcmp(pT, "if") == 0)
399 parse_if();
400 } else if(strcmp(pT, "while") == 0)
402 parse_while();
403 } else if(strcmp(pT, "do") == 0)
405 parse_do();
406 } else if(strcmp(pT, "return") == 0)
408 parse_return();
412 void parse_do()
414 if(settings.tokens) { printf("<doStatement>\n\t<keyword>do</keyword>\n"); }
415 if(has_more_tokens(pC) == true)
417 pC = advance(pC, pT);
418 tk = token_type(pT);
419 } else {
420 compiler_error(20, "Could Not Complete Do Statement. Incomplete Program", pS, pC, pT);
423 /* must be an identifier */
424 if(tk == IDENTIFIER) {
425 parse_subroutine_call();
426 } else {
427 compiler_error(30, "Subroutine Name Must Be Listed Here", pS, pC, pT);
430 if(settings.tokens) { printf("</doStatement>\n"); }
433 void parse_let()
435 if(settings.tokens) { printf("<letStatement>\n\t<keyword>let</keyword>\n"); }
436 if(has_more_tokens(pC) == true)
438 pC = advance(pC, pT);
439 tk = token_type(pT);
440 } else {
441 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
444 /* look for an identifier - must be a variable name */
445 if(tk == IDENTIFIER)
447 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
448 } else {
449 compiler_error(31, "Could Not Find Identifier At This Location", pS, pC, pT);
452 /* optional '[' for an array offset value */
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 if(*pT == '[')
463 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
464 parse_expression();
467 if(*pT == ']')
469 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
472 /* look for '=' */
473 if(*pT == '=')
475 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
476 } else {
477 compiler_error(32, "Could Not Find '=' Symbol At This Location", pS, pC, pT);
480 /* parse_expression(); */
482 /* look for identifier */
483 if(has_more_tokens(pC) == true)
485 pC = advance(pC, pT);
486 tk = token_type(pT);
487 } else {
488 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
491 if(tk == IDENTIFIER)
493 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
494 } else {
495 compiler_error(20, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
498 /* look for ';' */
499 if(has_more_tokens(pC) == true)
501 pC = advance(pC, pT);
502 tk = token_type(pT);
503 } else {
504 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
507 if(*pT == ';')
509 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
510 } else {
511 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
514 if(settings.tokens) { printf("</letStatement>\n"); }
517 void parse_while()
520 exit_error(0, "Parsing While");
523 void parse_return()
525 if(settings.tokens) { printf("<returnStatement>\n\t<identifier>%s</identifier>\n", pT); }
527 /* look for ';' */
528 if(has_more_tokens(pC) == true)
530 pC = advance(pC, pT);
531 tk = token_type(pT);
532 } else {
533 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
536 if (*pT != ';') { parse_expression(); }
538 if(*pT == ';')
540 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
541 } else {
542 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
544 if(settings.tokens) { printf("</returnStatement>\n"); }
547 void parse_if()
549 exit_error(0, "Parsing If");
552 void parse_expression()
554 do {
555 if(settings.tokens) { printf("<expression>%s</expression>\n", pT); }
556 if(has_more_tokens(pC) == true)
558 pC = advance(pC, pT);
559 tk = token_type(pT);
560 } else {
561 compiler_error(34, "Could Not Parse Expression. Incomplete Program", pS, pC, pT);
563 } while (*pT != ']' && *pT != ';');
566 void parse_term()
568 if(has_more_tokens(pC) == true)
570 pC = advance(pC, pT);
571 tk = token_type(pT);
572 } else {
573 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
576 switch(*pT)
578 case '[':
579 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
580 parse_term();
581 if(has_more_tokens(pC) == true)
583 pC = advance(pC, pT);
584 tk = token_type(pT);
585 if(*pT == ']')
587 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
588 } else {
589 compiler_error(26, "Improperly Terminated Array Expression. Symbol ']' Required at this Location.", pS, pC, pT);
591 } else {
592 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
594 break;
595 case '(':
596 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
597 parse_expr_lst();
598 break;
599 case '.':
600 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
601 break;
602 default:
603 return;
606 if(strchr(UNARY_OP, *pT) != NULL)
608 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
609 if(has_more_tokens(pC) == true)
611 pC = advance(pC, pT);
612 tk = token_type(pT);
613 parse_term();
614 } else {
615 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
620 void parse_subroutine_call()
622 if(settings.tokens) { printf("<subroutineCall>\n"); }
623 if(tk == IDENTIFIER)
625 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
626 } else {
627 compiler_error(35, "Could Not Find Class Name or Subroutine Name at This Location", pS, pC, pT);
630 if(has_more_tokens(pC) == true)
632 pC = advance(pC, pT);
633 tk = token_type(pT);
634 } else {
635 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
638 if (*pT == '.') {
639 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
640 if(has_more_tokens(pC) == true)
642 pC = advance(pC, pT);
643 tk = token_type(pT);
644 } else {
645 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
647 if(tk == IDENTIFIER)
649 if(settings.tokens) { printf("\t<identifier>%s</identifier>\n", pT); }
650 } else {
651 compiler_error(37, "Could Not Find Method Name or Subroutine Name at This Location", pS, pC, pT);
655 if(*pT != '(') /* this for calls with no class name at beginning */
657 if(has_more_tokens(pC) == true)
659 pC = advance(pC, pT);
660 tk = token_type(pT);
661 } else {
662 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
666 if(*pT == '(')
668 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
669 if(has_more_tokens(pC) == true)
671 pC = advance(pC, pT);
672 tk = token_type(pT);
673 } else {
674 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
676 parse_expr_lst();
678 if(*pT == ')')
680 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
681 if(has_more_tokens(pC) == true)
683 pC = advance(pC, pT);
684 tk = token_type(pT);
685 } else {
686 compiler_error(38, "Could Not Find Symbol ')' At This Location", pS, pC, pT);
689 } else {
690 compiler_error(39, "Could Not Find Symbol '(' At This Location", pS, pC, pT);
693 if(*pT == ';')
695 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
698 if(settings.tokens) { printf("<subroutineCall>\n"); }
701 void parse_expr_lst()
703 while(*pT != ')')
705 if(*pT == ',')
707 if(settings.tokens) { printf("\t<symbol>%s</symbol>\n", pT); }
708 if(has_more_tokens(pC) == true)
710 pC = advance(pC, pT);
711 tk = token_type(pT);
712 } else {
713 compiler_error(24, "Could Not Complete Expression List. Incomplete Program", pS, pC, pT);
715 } else {
716 parse_term();