More functional Makefile.
[Jack-Compiler.git] / parse.c
blobf0c6e29672b5346a07b65bb81b91a075ba67572a
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)
16 token_print("class", OPEN);
17 space_count++;
20 if(has_more_tokens(pC) == true)
22 pC = advance(pC, pT);
23 tk = token_type(pT);
24 } else {
25 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
28 if(strcmp(pT, "class") == 0 ) {
29 if(settings.tokens) { token_print("keyword", BOTH); }
30 } else {
31 compiler_error(43, "Incorrect Token Found: Must be 'class'", pS, pC, pT);
34 /* look for class name */
35 if(has_more_tokens(pC) == true)
37 pC = advance(pC, pT);
38 tk = token_type(pT);
39 } else {
40 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
43 if (tk == IDENTIFIER){
44 if(settings.tokens) { token_print("identifier", BOTH); }
45 } else {
46 compiler_error(44, "Could Not Find Class Name or Subroutine Name at This Location", pS, pC, pT);
49 /* look for '{' symbol */
50 if(has_more_tokens(pC) == true)
52 pC = advance(pC, pT);
53 tk = token_type(pT);
54 } else {
55 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
58 if (tk == SYMBOL)
60 if(settings.tokens) { token_print("symbol", BOTH); }
61 } else {
62 compiler_error(44, "Could Not Find Class Name or Subroutine Name at This Location", pS, pC, pT);
65 if(has_more_tokens(pC) == true)
67 pC = advance(pC, pT);
68 tk = token_type(pT);
69 } else {
70 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
73 while(strcmp(pT, "static") == 0 || strcmp(pT, "field") == 0)
75 parse_class_var_dec();
76 if(has_more_tokens(pC) == true)
78 pC = advance(pC, pT);
79 tk = token_type(pT);
80 } else {
81 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
85 while(strcmp(pT, "constructor") == 0 || strcmp(pT, "function") == 0 || strcmp(pT, "method") == 0)
87 parse_subroutine();
88 if(has_more_tokens(pC) == true)
90 pC = advance(pC, pT);
91 tk = token_type(pT);
92 } else {
93 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
97 if(*pT == '}')
99 if(settings.tokens) { token_print("symbol", BOTH); }
100 } else {
101 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
104 if(settings.tokens)
106 space_count--;
107 token_print("class", CLOSE);
111 void parse_class_var_dec()
113 if(settings.tokens)
115 token_print("classVarDec", OPEN);
116 space_count++;
119 /* look for 'static' or 'field' */
120 if(settings.tokens) { token_print("keyword", BOTH); }
121 if(has_more_tokens(pC) == true)
123 pC = advance(pC, pT);
124 tk = token_type(pT);
125 } else {
126 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
129 /* look for type */
130 if(tk == IDENTIFIER) {
131 if(settings.tokens) { token_print("identifier", BOTH); }
132 } else if (tk == KEYWORD) {
133 if(strcmp(pT, "int") == 0 || strcmp(pT, "char") == 0 || strcmp(pT, "boolean") == 0) {
134 if(settings.tokens) { token_print("keyword", BOTH); }
135 } else {
136 compiler_error(41, "Token Must be Data Type.", pS, pC, pT);
138 } else {
139 compiler_error(41, "Token Must be Data Type", pS, pC, pT);
142 /* look or variable name */
143 if(has_more_tokens(pC) == true)
145 pC = advance(pC, pT);
146 tk = token_type(pT);
147 } else {
148 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
150 if(tk == IDENTIFIER) {
151 if(settings.tokens) { token_print("identifier", BOTH); }
152 } else {
153 compiler_error(42, "Token Must be Variable Name", pS, pC, pT);
156 /* look for ',' */
157 if(has_more_tokens(pC) == true)
159 pC = advance(pC, pT);
160 tk = token_type(pT);
161 } else {
162 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
165 if(*pT == ',') {
166 do {
167 if(settings.tokens) { token_print("symbol", BOTH); }
168 if(has_more_tokens(pC) == true)
170 pC = advance(pC, pT);
171 tk = token_type(pT);
172 } else {
173 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
175 if(tk == IDENTIFIER) {
176 if(settings.tokens) { token_print("identifier", BOTH); }
177 } else {
178 compiler_error(42, "Token Must be Variable Name", pS, pC, pT);
180 if(has_more_tokens(pC) == true)
182 pC = advance(pC, pT);
183 tk = token_type(pT);
184 } else {
185 compiler_error(40, "Incomplete Class Declaration", pS, pC, pT);
187 } while (*pT == ',');
190 if(*pT == ';') {
191 if(settings.tokens) { token_print("symbol", BOTH); }
192 } else {
193 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
196 if(settings.tokens)
198 space_count--;
199 token_print("classVarDec", CLOSE);
203 void parse_subroutine()
205 if(settings.tokens)
207 token_print("subroutineDec", OPEN);
208 space_count++;
211 if(tk == KEYWORD) {
212 if(strcmp(pT, "constructor") == 0 || strcmp(pT, "function") == 0 || strcmp(pT, "method") == 0)
214 if(settings.tokens) { token_print("keyword", BOTH); }
215 } else {
216 compiler_error(8, "Incorrect Token Found: Must be 'constructor', 'function', or 'method'", pS, pC, pT);
220 /* look for return type of function */
221 if(has_more_tokens(pC) == true)
223 pC = advance(pC, pT);
224 tk = token_type(pT);
225 if(tk == KEYWORD || tk == IDENTIFIER)
227 if(strcmp(pT, "void") == 0)
229 if(settings.tokens) { token_print("keyword", BOTH); }
230 } else {
231 if(settings.tokens) { token_print("identifier", BOTH); }
233 } else {
234 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
236 } else {
237 compiler_error(29, "Incorrect Token Type", pS, pC, pT);
240 /* look for subroutine name */
241 if(has_more_tokens(pC) == true)
243 pC = advance(pC, pT);
244 tk = token_type(pT);
245 if(tk == IDENTIFIER)
247 if(settings.tokens) { token_print("identifier", BOTH); }
248 } else {
249 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
251 } else {
252 compiler_error(10, "Incorrect Token Type. Looking for Keyword or Identifier.", pS, pC, pT);
255 /* look for symbol '(' that specifies beginning of parameter list */
256 if(has_more_tokens(pC) == true)
258 pC = advance(pC, pT);
259 tk = token_type(pT);
260 if(*pT == '(')
262 if(settings.tokens) { token_print("symbol", BOTH); }
263 parse_params();
264 } else {
265 compiler_error(12, "Parameter List for Function Missing", pS, pC, pT);
267 } else {
268 compiler_error(11, "Name of Function Must be an Identifier", pS, pC, pT);
271 /* look for end of parameter list */
272 if(*pT == ')')
274 if(settings.tokens)
276 token_print("symbol", BOTH);
277 token_print("subroutineBody", OPEN);
278 space_count++;
280 } else {
281 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
284 /* look for opening brace for block */
285 if(has_more_tokens(pC) == true)
287 pC = advance(pC, pT);
288 tk = token_type(pT);
289 if(*pT == '{')
291 if(settings.tokens) { token_print("symbol", BOTH); }
292 if(has_more_tokens(pC) == true)
294 pC = advance(pC, pT);
295 tk = token_type(pT);
296 } else {
297 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
299 parse_var_dec();
301 } else {
302 compiler_error(9, "Could Not Complete Parse Tree of Subroutine. Incomplete Program", pS, pC, pT);
305 parse_statements();
307 if(*pT == '}')
309 if(settings.tokens) { token_print("symbol", BOTH); }
310 } else {
311 compiler_error(17, "Could Not Complete Subroutine. Incomplete Program", pS, pC, pT);
314 if(settings.tokens)
316 space_count--;
317 token_print("subroutineBody", CLOSE);
318 space_count--;
319 token_print("subroutineDec", CLOSE);
323 void parse_params()
325 if(*pT == '(') { if(settings.tokens) { token_print("parameterList", OPEN); space_count++; } }
327 /* look for datatype in parameter list */
328 if(has_more_tokens(pC) == true)
330 pC = advance(pC, pT);
331 tk = token_type(pT);
332 if(tk == KEYWORD) {
333 if(strcmp(pT, "int") == 0 || strcmp(pT, "char") == 0 || strcmp(pT, "boolean") == 0)
335 if(settings.tokens) { token_print("keyword", BOTH); }
336 } else {
337 compiler_error(14, "Incorrect Token Type in Parameter List. Looking for Datatype name.", pS, pC, pT);
339 } else if(tk == SYMBOL && *pT == ')') {
340 if(settings.tokens)
342 space_count--;
343 token_print("parameterList", CLOSE);
345 return;
347 } else {
348 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
351 /* look for identifier for this parameter */
352 if(has_more_tokens(pC) == true)
354 pC = advance(pC, pT);
355 tk = token_type(pT);
356 if(tk == IDENTIFIER) {
357 if(settings.tokens) { token_print("identifier", BOTH); }
358 } else {
359 compiler_error(15, "Incorrect Token Type in Parameter List. Looking for Variable Identifier.", pS, pC, pT);
361 } else {
362 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
365 /* are there more parameters? */
366 if(has_more_tokens(pC) == true)
368 pC = advance(pC, pT);
369 tk = token_type(pT);
370 if(*pT == ',') {
371 if(settings.tokens) { token_print("symbol", BOTH); }
372 parse_params();
373 } else if (*pT == ')') { /* exit parse_params */
374 if(settings.tokens)
376 space_count--;
377 token_print("parameterList", CLOSE);
379 return;
380 } else {
381 compiler_error(16, "Incorrect Token Type in Parameter List. Looking for ',' or ')'", pS, pC, pT);
383 } else {
384 compiler_error(13, "Could Not Complete Parameter List for Function", pS, pC, pT);
388 void parse_var_dec()
390 /* look for token named 'var' */
391 if(strcmp(pT, "var") == 0)
393 if(settings.tokens)
395 token_print("varDec", OPEN);
396 token_print("keyword", BOTH);
398 } else { return; }
400 /* look for variable data type */
401 if(has_more_tokens(pC) == true)
403 pC = advance(pC, pT);
404 tk = token_type(pT);
405 if(strcmp(pT, "int") == 0 || strcmp(pT, "char") == 0 || strcmp(pT, "boolean") == 0)
407 if(settings.tokens) { token_print("keyword", BOTH); }
409 } else if (tk == IDENTIFIER) { /* could also be a custom class name */
410 if(settings.tokens) { token_print("identifier", BOTH); }
411 } else {
412 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
416 /* look for identifier(s) for variable(s) */
417 do {
418 if(has_more_tokens(pC) == true)
420 pC = advance(pC, pT);
421 tk = token_type(pT);
422 } else {
423 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
425 if(tk == IDENTIFIER)
427 if(settings.tokens) { token_print("identifier", BOTH); }
430 if(has_more_tokens(pC) == true)
432 pC = advance(pC, pT);
433 tk = token_type(pT);
434 } else {
435 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
437 if(tk == SYMBOL)
439 if(settings.tokens) { token_print("symbol", BOTH); }
441 } while (*pT == ',');
443 if(has_more_tokens(pC) == true)
445 pC = advance(pC, pT);
446 tk = token_type(pT);
447 } else {
448 compiler_error(17, "Could Not Complete Variable List of Subroutine. Incomplete Program", pS, pC, pT);
450 if(settings.tokens) { token_print("varDec", CLOSE); }
451 parse_var_dec();
454 void parse_statements()
456 if(settings.tokens)
458 token_print("statements", OPEN);
459 space_count++;
461 do {
462 if(strcmp(pT, "let") == 0)
464 parse_let();
465 } else if(strcmp(pT, "if") == 0)
467 parse_if();
468 } else if(strcmp(pT, "while") == 0)
470 parse_while();
471 } else if(strcmp(pT, "do") == 0)
473 parse_do();
474 } else if(strcmp(pT, "return") == 0)
476 parse_return();
479 if(has_more_tokens(pC) == true)
481 pC = advance(pC, pT);
482 tk = token_type(pT);
485 } while (strcmp(pT, "let") == 0 || strcmp(pT, "if") == 0 || strcmp(pT, "while") == 0 || \
486 strcmp(pT, "do") == 0 || strcmp(pT, "return") == 0 );
487 if(settings.tokens)
489 space_count--;
490 token_print("statements", CLOSE);
494 void parse_do()
496 if(settings.tokens)
498 token_print("doStatement", OPEN);
499 space_count++;
500 token_print("keyword", BOTH);
503 if(has_more_tokens(pC) == true)
505 pC = advance(pC, pT);
506 tk = token_type(pT);
507 } else {
508 compiler_error(20, "Could Not Complete Do Statement. Incomplete Program", pS, pC, pT);
511 /* must be an identifier */
512 if(tk == IDENTIFIER) {
513 parse_subroutine_call();
514 } else {
515 compiler_error(30, "Subroutine Name Must Be Listed Here", pS, pC, pT);
518 if(*pT == ';')
520 if(settings.tokens) { token_print("symbol", BOTH); }
521 } else {
522 compiler_error(33, "Could Not Find ';' Symbol At This Location.", pS, pC, pT);
525 if(settings.tokens)
527 space_count--;
528 token_print("doStatement", CLOSE);
532 void parse_let()
534 int found_array = 0;
535 if(settings.tokens)
537 token_print("letStatement", OPEN);
538 space_count++;
539 token_print("keyword", BOTH);
542 if(has_more_tokens(pC) == true)
544 pC = advance(pC, pT);
545 tk = token_type(pT);
546 } else {
547 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
550 /* look for an identifier - must be a variable name */
551 if(tk == IDENTIFIER)
553 if(settings.tokens) { token_print("identifier", BOTH); }
554 } else {
555 compiler_error(31, "Could Not Find Identifier At This Location", pS, pC, pT);
558 /* optional '[' for an array offset value */
559 if(has_more_tokens(pC) == true)
561 pC = advance(pC, pT);
562 tk = token_type(pT);
563 } else {
564 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
567 if(*pT == '[')
569 found_array++;
570 if(settings.tokens) { token_print("symbol", BOTH); }
571 if(has_more_tokens(pC) == true)
573 pC = advance(pC, pT);
574 tk = token_type(pT);
575 } else {
576 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
578 parse_expression(0);
581 /* should be closing ']' here if variable was array */
582 if(found_array && *pT == ']')
584 if(settings.tokens) { token_print("symbol", BOTH); }
585 if(has_more_tokens(pC) == true)
587 pC = advance(pC, pT);
588 tk = token_type(pT);
589 } else {
590 compiler_error(20, "Could Not Find ']' Symbol At This Location", pS, pC, pT);
594 if(*pT == '=')
596 if(settings.tokens) { token_print("symbol", BOTH); }
597 } else {
598 compiler_error(32, "Could Not Find '=' Symbol At This Location", pS, pC, pT);
601 if(has_more_tokens(pC) == true)
603 pC = advance(pC, pT);
604 tk = token_type(pT);
605 } else {
606 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
609 parse_expression(0);
611 if(*pT == ';')
613 if(settings.tokens) { token_print("symbol", BOTH); }
614 } else {
615 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
618 if(settings.tokens)
620 space_count--;
621 token_print("letStatement", CLOSE);
625 void parse_while()
627 if(settings.tokens)
629 token_print("whileStatement", OPEN);
630 space_count++;
631 token_print("keyword", BOTH);
634 if(has_more_tokens(pC) == true)
636 pC = advance(pC, pT);
637 tk = token_type(pT);
638 } else {
639 compiler_error(47, "Could Not Complete While Statement. Incomplete Program", pS, pC, pT);
642 if(*pT == '(')
644 if(settings.tokens) { token_print("symbol", BOTH); }
645 } else {
646 compiler_error(39, "Could Not Find '(' Symbol At This Location", pS, pC, pT);
649 if(has_more_tokens(pC) == true)
651 pC = advance(pC, pT);
652 tk = token_type(pT);
653 } else {
654 compiler_error(47, "Could Not Complete While Statement. Incomplete Program", pS, pC, pT);
657 parse_expression(0);
659 if(*pT == ')')
661 if(settings.tokens) { token_print("symbol", BOTH); }
662 } else {
663 compiler_error(38, "Could Not Find ')' Symbol At This Location", pS, pC, pT);
666 if(has_more_tokens(pC) == true)
668 pC = advance(pC, pT);
669 tk = token_type(pT);
670 } else {
671 compiler_error(47, "Could Not Complete While Statement. Incomplete Program", pS, pC, pT);
674 if(*pT == '{')
676 if(settings.tokens) { token_print("symbol", BOTH); }
677 } else {
678 compiler_error(45, "Could Not Find '{' Symbol At This Location", pS, pC, pT);
681 if(has_more_tokens(pC) == true)
683 pC = advance(pC, pT);
684 tk = token_type(pT);
685 } else {
686 compiler_error(47, "Could Not Complete While Statement. Incomplete Program", pS, pC, pT);
689 parse_statements();
691 if(*pT == '}')
693 if(settings.tokens) { token_print("symbol", BOTH); }
694 } else {
695 compiler_error(46, "Could Not Find '}' Symbol At This Location", pS, pC, pT);
698 if(settings.tokens)
700 space_count--;
701 token_print("whileStatement", CLOSE);
705 void parse_return()
707 if(settings.tokens)
709 token_print("returnStatement", OPEN);
710 space_count++;
711 token_print("keyword", BOTH);
714 /* look for ';' */
715 if(has_more_tokens(pC) == true)
717 pC = advance(pC, pT);
718 tk = token_type(pT);
719 } else {
720 compiler_error(20, "Could Not Complete Let Statement. Incomplete Program", pS, pC, pT);
723 if (*pT != ';') { parse_expression(0); }
725 if(*pT == ';')
727 if(settings.tokens) { token_print("symbol", BOTH); }
728 } else {
729 compiler_error(33, "Could Not Find ';' Symbol At This Location", pS, pC, pT);
731 if(settings.tokens)
733 space_count--;
734 token_print("returnStatement", CLOSE);
738 void parse_if()
740 char *pTemp = NULL;
742 if(settings.tokens)
744 token_print("ifStatement", OPEN);
745 space_count++;
746 token_print("keyword", BOTH);
749 if(has_more_tokens(pC) == true)
751 pC = advance(pC, pT);
752 tk = token_type(pT);
753 } else {
754 compiler_error(47, "Could Not Complete If Statement. Incomplete Program", pS, pC, pT);
757 if(*pT == '(')
759 if(settings.tokens) { token_print("symbol", BOTH); }
760 } else {
761 compiler_error(39, "Could Not Find '(' Symbol At This Location", pS, pC, pT);
764 if(has_more_tokens(pC) == true)
766 pC = advance(pC, pT);
767 tk = token_type(pT);
768 } else {
769 compiler_error(47, "Could Not Complete If Statement. Incomplete Program", pS, pC, pT);
772 parse_expression(0);
774 if(*pT == ')')
776 if(settings.tokens) { token_print("symbol", BOTH); }
777 } else {
778 compiler_error(38, "Could Not Find ')' Symbol At This Location", pS, pC, pT);
781 if(has_more_tokens(pC) == true)
783 pC = advance(pC, pT);
784 tk = token_type(pT);
785 } else {
786 compiler_error(47, "Could Not Complete If Statement. Incomplete Program", pS, pC, pT);
789 if(*pT == '{')
791 if(settings.tokens) { token_print("symbol", BOTH); }
792 } else {
793 compiler_error(45, "Could Not Find '{' Symbol At This Location", pS, pC, pT);
796 if(has_more_tokens(pC) == true)
798 pC = advance(pC, pT);
799 tk = token_type(pT);
800 } else {
801 compiler_error(47, "Could Not Complete If Statement. Incomplete Program", pS, pC, pT);
804 parse_statements();
806 if(*pT == '}')
808 pTemp = pC; /* store pointer to where we are - in case no 'else' clause exists */
809 if(settings.tokens) { token_print("symbol", BOTH); }
810 } else {
811 compiler_error(46, "Could Not Find '}' Symbol At This Location", pS, pC, pT);
814 /* Look forward and see if 'else' clause is there*/
815 if(has_more_tokens(pC) == true)
817 pC = advance(pC, pT);
818 tk = token_type(pT);
819 } else {
820 compiler_error(47, "Could Not Complete If Statement. Incomplete Program", pS, pC, pT);
823 if(strcmp(pT, "else") == 0)
825 if(settings.tokens) { token_print("keyword", BOTH); };
827 if(has_more_tokens(pC) == true)
829 pC = advance(pC, pT);
830 tk = token_type(pT);
831 } else {
832 compiler_error(47, "Could Not Complete If Statement. Incomplete Program", pS, pC, pT);
835 if(*pT == '{')
837 if(settings.tokens) { token_print("symbol", BOTH); }
838 } else {
839 compiler_error(45, "Could Not Find '{' Symbol At This Location", pS, pC, pT);
842 parse_statements();
844 if(*pT == '}')
846 if(settings.tokens) { token_print("symbol", BOTH); }
847 } else {
848 compiler_error(46, "Could Not Find '}' Symbol At This Location", pS, pC, pT);
850 } else {
851 pC = pTemp-1; /* rewind back to end of 'if' statement */
852 if(has_more_tokens(pC) == true)
854 pC = advance(pC, pT);
855 tk = token_type(pT);
856 } else {
857 compiler_error(47, "Could Not Complete If Statement. Incomplete Program", pS, pC, pT);
861 if(settings.tokens)
863 space_count--;
864 token_print("ifStatement", CLOSE);
868 void parse_expression(int count)
870 if(settings.tokens && count == 0)
872 token_print("expression", OPEN);
873 space_count++;
875 count++;
876 parse_term();
878 if(strchr(BINARY_OP, *pT) != NULL)
880 if(settings.tokens) { token_print("symbol", BOTH); }
881 if(has_more_tokens(pC) == true)
883 pC = advance(pC, pT);
884 tk = token_type(pT);
885 } else {
886 compiler_error(34, "Could Not Parse Expression. Incomplete Program", pS, pC, pT);
888 parse_expression(count);
890 if(settings.tokens && count == 1)
892 space_count--;
893 token_print("expression", CLOSE);
897 void parse_term()
899 if(settings.tokens)
901 token_print("term", OPEN);
902 space_count++;
905 if(tk == INT_CONST)
907 if(settings.tokens) { token_print("integerConstant", BOTH); }
908 if(has_more_tokens(pC) == true)
910 pC = advance(pC, pT);
911 tk = token_type(pT);
912 } else {
913 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
916 if(settings.tokens)
918 space_count--;
919 token_print("term", CLOSE);
921 return;
924 if(strchr(UNARY_OP, *pT) != NULL)
926 if(settings.tokens) { token_print("unaryOperator", BOTH); }
927 if(has_more_tokens(pC) == true)
929 pC = advance(pC, pT);
930 tk = token_type(pT);
931 } else {
932 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
934 parse_term();
937 if(tk == KEYWORD)
939 if(settings.tokens) { token_print("keyword", BOTH); }
941 if(has_more_tokens(pC) == true)
943 pC = advance(pC, pT);
944 tk = token_type(pT);
945 } else {
946 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
950 if(tk == IDENTIFIER)
952 if(settings.tokens) { token_print("identifier", BOTH); }
954 if(has_more_tokens(pC) == true)
956 pC = advance(pC, pT);
957 tk = token_type(pT);
958 } else {
959 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
963 switch(*pT)
965 case '[':
966 if(settings.tokens) { token_print("symbol", BOTH); }
968 if(has_more_tokens(pC) == true)
970 pC = advance(pC, pT);
971 tk = token_type(pT);
972 } else {
973 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
975 parse_expression(0);
976 if(*pT == ']')
978 if(settings.tokens) { token_print("symbol", BOTH); }
979 /* parse_expression(0); */
980 } else {
981 compiler_error(26, "Improperly Terminated Array Expression. Symbol ']' Required at this Location.", pS, pC, pT);
984 if(has_more_tokens(pC) == true)
986 pC = advance(pC, pT);
987 tk = token_type(pT);
988 } else {
989 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
991 break;
992 case '(':
993 if(settings.tokens) { token_print("symbol", BOTH); }
995 if(has_more_tokens(pC) == true)
997 pC = advance(pC, pT);
998 tk = token_type(pT);
999 } else {
1000 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
1003 parse_expression(0);
1005 if (*pT == ')') {
1006 if(settings.tokens) { token_print("symbol", BOTH); }
1007 } else {
1008 compiler_error(38, "Could Not Find Symbol ')' At This Location", pS, pC, pT);
1011 if(has_more_tokens(pC) == true)
1013 pC = advance(pC, pT);
1014 tk = token_type(pT);
1015 } else {
1016 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
1018 break;
1019 case '.':
1020 if(settings.tokens) { token_print("symbol", BOTH); }
1022 if(has_more_tokens(pC) == true)
1024 pC = advance(pC, pT);
1025 tk = token_type(pT);
1026 } else {
1027 compiler_error(25, "Could Not Complete Term. Incomplete Program", pS, pC, pT);
1030 parse_subroutine_call();
1031 break;
1034 if(settings.tokens)
1036 space_count--;
1037 token_print("term", CLOSE);
1041 void parse_subroutine_call()
1043 if(tk == IDENTIFIER)
1045 if(settings.tokens) { token_print("identifier", BOTH); }
1046 } else {
1047 compiler_error(35, "Could Not Find Class Name or Subroutine Name at This Location", pS, pC, pT);
1050 if(has_more_tokens(pC) == true)
1052 pC = advance(pC, pT);
1053 tk = token_type(pT);
1054 } else {
1055 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
1058 if (*pT == '.') {
1059 if(settings.tokens) { token_print("symbol", BOTH); }
1060 if(has_more_tokens(pC) == true)
1062 pC = advance(pC, pT);
1063 tk = token_type(pT);
1064 } else {
1065 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
1067 if(tk == IDENTIFIER)
1069 if(settings.tokens) { token_print("identifier", BOTH); }
1070 } else {
1071 compiler_error(37, "Could Not Find Method Name or Subroutine Name at This Location", pS, pC, pT);
1075 if(*pT != '(') /* this for calls with no class name at beginning */
1077 if(has_more_tokens(pC) == true)
1079 pC = advance(pC, pT);
1080 tk = token_type(pT);
1081 } else {
1082 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
1086 if(*pT == '(')
1088 if(settings.tokens) { token_print("symbol", BOTH); }
1089 } else {
1090 compiler_error(39, "Could Not Find Symbol '(' At This Location", pS, pC, pT);
1093 if(has_more_tokens(pC) == true)
1095 pC = advance(pC, pT);
1096 tk = token_type(pT);
1097 } else {
1098 compiler_error(36, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
1101 parse_expr_lst();
1103 if(*pT == ')')
1105 if(settings.tokens) { token_print("symbol", BOTH); }
1106 } else {
1107 compiler_error(38, "Could Not Find Symbol ')' At This Location", pS, pC, pT);
1110 if(has_more_tokens(pC) == true)
1112 pC = advance(pC, pT);
1113 tk = token_type(pT);
1114 } else {
1115 compiler_error(24, "Could Not Complete Subroutine Call. Incomplete Program", pS, pC, pT);
1119 void parse_expr_lst()
1121 if(settings.tokens) { token_print("expressionList", OPEN); }
1122 while(*pT != ')')
1124 if(*pT == ',')
1126 if(settings.tokens) { token_print("symbol", BOTH); }
1127 if(has_more_tokens(pC) == true)
1129 pC = advance(pC, pT);
1130 tk = token_type(pT);
1131 } else {
1132 compiler_error(24, "Could Not Complete Expression List. Incomplete Program", pS, pC, pT);
1134 } else {
1135 parse_expression(0);
1138 if(settings.tokens) { token_print("expressionList", CLOSE); }