1 /*
2  * OpenBOR - http://www.LavaLit.com
3  * -----------------------------------------------------------------------
4  * All rights reserved, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2013 OpenBOR Team
7  */
8 
9 #include "Parser.h"
10 
11 Parser *pcurParser = NULL;
12 
Parser_Init(Parser * pparser)13 void Parser_Init(Parser *pparser)
14 {
15     memset(pparser, 0, sizeof(Parser));
16     Stack_Init(&(pparser->LabelStack));
17     ParserSet_Buildup(&(pparser->theParserSet));
18     pparser->LabelCount = 0;
19     pparser->theFieldToken.theType = END_OF_TOKENS;
20     pparser->theNextToken.theType = END_OF_TOKENS;
21 }
22 
Parser_Clear(Parser * pparser)23 void Parser_Clear(Parser *pparser)
24 {
25     Label label;
26     Lexer_Clear(&(pparser->theLexer));
27     ParserSet_Clear(&(pparser->theParserSet));
28     while(!Stack_IsEmpty(&(pparser->LabelStack)))
29     {
30         label = (Label)Stack_Top(&(pparser->LabelStack));
31         free(label);
32         Stack_Pop(&(pparser->LabelStack));
33     }
34     List_Clear(&(pparser->LabelStack));
35 }
36 
37 /******************************************************************************
38 *  ParseText -- This method begins the recursive-descent process for each global
39 *  variable and function definition.
40 *  Parameters: pcontext -- Preprocessor context for the script to be parsed.
41 *              pIList -- pointer to a TList<CInstruction> which takes the
42 *                        stream of CInstructions representing the parsed text
43 *              scriptText -- LPCSTR which contains ths script to be parsed.
44 *              startingLineNumber -- Line on which this script starts.  The
45 *                        lexer needs this information to maintain accurate
46 *                        line counts.
47 *  Returns:
48 ******************************************************************************/
Parser_ParseText(Parser * pparser,pp_context * pcontext,List * pIList,LPSTR scriptText,ULONG startingLineNumber,LPCSTR path)49 void Parser_ParseText(Parser *pparser, pp_context *pcontext, List *pIList, LPSTR scriptText,
50                       ULONG startingLineNumber, LPCSTR path )
51 {
52     //Create a new CLexer for this script text.
53     TEXTPOS thePosition;
54     thePosition.row = startingLineNumber;
55     thePosition.col = 1;
56     pcurParser = pparser;
57     if(path)
58     {
59         strncpy(pparser->currentPath, path, 255);
60     }
61     else
62     {
63         pparser->currentPath[0] = 0;
64     }
65     pparser->errorFound = FALSE;
66     Lexer_Init(&(pparser->theLexer), pcontext, path, scriptText, thePosition );
67 
68     //Get the first token from the CLexer.
69     Lexer_GetNextToken(&(pparser->theLexer), &(pparser->theNextToken));
70 
71     //Setup the instruction list so we can add instructions.
72     pparser->pIList = pIList;
73 
74     //Make sure we're pointing at the end of that list
75     List_GotoLast(pparser->pIList);
76 
77     if(!pparser->isImport && testpackfile("data/scripts/openbor.h", packfile) >= 0)
78     {
79         pp_parser_include(&pparser->theLexer.preprocessor, "data/scripts/openbor.h");
80     }
81 
82     //Parse the script text until you reach the end of the file, or until
83     //an error occurs.
84     while( pparser->theNextToken.theType != TOKEN_EOF )
85     {
86         Parser_External_decl(pparser );
87     }
88 }
89 
90 
91 
92 /******************************************************************************
93 *  ParseExpression -- This method begins the recursive-descent process for each
94 *  global variable and function definition.
95 *  Parameters: pIList -- pointer to a TList<CInstruction> which takes the
96 *                        stream of CInstructions representing the parsed text
97 *              scriptText -- LPCSTR which contains ths script to be parsed.
98 *              startingLineNumber -- Line on which this script starts.  The
99 *                        lexer needs this information to maintain accurate
100 *                        line counts.
101 *  Returns:
102 ******************************************************************************/
Parser_ParseExpression(Parser * pparser,List * pIList,LPSTR scriptText,ULONG startingLineNumber,LPCSTR path)103 void Parser_ParseExpression(Parser *pparser, List *pIList, LPSTR scriptText,
104                             ULONG startingLineNumber, LPCSTR path )
105 {
106     TEXTPOS thePosition;
107 
108     //Append a semi-colon to the end of the expression, in order to use the
109     //same grammar as regular script text.
110     LPSTR expressionText = (CHAR *)malloc(sizeof(CHAR) * strlen(scriptText) + 2);
111     strcpy( (CHAR *)expressionText, scriptText );
112     strcat( (CHAR *)expressionText, ";" );
113 
114     //Create a new CLexer for this script text.
115     thePosition.row = startingLineNumber;
116     thePosition.col = 1;
117     if(path)
118     {
119         strncpy(pparser->currentPath, path, 255);
120     }
121     else
122     {
123         pparser->currentPath[0] = 0;
124     }
125     pparser->errorFound = FALSE;
126     Lexer_Init(&(pparser->theLexer), pparser->theLexer.preprocessor.ctx, path, expressionText, thePosition );
127 
128     //Get the first token from the CLexer.
129     Lexer_GetNextToken(&(pparser->theLexer), &(pparser->theNextToken));
130 
131     //Setup the instruction list so we can add instructions.
132     pparser->pIList = pIList;
133 
134     //Make sure we're pointing at the end of that list
135     List_GotoLast(pparser->pIList);
136 
137     //Parse the expression
138     Parser_Expr(pparser);
139 
140     //release text buffer
141     free(expressionText);
142 }
143 
144 /******************************************************************************
145 *  AddInstruction -- This method creates a new CInstruction and adds it to the
146 *  instruction list.  It serves to simplify the parser code slightly, and to
147 *  allow for easier extension of the CInstruction class for debugging.
148 *  Parameters: pCode -- OpCode of the new instruction
149 *              pToken -- CToken associated with the new instruction
150 *              label -- entry point label in the instruction list
151 ******************************************************************************/
152 
Parser_AddInstructionViaToken(Parser * pparser,OpCode pCode,Token * pToken,Label label)153 void Parser_AddInstructionViaToken(Parser *pparser, OpCode pCode, Token *pToken, Label label )
154 {
155     Instruction *pInstruction = NULL;
156     pInstruction = (Instruction *)malloc(sizeof(Instruction));
157     Instruction_InitViaToken(pInstruction, pCode, pToken);
158     List_InsertAfter(pparser->pIList, pInstruction, label);
159 }
160 
161 /******************************************************************************
162 *  AddInstruction -- This method creates a new CInstruction and adds it to the
163 *  instruction list.  It serves to simplify the parser code slightly, and to
164 *  allow for easier extension of the CInstruction class for debugging.
165 *  Parameters: pCode -- OpCode of the new instruction
166 *              instrLabel -- Label associated with this instruction
167 *              listLabel -- entry point label in the instruction list
168 ******************************************************************************/
Parser_AddInstructionViaLabel(Parser * pparser,OpCode pCode,Label instrLabel,Label listLabel)169 void Parser_AddInstructionViaLabel(Parser *pparser, OpCode pCode, Label instrLabel, Label listLabel )
170 {
171     Instruction *pInstruction = NULL;
172     pInstruction = (Instruction *)malloc(sizeof(Instruction));
173     Instruction_InitViaLabel(pInstruction, pCode, instrLabel);
174     List_InsertAfter(pparser->pIList, pInstruction, listLabel);
175 }
176 
177 /******************************************************************************
178 *  Check -- This method compares the type of the current token with a specified
179 *  token type.
180 *  Parameters: theType -- MY_TOKEN_TYPE specifying the type to compare
181 *  Returns: true if the current token type matches theType
182 *           false otherwise.
183 ******************************************************************************/
Parser_Check(Parser * pparser,MY_TOKEN_TYPE theType)184 BOOL Parser_Check(Parser *pparser, MY_TOKEN_TYPE theType )
185 {
186     //compare the token types
187     return (pparser->theNextToken.theType == theType);
188 }
189 
190 /*****************************************************************************
191 *  Match -- This method consumes the current token and retrieves the next one.
192 *  Parameters:
193 *  Returns:
194 ******************************************************************************/
Parser_Match(Parser * pparser)195 void Parser_Match( Parser *pparser )
196 {
197     if (FAILED(Lexer_GetNextToken(&(pparser->theLexer), &(pparser->theNextToken))))
198     {
199         Parser_Error(pparser, error);
200     }
201 }
202 
203 /******************************************************************************
204 *   CreateLabel -- This method creates a label, unique within this parser, to
205 *   Serve as a target for jumps and calls.
206 *   Parameters: none
207 *   Returns: A unique Label
208 ******************************************************************************/
Parser_CreateLabel(Parser * pparser)209 Label Parser_CreateLabel( Parser *pparser )
210 {
211     //Allocate a buffer for the new Label.  A long can take 10 characters at
212     //most, so allocate that plus two extra for the "" and the null
213     //terminator
214     Label theLabel = (CHAR *)malloc(12);
215     memset(theLabel, 0, 12);
216 
217     //Increment the label count.
218     pparser->LabelCount++;
219 
220     sprintf(theLabel, "L%d", pparser->LabelCount);
221 
222     return theLabel;
223 }
224 
225 /******************************************************************************
226 *  Productions -- These methods recursively parse the token stream into an
227 *  Abstract Syntax Tree.
228 ******************************************************************************/
229 
Parser_Start(Parser * pparser)230 void Parser_Start(Parser *pparser )
231 {
232     if (ParserSet_First(&(pparser->theParserSet), external_decl, pparser->theNextToken.theType))
233     {
234         Parser_External_decl(pparser);
235         Parser_Start(pparser );
236     }
237     else if (ParserSet_Follow(&(pparser->theParserSet), start, pparser->theNextToken.theType )) {}
238     else
239     {
240         Parser_Error(pparser, start );
241     }
242 }
243 
244 /******************************************************************************
245 *  Declaration evaluation -- These methods translate declarations into
246 *  appropriate instructions.
247 ******************************************************************************/
Parser_External_decl(Parser * pparser)248 void Parser_External_decl(Parser *pparser )
249 {
250     if (ParserSet_First(&(pparser->theParserSet), decl_spec, pparser->theNextToken.theType ))
251     {
252         Parser_Decl_spec(pparser );
253         Parser_External_decl2(pparser, FALSE); // go for the declaration
254     }
255 
256     else
257     {
258         Parser_Error(pparser, external_decl );
259     }
260 }
261 
262 // this function is used by Parser_External_decl, because there can be multiple identifiers share only one type token
263 // variable only means the function only accept variables, not function declaration, e.g.
264 // int a, b=1, c;
Parser_External_decl2(Parser * pparser,BOOL variableonly)265 void Parser_External_decl2(Parser *pparser, BOOL variableonly )
266 {
267     Token token = pparser->theNextToken;
268     //ignore the type of this declaration
269     if(!Parser_Check(pparser, TOKEN_IDENTIFIER ))
270     {
271         printf("Identifier expected before '%s'.\n", token.theSource);
272         Parser_Error(pparser, external_decl );
273     }
274     Parser_Match(pparser);
275 
276     //type a =
277     if (ParserSet_First(&(pparser->theParserSet), initializer, pparser->theNextToken.theType ))
278     {
279         //switch to immediate mode and allocate a variable.
280         Parser_AddInstructionViaToken(pparser, IMMEDIATE, (Token *)NULL, NULL );
281         Parser_AddInstructionViaToken(pparser, DATA, &token, NULL );
282 
283         //Get the initializer; type a = expression
284         Parser_Initializer(pparser );
285         //type a = expresson;
286         if(Parser_Check(pparser, TOKEN_SEMICOLON ))
287         {
288             Parser_Match(pparser);
289 
290             //Save the initializer
291             Parser_AddInstructionViaToken(pparser, SAVE, &token, NULL );
292 
293             //Switch back to deferred mode
294             Parser_AddInstructionViaToken(pparser, DEFERRED, (Token *)NULL, NULL );
295         }
296         //there's a comma instead of semicolon, so there should be another identifier
297         else if(Parser_Check(pparser, TOKEN_COMMA ))
298         {
299             Parser_Match(pparser);
300             //Save the initializer
301             Parser_AddInstructionViaToken(pparser, SAVE, &token, NULL );
302             Parser_External_decl2(pparser, TRUE);
303         }
304         else
305         {
306             Parser_Match(pparser);
307             printf("Semicolon or comma expected before '%s'\n", pparser->theNextToken.theSource);
308             Parser_Error(pparser, external_decl );
309         }
310     }
311     // semicolon, end expression.
312     else if ( Parser_Check(pparser, TOKEN_SEMICOLON ))
313     {
314         Parser_Match(pparser);
315         //switch to immediate mode and allocate a variable.
316         Parser_AddInstructionViaToken(pparser, IMMEDIATE, (Token *)NULL, NULL );
317         Parser_AddInstructionViaToken(pparser, DATA, &token, NULL );
318 
319         //Switch back to deferred mode
320         Parser_AddInstructionViaToken(pparser, DEFERRED, (Token *)NULL, NULL );
321     }
322     // still comma? there should be another identifier so allocate the variable and go for the next
323     else if ( Parser_Check(pparser, TOKEN_COMMA ))
324     {
325         Parser_Match(pparser);
326         Parser_AddInstructionViaToken(pparser, DATA, &token, NULL );
327         Parser_External_decl2(pparser, TRUE);
328     }
329     // not a comma, semicolon, or initializer, so must be a function declaration
330     else if (variableonly == FALSE && ParserSet_First(&(pparser->theParserSet), funcDecl, pparser->theNextToken.theType ))
331     {
332         Parser_AddInstructionViaToken(pparser, FUNCDECL, &token, (Label)token.theSource );
333         Parser_AddInstructionViaToken(pparser, PUSH, (Token *)NULL, NULL );
334         Parser_FuncDecl(pparser );
335         Parser_Comp_stmt_Label(pparser, pparser->theRetLabel );
336         Parser_AddInstructionViaToken(pparser, POP, (Token *)NULL, NULL );
337         Parser_AddInstructionViaToken(pparser, RET, (Token *)NULL, NULL );
338     }
339     else
340     {
341         Parser_Error(pparser, external_decl );
342     }
343 }
344 
Parser_Decl_spec(Parser * pparser)345 void Parser_Decl_spec(Parser *pparser )
346 {
347     if (Parser_Check(pparser, TOKEN_CONST ))
348     {
349         Parser_Match(pparser);
350     }
351 
352     if (Parser_Check(pparser, TOKEN_SIGNED ))
353     {
354         Parser_Match(pparser);
355     }
356     else if (Parser_Check(pparser, TOKEN_UNSIGNED ))
357     {
358         Parser_Match(pparser);
359     }
360 // It's OK though not all delow are valid types for C language
361     if (Parser_Check(pparser, TOKEN_VOID ))
362     {
363         Parser_Match(pparser);
364     }
365     else if (Parser_Check(pparser, TOKEN_CHAR ))
366     {
367         Parser_Match(pparser);
368     }
369     else if (Parser_Check(pparser, TOKEN_SHORT ))
370     {
371         Parser_Match(pparser);
372     }
373     else if (Parser_Check(pparser, TOKEN_INT ))
374     {
375         Parser_Match(pparser);
376     }
377     else if (Parser_Check(pparser, TOKEN_LONG ))
378     {
379         Parser_Match(pparser);
380     }
381     else if (Parser_Check(pparser, TOKEN_FLOAT ))
382     {
383         Parser_Match(pparser);
384     }
385     else if (Parser_Check(pparser, TOKEN_DOUBLE ))
386     {
387         Parser_Match(pparser);
388     }
389     else
390     {
391         Parser_Error(pparser, decl_spec );
392     }
393 }
394 
395 // internal decleraton for variables.
Parser_Decl(Parser * pparser)396 void Parser_Decl(Parser *pparser )
397 {
398     if (ParserSet_First(&(pparser->theParserSet), decl_spec, pparser->theNextToken.theType ))
399     {
400         //ignore the type of this declaration
401         Parser_Decl_spec(pparser );
402         Parser_Decl2(pparser);
403     }
404     else
405     {
406         Parser_Error(pparser, decl );
407     }
408 }
409 
410 // this function is used by Parser_Decl for multiple declaration separated by commas
Parser_Decl2(Parser * pparser)411 void Parser_Decl2(Parser *pparser )
412 {
413     Token token = pparser->theNextToken;
414     if(Parser_Check(pparser, TOKEN_IDENTIFIER ) == FALSE)
415     {
416         printf("Identifier expected before '%s'.\n", token.theSource);
417         Parser_Error(pparser, decl );
418     }
419     Parser_Match(pparser);
420 
421     // =
422     if (ParserSet_First(&(pparser->theParserSet), initializer, pparser->theNextToken.theType ))
423     {
424         Parser_AddInstructionViaToken(pparser, DATA, &token, NULL );
425 
426         //Get the initializer;
427         Parser_Initializer(pparser );
428         if(Parser_Check(pparser, TOKEN_SEMICOLON ))
429         {
430             Parser_Match(pparser);
431             //Save the initializer
432             Parser_AddInstructionViaToken(pparser, SAVE, &token, NULL );
433         }
434         else if(Parser_Check(pparser, TOKEN_COMMA ))
435         {
436             Parser_Match(pparser);
437             Parser_AddInstructionViaToken(pparser, SAVE, &token, NULL );
438             Parser_Decl2(pparser);
439         }
440         else
441         {
442             Parser_Match(pparser);
443             printf("Semicolon or comma expected before '%s'\n", pparser->theNextToken.theSource);
444             Parser_Error(pparser, decl );
445         }
446     }
447     // ,
448     else if ( Parser_Check(pparser, TOKEN_COMMA ))
449     {
450         Parser_Match(pparser);
451         Parser_AddInstructionViaToken(pparser, DATA, &token, NULL );
452         Parser_Decl2(pparser);
453     }
454     // ;
455     else if ( Parser_Check(pparser, TOKEN_SEMICOLON ))
456     {
457         Parser_Match(pparser);
458         Parser_AddInstructionViaToken(pparser, DATA, &token, NULL );
459     }
460     else
461     {
462         Parser_Error(pparser, decl );
463     }
464 }
465 
Parser_FuncDecl(Parser * pparser)466 void Parser_FuncDecl(Parser *pparser )
467 {
468     if (Parser_Check(pparser, TOKEN_LPAREN ))
469     {
470         Parser_Match(pparser);
471         Parser_FuncDecl1(pparser);
472     }
473     else if (ParserSet_Follow(&(pparser->theParserSet), funcDecl, pparser->theNextToken.theType )) {}
474     else
475     {
476         Parser_Error(pparser, funcDecl );
477     }
478 }
479 
Parser_FuncDecl1(Parser * pparser)480 void Parser_FuncDecl1(Parser *pparser )
481 {
482     if (ParserSet_First(&(pparser->theParserSet), param_list, pparser->theNextToken.theType ))
483     {
484         Parser_Param_list(pparser );
485         Parser_Check(pparser, TOKEN_RPAREN );
486         Parser_Match(pparser);
487     }
488     else if (Parser_Check(pparser, TOKEN_RPAREN ))
489     {
490         Parser_AddInstructionViaLabel(pparser, CHECKARG, "0", NULL );
491         Parser_Match(pparser);
492     }
493     else
494     {
495         Parser_Error(pparser, funcDecl1 );
496     }
497 }
498 
Parser_Initializer(Parser * pparser)499 void Parser_Initializer(Parser *pparser )
500 {
501     if (Parser_Check(pparser, TOKEN_ASSIGN ))
502     {
503         Parser_Match(pparser);
504         Parser_Assignment_expr(pparser );
505     }
506     else if (ParserSet_Follow(&(pparser->theParserSet), initializer, pparser->theNextToken.theType )) {}
507     else
508     {
509         Parser_Error(pparser, initializer );
510     }
511 }
512 
Parser_Parm_decl(Parser * pparser)513 void Parser_Parm_decl(Parser *pparser )
514 {
515     if (ParserSet_First(&(pparser->theParserSet), decl_spec, pparser->theNextToken.theType ))
516     {
517         Parser_Decl_spec( pparser);
518 
519         if ( Parser_Check(pparser, TOKEN_IDENTIFIER ))
520         {
521             Parser_AddInstructionViaToken(pparser, PARAM, &(pparser->theNextToken), NULL );
522             Parser_Match(pparser);
523         }
524         else
525         {
526             Parser_AddInstructionViaToken(pparser, PARAM, (Token *)NULL, NULL );
527         }
528     }
529     else
530     {
531         Parser_Error(pparser, parm_decl );
532     }
533 }
534 
Parser_Param_list(Parser * pparser)535 void Parser_Param_list(Parser *pparser )
536 {
537     if (ParserSet_First(&(pparser->theParserSet), parm_decl, pparser->theNextToken.theType ))
538     {
539         Parser_Parm_decl(pparser );
540         pparser->paramCount = 1; // start count params
541         Parser_Param_list2(pparser );
542     }
543     else
544     {
545         Parser_Error(pparser, param_list );
546     }
547 }
548 
Parser_Param_list2(Parser * pparser)549 void Parser_Param_list2(Parser *pparser )
550 {
551     int i;
552     CHAR buf[4];
553     Instruction *pinstruction;
554     if (Parser_Check(pparser, TOKEN_COMMA ))
555     {
556         Parser_Match(pparser);
557         Parser_Parm_decl(pparser );
558         pparser->paramCount++;
559         Parser_Param_list2(pparser );
560     }
561     else if (ParserSet_Follow(&(pparser->theParserSet), param_list2, pparser->theNextToken.theType ))
562     {
563         //Walk back up the Instruction list and insert before the first PARAM
564         //instruction.
565         for(i = 1; i < pparser->paramCount; i++ )
566         {
567             List_GotoPrevious(pparser->pIList);
568         }
569 
570         sprintf( buf, "%d", pparser->paramCount );
571         pinstruction = (Instruction *)malloc(sizeof(Instruction));
572         Instruction_InitViaLabel(pinstruction, CHECKARG, buf);
573 
574         List_InsertBefore(pparser->pIList, pinstruction, NULL );
575 
576         //Walk back down the InstructionList to reset the insertion point
577         for (i = 0; i < pparser->paramCount; i++ )
578         {
579             List_GotoNext(pparser->pIList);
580         }
581 
582         //pparser->paramCount = 1;
583     }
584 
585     else
586     {
587         Parser_Error(pparser, param_list2 );
588         //pparser->paramCount =1 ;
589     }
590 }
591 
Parser_Decl_list(Parser * pparser)592 void Parser_Decl_list(Parser *pparser )
593 {
594     if (ParserSet_First(&(pparser->theParserSet), decl, pparser->theNextToken.theType ))
595     {
596         Parser_Decl(pparser );
597         Parser_Decl_list2(pparser );
598     }
599     else
600     {
601         Parser_Error(pparser, decl_list );
602     }
603 }
604 
Parser_Decl_list2(Parser * pparser)605 void Parser_Decl_list2(Parser *pparser )
606 {
607     if (ParserSet_First(&(pparser->theParserSet), decl, pparser->theNextToken.theType ))
608     {
609         Parser_Decl(pparser );
610         Parser_Decl_list2(pparser );
611     }
612     if (ParserSet_First(&(pparser->theParserSet), stmt, pparser->theNextToken.theType ))
613     {
614         Parser_Stmt(pparser );
615         Parser_Stmt_list2(pparser );
616     }
617     else if (ParserSet_Follow(&(pparser->theParserSet), decl_list2, pparser->theNextToken.theType )) {}
618     else
619     {
620         Parser_Error(pparser, decl_list2 );
621     }
622 }
623 
624 /******************************************************************************
625 *  Statement evaluation -- These methods translate statements into
626 *  appropriate instructions.
627 ******************************************************************************/
Parser_Stmt_list(Parser * pparser)628 void Parser_Stmt_list(Parser *pparser )
629 {
630     if (ParserSet_First(&(pparser->theParserSet), stmt, pparser->theNextToken.theType ))
631     {
632         Parser_Stmt(pparser );
633         Parser_Stmt_list2(pparser );
634     }
635     else
636     {
637         Parser_Error(pparser, stmt_list );
638     }
639 }
640 
Parser_Stmt_list2(Parser * pparser)641 void Parser_Stmt_list2(Parser *pparser )
642 {
643     if (ParserSet_First(&(pparser->theParserSet), stmt, pparser->theNextToken.theType ))
644     {
645         Parser_Stmt(pparser );
646         Parser_Stmt_list2(pparser );
647     }
648     else if (ParserSet_First(&(pparser->theParserSet), decl, pparser->theNextToken.theType ))
649     {
650         Parser_Decl(pparser);
651         Parser_Decl_list2(pparser);
652     }
653     else if (ParserSet_Follow(&(pparser->theParserSet), stmt_list2, pparser->theNextToken.theType )) {}
654     else
655     {
656         Parser_Error(pparser, stmt_list2 );
657     }
658 }
659 
Parser_Stmt(Parser * pparser)660 void Parser_Stmt( Parser *pparser)
661 {
662     if (ParserSet_First(&(pparser->theParserSet), expr_stmt, pparser->theNextToken.theType ))
663     {
664         Parser_Expr_stmt(pparser );
665     }
666     else if (ParserSet_First(&(pparser->theParserSet), comp_stmt, pparser->theNextToken.theType ))
667     {
668         Parser_Comp_stmt(pparser );
669     }
670     else if (ParserSet_First(&(pparser->theParserSet), select_stmt, pparser->theNextToken.theType ))
671     {
672         Parser_Select_stmt(pparser );
673     }
674     else if (ParserSet_First(&(pparser->theParserSet), iter_stmt, pparser->theNextToken.theType ))
675     {
676         Parser_Iter_stmt(pparser );
677     }
678     else if (ParserSet_First(&(pparser->theParserSet), jump_stmt, pparser->theNextToken.theType ))
679     {
680         Parser_Jump_stmt(pparser );
681     }
682     else
683     {
684         Parser_Error(pparser, stmt );
685     }
686 }
687 
Parser_Expr_stmt(Parser * pparser)688 void Parser_Expr_stmt(Parser *pparser )
689 {
690     Instruction *pInstruction;
691     if (ParserSet_First(&(pparser->theParserSet), expr, pparser->theNextToken.theType ))
692     {
693         Parser_Expr(pparser );
694         if((pInstruction = (Instruction *)List_Retrieve(pparser->pIList))->OpCode == LOAD)
695         {
696             Instruction_Clear(pInstruction);
697             free(pInstruction);
698             List_Remove(pparser->pIList);
699         }
700         else
701         {
702             Parser_AddInstructionViaToken(pparser, CLEAN, (Token *)NULL, NULL );
703         }
704         Parser_Check(pparser, TOKEN_SEMICOLON );
705         Parser_Match(pparser);
706     }
707     else
708     {
709         Parser_Error(pparser, expr_stmt );
710     }
711 }
712 
Parser_Comp_stmt_Label(Parser * pparser,Label theLabel)713 void Parser_Comp_stmt_Label(Parser *pparser, Label theLabel )
714 {
715     Label label;
716     if (Parser_Check(pparser, TOKEN_LCURLY ))
717     {
718         Parser_Match(pparser);
719         Parser_AddInstructionViaToken(pparser, PUSH, (Token *)NULL, NULL );
720         label = Parser_CreateLabel(pparser);
721         strcpy((CHAR *)theLabel, label);
722         Parser_Comp_stmt2(pparser );
723         Parser_Comp_stmt3(pparser );
724         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, label );
725         free(label);//dont forget to free the label
726         Parser_AddInstructionViaToken(pparser, POP, (Token *)NULL, NULL );
727         Parser_Check(pparser, TOKEN_RCURLY );
728         Parser_Match(pparser);
729     }
730     else
731     {
732         Parser_Error(pparser, comp_stmt );
733     }
734 }
735 
Parser_Comp_stmt(Parser * pparser)736 void Parser_Comp_stmt(Parser *pparser )
737 {
738     Label jumpLabel;
739     if (Parser_Check(pparser, TOKEN_LCURLY ))
740     {
741         Parser_Match(pparser);
742         Parser_AddInstructionViaToken(pparser, PUSH, (Token *)NULL, NULL );
743         jumpLabel = Parser_CreateLabel(pparser);
744         Parser_Comp_stmt2(pparser );
745         Parser_Comp_stmt3(pparser );
746         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, jumpLabel );
747         free(jumpLabel);
748         Parser_AddInstructionViaToken(pparser, POP, (Token *)NULL, NULL );
749         Parser_Check(pparser, TOKEN_RCURLY );
750         Parser_Match(pparser);
751     }
752     else
753     {
754         Parser_Error(pparser, comp_stmt );
755     }
756 }
757 
Parser_Comp_stmt2(Parser * pparser)758 void Parser_Comp_stmt2(Parser *pparser )
759 {
760     if (ParserSet_First(&(pparser->theParserSet), decl_list, pparser->theNextToken.theType ))
761     {
762         Parser_Decl_list(pparser );
763     }
764     else if (ParserSet_Follow(&(pparser->theParserSet), comp_stmt2, pparser->theNextToken.theType )) {}
765     else
766     {
767         Parser_Error(pparser, comp_stmt2 );
768     }
769 }
770 
Parser_Comp_stmt3(Parser * pparser)771 void Parser_Comp_stmt3(Parser *pparser )
772 {
773     if (ParserSet_First(&(pparser->theParserSet), stmt_list, pparser->theNextToken.theType ))
774     {
775         Parser_Stmt_list(pparser );
776     }
777     else if (ParserSet_Follow(&(pparser->theParserSet), comp_stmt3, pparser->theNextToken.theType )) {}
778     else
779     {
780         Parser_Error(pparser, comp_stmt3 );
781     }
782 }
783 
Parser_Select_stmt(Parser * pparser)784 void Parser_Select_stmt(Parser *pparser )
785 {
786     Label falseLabel, endLabel, defaultLabel;
787 
788     if (Parser_Check(pparser, TOKEN_IF ))
789     {
790         //Create some labels for jump targets
791         falseLabel = Parser_CreateLabel(pparser);
792         endLabel = Parser_CreateLabel(pparser);
793         Parser_Match(pparser);
794         Parser_Check(pparser, TOKEN_LPAREN );
795         Parser_Match(pparser);
796         Parser_Expr(pparser );
797         Parser_Check(pparser, TOKEN_RPAREN );
798         Parser_AddInstructionViaLabel(pparser, Branch_FALSE, falseLabel, NULL );
799         Parser_Match(pparser);
800         Parser_Stmt(pparser );
801         Parser_AddInstructionViaLabel(pparser, JUMP, endLabel, NULL );
802         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, falseLabel );
803         Parser_Opt_else(pparser );
804         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, endLabel );
805         //dont forget to free the labels
806         free(falseLabel);
807         free(endLabel);
808     }
809     else if (Parser_Check(pparser, TOKEN_SWITCH ))
810     {
811         List *pMainList, bodyInsts, cases;
812         int size, i; //for FOREACH
813 
814         Parser_Match(pparser );
815         Parser_Check(pparser, TOKEN_LPAREN );
816         Parser_Match(pparser );
817         Parser_Expr(pparser );
818         Parser_Check(pparser, TOKEN_RPAREN );
819         Parser_Match(pparser );
820         Parser_Check(pparser, TOKEN_LCURLY );
821         Parser_Match(pparser );
822 
823         endLabel = Parser_CreateLabel(pparser );
824         Stack_Push(&(pparser->LabelStack), NULL );
825         Stack_Push(&(pparser->LabelStack), endLabel );
826         defaultLabel = endLabel;
827 
828         //The jump instructions need to be right after the expression is evaluated,
829         //but we don't know the jump targets until after parsing the switch body. So
830         //we use a temporary instruction list when parsing the switch body.
831         pMainList = pparser->pIList;
832         List_Init(&bodyInsts);
833         pparser->pIList = &bodyInsts;
834 
835         //Parse body of switch, and consume the closing brace
836         List_Init(&cases);
837         Parser_Switch_body(pparser, &cases );
838         Parser_Check(pparser, TOKEN_RCURLY );
839         Parser_Match(pparser );
840 
841         //Restore the main instruction list
842         pparser->pIList = pMainList;
843 
844         //Add a conditional branch for each case label in the switch body
845         FOREACH(cases,
846                 Token *pToken = List_Retrieve(&cases);
847                 if(pToken)
848     {
849         int opcode = pToken->theType == TOKEN_STRING_LITERAL ? CONSTSTR : CONSTINT;
850         Parser_AddInstructionViaToken(pparser, opcode, pToken, NULL );
851             Parser_AddInstructionViaLabel(pparser, Branch_EQUAL, List_GetName(&cases), NULL );
852             free(pToken);
853         }
854         else
855         {
856             if(defaultLabel != endLabel)
857             {
858                 printf("Multiple default labels in one switch.");
859                 Parser_Error(pparser, select_stmt );
860             }
861             defaultLabel = List_GetName(&cases);
862         }
863                );
864 
865         //Add a jump to the "default" label if there is one, or to the end of
866         //the switch statement if there isn't.  We use PJUMP to pop the value
867         //of the switch expression from the stack before jumping.
868         Parser_AddInstructionViaLabel(pparser, PJUMP, defaultLabel, NULL );
869         List_Clear(&cases);
870 
871         //Now add the instructions from the switch body.
872         Parser_AddInstructionViaToken(pparser, PUSH, (Token *)NULL, NULL );
873         FOREACH(bodyInsts,
874                 void *pInstruction = List_Retrieve(&bodyInsts);
875                 List_InsertAfter(pparser->pIList, pInstruction, List_GetName(&bodyInsts));
876                );
877         List_Clear(&bodyInsts);
878 
879         //End the switch body's scope and add the end label.
880         Parser_AddInstructionViaToken(pparser, POP, (Token *)NULL, endLabel );
881         Stack_Pop(&(pparser->LabelStack));
882         Stack_Pop(&(pparser->LabelStack));
883         free(endLabel);
884     }
885     else
886     {
887         Parser_Error(pparser, select_stmt );
888     }
889 }
890 
Parser_Opt_else(Parser * pparser)891 void Parser_Opt_else(Parser *pparser )
892 {
893     if (Parser_Check(pparser, TOKEN_ELSE ))
894     {
895         Parser_Match(pparser);
896         Parser_Stmt(pparser );
897     }
898     else if (ParserSet_Follow(&(pparser->theParserSet), opt_else, pparser->theNextToken.theType )) {}
899     else
900     {
901         Parser_Error(pparser, opt_else );
902     }
903 }
904 
Parser_Switch_body(Parser * pparser,List * pCases)905 void Parser_Switch_body(Parser *pparser, List *pCases )
906 {
907     //Using a loop here instead of recursion goes against the idea of a
908     //recursive descent parser, but it keeps us from having 200 stack frames.
909     while(1)
910     {
911         if (ParserSet_First(&(pparser->theParserSet), case_label, pparser->theNextToken.theType ))
912         {
913             Parser_Case_label(pparser, pCases );
914         }
915         else if (ParserSet_First(&(pparser->theParserSet), stmt, pparser->theNextToken.theType ))
916         {
917             Parser_Stmt(pparser );
918             Parser_Stmt_list2(pparser );
919         }
920         else if (ParserSet_First(&(pparser->theParserSet), decl, pparser->theNextToken.theType ))
921         {
922             Parser_Decl(pparser );
923             Parser_Decl_list2(pparser );
924         }
925         else if (ParserSet_Follow(&(pparser->theParserSet), switch_body, pparser->theNextToken.theType ))
926         {
927             break;
928         }
929         else
930         {
931             Parser_Error(pparser, switch_body );
932             break;
933         }
934     }
935 }
936 
Parser_Case_label(Parser * pparser,List * pCases)937 void Parser_Case_label(Parser *pparser, List *pCases )
938 {
939     Label label;
940     Token *token;
941     if (Parser_Check(pparser, TOKEN_CASE ))
942     {
943         label = Parser_CreateLabel(pparser );
944         Parser_Match(pparser);
945         if(!Parser_Check(pparser, TOKEN_INTCONSTANT ) &&
946                 !Parser_Check(pparser, TOKEN_STRING_LITERAL ))
947         {
948             Parser_Error(pparser, case_label );
949         }
950         token = malloc(sizeof(Token));
951         memcpy(token, &pparser->theNextToken, sizeof(Token));
952         List_InsertAfter(pCases, token, label);
953         Parser_Match(pparser);
954         Parser_Check(pparser, TOKEN_COLON );
955         Parser_Match(pparser);
956         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, label );
957         free(label);
958     }
959     else if (Parser_Check(pparser, TOKEN_DEFAULT ))
960     {
961         label = Parser_CreateLabel(pparser );
962         Parser_Match(pparser);
963         Parser_Check(pparser, TOKEN_COLON );
964         Parser_Match(pparser);
965         List_InsertAfter(pCases, NULL, label);
966         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, label );
967         free(label);
968     }
969     else
970     {
971         Parser_Error(pparser, case_label );
972     }
973 }
974 
Parser_Iter_stmt(Parser * pparser)975 void Parser_Iter_stmt(Parser *pparser )
976 {
977     Label endLabel, startLabel, continueLabel;
978     List *pDefInst = NULL;
979     Instruction *pInstruction;
980     int i, size;
981     //Create some labels for jump targets
982     endLabel = Parser_CreateLabel(pparser);
983     startLabel = Parser_CreateLabel(pparser);
984     continueLabel = Parser_CreateLabel(pparser);
985 
986 
987     if (Parser_Check(pparser, TOKEN_WHILE ))
988     {
989         Parser_Match(pparser);
990         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, startLabel );
991         Parser_Check(pparser, TOKEN_LPAREN );
992         Parser_Match(pparser);
993         Parser_Expr(pparser );
994         Parser_Check(pparser, TOKEN_RPAREN );
995         Parser_AddInstructionViaLabel(pparser, Branch_FALSE, endLabel, NULL );
996         Stack_Push(&(pparser->LabelStack), startLabel ); //*****
997         Stack_Push(&(pparser->LabelStack), endLabel ); //*****
998         Parser_Match(pparser);
999         Parser_Stmt(pparser );
1000         Stack_Pop(&(pparser->LabelStack)); //*****
1001         Stack_Pop(&(pparser->LabelStack)); //*****
1002         Parser_AddInstructionViaLabel(pparser, JUMP, startLabel, NULL );
1003         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, endLabel );
1004     }
1005     else if (Parser_Check(pparser, TOKEN_DO ))
1006     {
1007         Parser_Match(pparser);
1008         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, startLabel );
1009         Stack_Push(&(pparser->LabelStack), startLabel ); //*****
1010         Stack_Push(&(pparser->LabelStack), endLabel ); //*****
1011         Parser_Stmt(pparser );
1012         Parser_Check(pparser, TOKEN_WHILE );
1013         Parser_Match(pparser);
1014         Parser_Check(pparser, TOKEN_LPAREN );
1015         Parser_Match(pparser);
1016         Parser_Expr(pparser );
1017         Parser_Check(pparser, TOKEN_RPAREN );
1018         Parser_AddInstructionViaLabel(pparser, Branch_TRUE, startLabel, NULL );
1019         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, endLabel );
1020         Stack_Pop(&(pparser->LabelStack)); //*****
1021         Stack_Pop(&(pparser->LabelStack)); //*****
1022         Parser_Match(pparser);
1023         Parser_Check(pparser, TOKEN_SEMICOLON );
1024         Parser_Match(pparser);
1025     }
1026     else if (Parser_Check(pparser, TOKEN_FOR ))
1027     {
1028         Parser_Match(pparser);
1029         Parser_Check(pparser, TOKEN_LPAREN );
1030         Parser_Match(pparser);
1031 
1032         //Add any initializer code
1033         Parser_Opt_expr_stmt(pparser );
1034 
1035         //Set the flag for the conditional to jump back to.
1036         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, startLabel );
1037         Stack_Push(&(pparser->LabelStack), continueLabel); //*****
1038         Stack_Push(&(pparser->LabelStack), endLabel ); //*****
1039 
1040         //Build the conditional statement
1041         if (ParserSet_First(&(pparser->theParserSet), expr, pparser->theNextToken.theType ))
1042         {
1043             Parser_Expr(pparser);
1044             Parser_AddInstructionViaLabel(pparser, Branch_FALSE, endLabel, NULL );
1045             Parser_Check(pparser, TOKEN_SEMICOLON );
1046             Parser_Match(pparser);
1047         }
1048         else if (ParserSet_Follow(&(pparser->theParserSet), opt_expr_stmt, pparser->theNextToken.theType )) {}
1049         else
1050         {
1051             Parser_Error(pparser, opt_expr_stmt );
1052         }
1053 
1054         //We need to defer adding the instructions related to the last parameter
1055         //of the for loop, so catch them.
1056         pDefInst = Parser_Defer_expr_stmt(pparser );
1057         Parser_Check(pparser, TOKEN_RPAREN );
1058         Parser_Match(pparser);
1059         Parser_Stmt(pparser );
1060 
1061         // for continue statement
1062         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, continueLabel );
1063         //Add in the deferred instructions, if there were any.
1064         if (pDefInst)
1065         {
1066             pInstruction = NULL;
1067 
1068             PFOREACH( pDefInst,
1069                       pInstruction = (Instruction *)List_Retrieve(pDefInst);
1070                       /*
1071                       //We have to assume here that the expression didn't need labels.
1072                       AddInstruction( pInstruction->m_OpCode, pInstruction->m_pToken, NULL );
1073                       */
1074                       List_InsertAfter(pparser->pIList, pInstruction, NULL);
1075                     );
1076 
1077             List_Clear(pDefInst);
1078             free(pDefInst);
1079         }
1080 
1081         //Add the jump statement
1082         Parser_AddInstructionViaLabel(pparser, JUMP, startLabel, NULL );
1083 
1084         //Add the end label.
1085         Parser_AddInstructionViaToken(pparser, NOOP, (Token *)NULL, endLabel );
1086         Stack_Pop(&(pparser->LabelStack));//**********
1087         Stack_Pop(&(pparser->LabelStack));//**********
1088     }
1089     else
1090     {
1091         Parser_Error(pparser, iter_stmt );
1092     }
1093     free(startLabel);
1094     free(endLabel);
1095     free(continueLabel);
1096 }
1097 
Parser_Opt_expr_stmt(Parser * pparser)1098 void Parser_Opt_expr_stmt(Parser *pparser )
1099 {
1100     if (ParserSet_First(&(pparser->theParserSet), expr_stmt, pparser->theNextToken.theType ))
1101     {
1102         Parser_Expr_stmt(pparser );
1103     }
1104     else if (ParserSet_Follow(&(pparser->theParserSet), opt_expr_stmt, pparser->theNextToken.theType )) {}
1105     else
1106     {
1107         Parser_Error(pparser, opt_expr_stmt );
1108     }
1109 }
1110 
Parser_Defer_expr_stmt(Parser * pparser)1111 List *Parser_Defer_expr_stmt(Parser *pparser )
1112 {
1113     List *pMainList, *pTemp; //save main list
1114     //if (ParserSet_First(&(pparser->theParserSet), expr_stmt, pparser->theNextToken.theType )){
1115     if (ParserSet_First(&(pparser->theParserSet), expr, pparser->theNextToken.theType ))
1116     {
1117         //We have to swap out instruction lists
1118         pMainList = pparser->pIList;
1119         //create a new Instruction List
1120         pparser->pIList = (List *)malloc(sizeof(List));
1121         List_Init(pparser->pIList);
1122 
1123         //Expr_stmt( );
1124         Parser_Expr(pparser);
1125 
1126         //Swap the instruction lists back and return the deferred list
1127         pTemp = pparser->pIList;
1128         pparser->pIList = pMainList;
1129 
1130         return pTemp;
1131     }
1132     else if (ParserSet_Follow(&(pparser->theParserSet), defer_expr_stmt, pparser->theNextToken.theType )) {}
1133     else
1134     {
1135         Parser_Error(pparser, defer_expr_stmt );
1136     }
1137 
1138     return NULL;
1139 }
1140 
Parser_Jump_stmt(Parser * pparser)1141 void Parser_Jump_stmt(Parser *pparser )
1142 {
1143     Label breakTarget = NULL;
1144     if (Parser_Check(pparser, TOKEN_BREAK ))
1145     {
1146         Parser_Match(pparser);
1147         Parser_Check(pparser, TOKEN_SEMICOLON );
1148         Parser_Match(pparser);
1149 
1150         breakTarget = Stack_Top(&(pparser->LabelStack));
1151         Parser_AddInstructionViaLabel(pparser, JUMP, breakTarget, NULL );
1152     }
1153     else if (Parser_Check(pparser, TOKEN_CONTINUE))
1154     {
1155         Parser_Match(pparser);
1156         Parser_Check(pparser, TOKEN_SEMICOLON );
1157         Parser_Match(pparser);
1158 
1159         //Violate the rules of a stack (treat it as a list) so we can ignore switches
1160         while(1)
1161         {
1162             List_GotoNext(&(pparser->LabelStack));
1163             breakTarget = List_Retrieve(&(pparser->LabelStack));
1164             List_GotoNext(&(pparser->LabelStack));
1165             if(breakTarget)
1166             {
1167                 break;
1168             }
1169             if(List_GetIndex(&(pparser->LabelStack)) == List_GetSize(&(pparser->LabelStack)) - 1)
1170             {
1171                 Parser_Error(pparser, jump_stmt );
1172                 break;
1173             }
1174         }
1175         Parser_AddInstructionViaLabel(pparser, JUMP, breakTarget, NULL );
1176         //Restore the list to its original state as a stack
1177         List_Reset(&(pparser->LabelStack));
1178     }
1179     else if (Parser_Check(pparser, TOKEN_RETURN ))
1180     {
1181         Parser_Match(pparser);
1182         Parser_Opt_expr(pparser );
1183         Parser_Check(pparser, TOKEN_SEMICOLON );
1184         Parser_Match(pparser);
1185 
1186         Parser_AddInstructionViaLabel(pparser, JUMPR, pparser->theRetLabel, NULL );
1187     }
1188     else
1189     {
1190         Parser_Error(pparser, jump_stmt );
1191     }
1192 }
1193 
1194 /******************************************************************************
1195 *  Expression Evaluation -- These methods translate expressions into
1196 *  appropriate instructions.
1197 ******************************************************************************/
Parser_Opt_expr(Parser * pparser)1198 void Parser_Opt_expr(Parser *pparser )
1199 {
1200     if (ParserSet_First(&(pparser->theParserSet), expr, pparser->theNextToken.theType ))
1201     {
1202         Parser_Expr(pparser );
1203     }
1204     else if (ParserSet_Follow(&(pparser->theParserSet), opt_expr, pparser->theNextToken.theType )) {}
1205     else
1206     {
1207         Parser_Error(pparser, opt_expr );
1208     }
1209 }
1210 
Parser_Expr(Parser * pparser)1211 void Parser_Expr(Parser *pparser)
1212 {
1213     if (ParserSet_First(&(pparser->theParserSet), assignment_expr, pparser->theNextToken.theType ))
1214     {
1215         Parser_Assignment_expr(pparser );
1216     }
1217     else
1218     {
1219         Parser_Error(pparser, expr );
1220     }
1221 }
1222 
Parser_Assignment_op(Parser * pparser)1223 OpCode Parser_Assignment_op(Parser *pparser )
1224 {
1225     if (Parser_Check(pparser, TOKEN_ASSIGN ))
1226     {
1227         Parser_Match(pparser);
1228         return NOOP;
1229     }
1230     else if (Parser_Check(pparser, TOKEN_MUL_ASSIGN ))
1231     {
1232         Parser_Match(pparser);
1233         return MUL;
1234     }
1235     else if (Parser_Check(pparser, TOKEN_DIV_ASSIGN ))
1236     {
1237         Parser_Match(pparser);
1238         return DIV;
1239     }
1240     else if (Parser_Check(pparser, TOKEN_ADD_ASSIGN ))
1241     {
1242         Parser_Match(pparser);
1243         return ADD;
1244     }
1245     else if (Parser_Check(pparser, TOKEN_SUB_ASSIGN ))
1246     {
1247         Parser_Match(pparser);
1248         return SUB;
1249     }
1250     else if (Parser_Check(pparser, TOKEN_MOD_ASSIGN ))
1251     {
1252         Parser_Match(pparser);
1253         return MOD;
1254     }
1255     else
1256     {
1257         Parser_Error(pparser, assignment_op );
1258     }
1259 
1260     return ERR;
1261 }
1262 
Parser_Assignment_expr(Parser * pparser)1263 void Parser_Assignment_expr(Parser *pparser )
1264 {
1265     if (ParserSet_First(&(pparser->theParserSet), cond_expr, pparser->theNextToken.theType )) //= /= += Operator, or a comma and the like (the reputation of a variable)
1266     {
1267         Parser_Cond_expr(pparser );
1268         Parser_Assignment_expr2(pparser );
1269     }
1270     else
1271     {
1272         Parser_Error(pparser, assignment_expr );
1273     }
1274 }
1275 
Parser_Assignment_expr2(Parser * pparser)1276 void Parser_Assignment_expr2(Parser *pparser )
1277 {
1278     Instruction *pInstruction;
1279     Token token;
1280     OpCode code;
1281     if (ParserSet_First(&(pparser->theParserSet), assignment_op, pparser->theNextToken.theType ))
1282     {
1283         pInstruction = (Instruction *)List_Retrieve(pparser->pIList);
1284         token = pparser->theFieldToken;
1285         pparser->theFieldToken.theType = END_OF_TOKENS;
1286 
1287         code = Parser_Assignment_op(pparser );
1288         if (code == NOOP)
1289         {
1290             List_Remove(pparser->pIList);
1291         }
1292         Parser_Cond_expr(pparser );
1293         if (code != NOOP)
1294         {
1295             Parser_AddInstructionViaToken(pparser, code, (Token *)NULL, NULL );
1296         }
1297 
1298         if (token.theType != END_OF_TOKENS)
1299         {
1300             Parser_AddInstructionViaToken(pparser, LOAD, &token, NULL );
1301             Parser_AddInstructionViaToken(pparser, FIELD, (Token *)NULL, NULL );
1302         }
1303 
1304         Parser_AddInstructionViaToken(pparser, SAVE, pInstruction->theToken, NULL );
1305         Parser_AddInstructionViaToken(pparser, LOAD, pInstruction->theToken, NULL );
1306         if (code == NOOP)
1307         {
1308             Instruction_Clear(pInstruction);
1309             free(pInstruction);
1310         }
1311         Parser_Assignment_expr2(pparser );
1312     }
1313     else if (ParserSet_Follow(&(pparser->theParserSet), assignment_expr2, pparser->theNextToken.theType ))
1314     {
1315         pparser->theFieldToken.theType = END_OF_TOKENS;
1316     }
1317     else
1318     {
1319         Parser_Error(pparser, assignment_expr2 );
1320     }
1321 }
1322 
Parser_Const_expr(Parser * pparser)1323 void Parser_Const_expr(Parser *pparser)
1324 {
1325     if (ParserSet_First(&(pparser->theParserSet), cond_expr, pparser->theNextToken.theType ))
1326     {
1327         Parser_Cond_expr(pparser );
1328     }
1329     else
1330     {
1331         Parser_Error(pparser, const_expr );
1332     }
1333 }
1334 
Parser_Cond_expr(Parser * pparser)1335 void Parser_Cond_expr(Parser *pparser )
1336 {
1337     if (ParserSet_First(&(pparser->theParserSet), log_or_expr, pparser->theNextToken.theType ))
1338     {
1339         Parser_Log_or_expr(pparser );
1340         Parser_Cond_expr2(pparser );
1341     }
1342     else
1343     {
1344         Parser_Error(pparser, cond_expr );
1345     }
1346 }
1347 
Parser_Cond_expr2(Parser * pparser)1348 void Parser_Cond_expr2(Parser *pparser )
1349 {
1350     Label falseLabel, endLabel, varName;
1351     Token var;
1352     TEXTPOS pos = {0, 0};
1353     if (Parser_Check(pparser, TOKEN_CONDITIONAL ))
1354     {
1355         falseLabel = Parser_CreateLabel(pparser);
1356         endLabel = Parser_CreateLabel(pparser);
1357         varName = Parser_CreateLabel(pparser);
1358         Token_Init(&var, TOKEN_IDENTIFIER, varName, pos, 0);
1359         Parser_AddInstructionViaToken(pparser, DATA, &var, NULL );
1360 
1361         Parser_Match(pparser);
1362         Parser_AddInstructionViaLabel(pparser, Branch_FALSE, falseLabel, NULL );
1363         Parser_Expr(pparser );
1364         Parser_AddInstructionViaToken(pparser, SAVE, &var, NULL );
1365         Parser_AddInstructionViaLabel(pparser, JUMP, endLabel, NULL );
1366         if (Parser_Check(pparser, TOKEN_COLON ))
1367         {
1368             Parser_Match(pparser);
1369             Parser_AddInstructionViaToken(pparser, NOOP, NULL, falseLabel );
1370             Parser_Cond_expr(pparser );
1371             Parser_AddInstructionViaToken(pparser, SAVE, &var, NULL );
1372             Parser_AddInstructionViaToken(pparser, NOOP, NULL, endLabel );
1373             Parser_AddInstructionViaToken(pparser, LOAD, &var, NULL );
1374         }
1375         else
1376         {
1377             Parser_Error(pparser, cond_expr2 );
1378         }
1379         free(falseLabel);
1380         free(endLabel);
1381         free(varName);
1382     }
1383     else if (ParserSet_Follow(&(pparser->theParserSet), cond_expr2, pparser->theNextToken.theType )) {}
1384     else
1385     {
1386         Parser_Error(pparser, cond_expr2 );
1387     }
1388 }
1389 
Parser_Log_or_expr(Parser * pparser)1390 void Parser_Log_or_expr(Parser *pparser )
1391 {
1392     if (ParserSet_First(&(pparser->theParserSet), log_and_expr, pparser->theNextToken.theType ))
1393     {
1394         Parser_Log_and_expr(pparser );
1395         Parser_Log_or_expr2(pparser );
1396     }
1397     else
1398     {
1399         Parser_Error(pparser, log_or_expr );
1400     }
1401 }
1402 
Parser_Log_or_expr2(Parser * pparser)1403 void Parser_Log_or_expr2(Parser *pparser )
1404 {
1405     if (Parser_Check(pparser, TOKEN_OR_OP ))
1406     {
1407         Parser_Match(pparser);
1408         Parser_Log_and_expr(pparser );
1409         Parser_AddInstructionViaToken(pparser, OR, (Token *)NULL, NULL );
1410         Parser_Log_or_expr2(pparser );
1411     }
1412     else if (ParserSet_Follow(&(pparser->theParserSet), log_or_expr2, pparser->theNextToken.theType )) {}
1413     else
1414     {
1415         Parser_Error(pparser, log_or_expr2 );
1416     }
1417 }
1418 
Parser_Log_and_expr(Parser * pparser)1419 void Parser_Log_and_expr(Parser *pparser )
1420 {
1421     if (ParserSet_First(&(pparser->theParserSet), bit_or_expr, pparser->theNextToken.theType ))
1422     {
1423         Parser_Bit_or_expr(pparser );
1424         Parser_Log_and_expr2(pparser );
1425     }
1426     else
1427     {
1428         Parser_Error(pparser, log_and_expr );
1429     }
1430 }
1431 
Parser_Log_and_expr2(Parser * pparser)1432 void Parser_Log_and_expr2(Parser *pparser )
1433 {
1434     if (Parser_Check(pparser, TOKEN_AND_OP ))
1435     {
1436         Parser_Match(pparser);
1437         Parser_Bit_or_expr(pparser );
1438         Parser_AddInstructionViaToken(pparser, AND, (Token *)NULL, NULL );
1439         Parser_Log_and_expr2( pparser);
1440     }
1441     else if (ParserSet_Follow(&(pparser->theParserSet), log_and_expr2, pparser->theNextToken.theType )) {}
1442     else
1443     {
1444         Parser_Error(pparser, log_and_expr2 );
1445     }
1446 }
1447 
Parser_Bit_or_expr(Parser * pparser)1448 void Parser_Bit_or_expr(Parser *pparser )
1449 {
1450     if (ParserSet_First(&(pparser->theParserSet), xor_expr, pparser->theNextToken.theType ))
1451     {
1452         Parser_Xor_expr(pparser );
1453         Parser_Bit_or_expr2(pparser );
1454     }
1455     else
1456     {
1457         Parser_Error(pparser, bit_or_expr );
1458     }
1459 }
1460 
Parser_Bit_or_expr2(Parser * pparser)1461 void Parser_Bit_or_expr2(Parser *pparser )
1462 {
1463     if (Parser_Check(pparser, TOKEN_BITWISE_OR ))
1464     {
1465         Parser_Match(pparser);
1466         Parser_Xor_expr(pparser );
1467         Parser_AddInstructionViaToken(pparser, BIT_OR, (Token *)NULL, NULL );
1468         Parser_Bit_or_expr2( pparser);
1469     }
1470     else if (ParserSet_Follow(&(pparser->theParserSet), bit_or_expr2, pparser->theNextToken.theType )) {}
1471     else
1472     {
1473         Parser_Error(pparser, bit_or_expr2 );
1474     }
1475 }
1476 
Parser_Xor_expr(Parser * pparser)1477 void Parser_Xor_expr(Parser *pparser )
1478 {
1479     if (ParserSet_First(&(pparser->theParserSet), bit_and_expr, pparser->theNextToken.theType ))
1480     {
1481         Parser_Bit_and_expr(pparser );
1482         Parser_Xor_expr2(pparser );
1483     }
1484     else
1485     {
1486         Parser_Error(pparser, xor_expr );
1487     }
1488 }
1489 
Parser_Xor_expr2(Parser * pparser)1490 void Parser_Xor_expr2(Parser *pparser )
1491 {
1492     if (Parser_Check(pparser, TOKEN_XOR ))
1493     {
1494         Parser_Match(pparser);
1495         Parser_Bit_and_expr(pparser );
1496         Parser_AddInstructionViaToken(pparser, XOR, (Token *)NULL, NULL );
1497         Parser_Xor_expr2( pparser);
1498     }
1499     else if (ParserSet_Follow(&(pparser->theParserSet), xor_expr2, pparser->theNextToken.theType )) {}
1500     else
1501     {
1502         Parser_Error(pparser, xor_expr2 );
1503     }
1504 }
1505 
Parser_Bit_and_expr(Parser * pparser)1506 void Parser_Bit_and_expr(Parser *pparser )
1507 {
1508     if (ParserSet_First(&(pparser->theParserSet), equal_expr, pparser->theNextToken.theType ))
1509     {
1510         Parser_Equal_expr(pparser );
1511         Parser_Bit_and_expr2(pparser );
1512     }
1513     else
1514     {
1515         Parser_Error(pparser, bit_and_expr );
1516     }
1517 }
1518 
Parser_Bit_and_expr2(Parser * pparser)1519 void Parser_Bit_and_expr2(Parser *pparser )
1520 {
1521     if (Parser_Check(pparser, TOKEN_BITWISE_AND ))
1522     {
1523         Parser_Match(pparser);
1524         Parser_Equal_expr(pparser );
1525         Parser_AddInstructionViaToken(pparser, BIT_AND, (Token *)NULL, NULL );
1526         Parser_Bit_and_expr2( pparser);
1527     }
1528     else if (ParserSet_Follow(&(pparser->theParserSet), bit_and_expr2, pparser->theNextToken.theType )) {}
1529     else
1530     {
1531         Parser_Error(pparser, bit_and_expr2 );
1532     }
1533 }
1534 
Parser_Eq_op(Parser * pparser)1535 OpCode Parser_Eq_op(Parser *pparser )
1536 {
1537     if (Parser_Check(pparser, TOKEN_EQ_OP ))
1538     {
1539         Parser_Match(pparser);
1540         return EQ;
1541     }
1542     else if (Parser_Check(pparser, TOKEN_NE_OP ))
1543     {
1544         Parser_Match(pparser);
1545         return NE;
1546     }
1547     else
1548     {
1549         Parser_Error(pparser, eq_op );
1550     }
1551 
1552     return ERR;
1553 }
1554 
Parser_Equal_expr(Parser * pparser)1555 void Parser_Equal_expr(Parser *pparser )
1556 {
1557     if (ParserSet_First(&(pparser->theParserSet), rel_expr, pparser->theNextToken.theType ))
1558     {
1559         Parser_Rel_expr(pparser );
1560         Parser_Equal_expr2(pparser );
1561     }
1562     else
1563     {
1564         Parser_Error(pparser, equal_expr );
1565     }
1566 }
1567 
Parser_Equal_expr2(Parser * pparser)1568 void Parser_Equal_expr2(Parser *pparser )
1569 {
1570     OpCode code;
1571     if (ParserSet_First(&(pparser->theParserSet), eq_op, pparser->theNextToken.theType ))
1572     {
1573         code = Parser_Eq_op(pparser );
1574         Parser_Rel_expr(pparser );
1575         Parser_AddInstructionViaToken(pparser, code, (Token *)NULL, NULL );
1576         Parser_Equal_expr2(pparser );
1577     }
1578     else if (ParserSet_Follow(&(pparser->theParserSet), equal_expr2, pparser->theNextToken.theType )) {}
1579     else
1580     {
1581         Parser_Error(pparser, equal_expr2 );
1582     }
1583 }
1584 
Parser_Rel_op(Parser * pparser)1585 OpCode Parser_Rel_op(Parser *pparser )
1586 {
1587     if (Parser_Check(pparser, TOKEN_GE_OP ))
1588     {
1589         Parser_Match(pparser);
1590         return GE;
1591     }
1592     else if (Parser_Check(pparser, TOKEN_LE_OP ))
1593     {
1594         Parser_Match(pparser);
1595         return LE;
1596     }
1597     else if (Parser_Check(pparser, TOKEN_LT ))
1598     {
1599         Parser_Match(pparser);
1600         return LT;
1601     }
1602     else if (Parser_Check(pparser, TOKEN_GT ))
1603     {
1604         Parser_Match(pparser);
1605         return GT;
1606     }
1607     else
1608     {
1609         Parser_Error(pparser, rel_op );
1610     }
1611 
1612     return ERR;
1613 }
1614 
Parser_Rel_expr(Parser * pparser)1615 void Parser_Rel_expr(Parser *pparser )
1616 {
1617     if (ParserSet_First(&(pparser->theParserSet), shift_expr, pparser->theNextToken.theType ))
1618     {
1619         Parser_Shift_expr(pparser );
1620         Parser_Rel_expr2(pparser );
1621     }
1622     else
1623     {
1624         Parser_Error(pparser, rel_expr );
1625     }
1626 }
1627 
Parser_Rel_expr2(Parser * pparser)1628 void Parser_Rel_expr2(Parser *pparser )
1629 {
1630     OpCode code;
1631     if (ParserSet_First(&(pparser->theParserSet), rel_op, pparser->theNextToken.theType ))
1632     {
1633         code = Parser_Rel_op(pparser );
1634         Parser_Shift_expr(pparser );
1635         Parser_AddInstructionViaToken(pparser, code, (Token *)NULL, NULL );
1636         Parser_Rel_expr2(pparser );
1637     }
1638     else if (ParserSet_Follow(&(pparser->theParserSet), rel_expr2, pparser->theNextToken.theType )) {}
1639     else
1640     {
1641         Parser_Error(pparser, rel_expr2 );
1642     }
1643 }
1644 
Parser_Shift_op(Parser * pparser)1645 OpCode Parser_Shift_op(Parser *pparser )
1646 {
1647     if (Parser_Check(pparser, TOKEN_LEFT_OP ))
1648     {
1649         Parser_Match(pparser);
1650         return SHL;
1651     }
1652     else if (Parser_Check(pparser, TOKEN_RIGHT_OP ))
1653     {
1654         Parser_Match(pparser);
1655         return SHR;
1656     }
1657     else
1658     {
1659         Parser_Error(pparser, shift_op );
1660     }
1661 
1662     return ERR;
1663 }
1664 
Parser_Shift_expr(Parser * pparser)1665 void Parser_Shift_expr(Parser *pparser )
1666 {
1667     if (ParserSet_First(&(pparser->theParserSet), add_expr, pparser->theNextToken.theType ))
1668     {
1669         Parser_Add_expr(pparser );
1670         Parser_Shift_expr2(pparser );
1671     }
1672     else
1673     {
1674         Parser_Error(pparser, shift_expr );
1675     }
1676 }
1677 
Parser_Shift_expr2(Parser * pparser)1678 void Parser_Shift_expr2(Parser *pparser )
1679 {
1680     OpCode code;
1681     if (ParserSet_First(&(pparser->theParserSet), shift_op, pparser->theNextToken.theType ))
1682     {
1683         code = Parser_Shift_op(pparser );
1684         Parser_Add_expr(pparser );
1685         Parser_AddInstructionViaToken(pparser, code, (Token *)NULL, NULL );
1686         Parser_Shift_expr2(pparser );
1687     }
1688     else if (ParserSet_Follow(&(pparser->theParserSet), shift_expr2, pparser->theNextToken.theType )) {}
1689     else
1690     {
1691         Parser_Error(pparser, shift_expr2 );
1692     }
1693 }
1694 
Parser_Add_op(Parser * pparser)1695 OpCode Parser_Add_op(Parser *pparser )
1696 {
1697     if (Parser_Check(pparser, TOKEN_ADD ))
1698     {
1699         Parser_Match(pparser);
1700         return ADD;
1701     }
1702     else if (Parser_Check(pparser, TOKEN_SUB ))
1703     {
1704         Parser_Match(pparser);
1705         return SUB;
1706     }
1707     else
1708     {
1709         Parser_Error(pparser, add_op );
1710     }
1711 
1712     return ERR;
1713 }
1714 
Parser_Add_expr(Parser * pparser)1715 void Parser_Add_expr(Parser *pparser )
1716 {
1717     if (ParserSet_First(&(pparser->theParserSet), mult_expr, pparser->theNextToken.theType ))
1718     {
1719         Parser_Mult_expr(pparser );
1720         Parser_Add_expr2(pparser );
1721     }
1722     else
1723     {
1724         Parser_Error(pparser, add_expr );
1725     }
1726 }
1727 
Parser_Add_expr2(Parser * pparser)1728 void Parser_Add_expr2(Parser *pparser )
1729 {
1730     OpCode code;
1731     if (ParserSet_First(&(pparser->theParserSet), add_op, pparser->theNextToken.theType ))
1732     {
1733         code = Parser_Add_op(pparser );
1734         Parser_Mult_expr(pparser );
1735         Parser_AddInstructionViaToken(pparser, code, (Token *)NULL, NULL );
1736         Parser_Add_expr2(pparser );
1737     }
1738     else if (ParserSet_Follow(&(pparser->theParserSet), add_expr2, pparser->theNextToken.theType )) {}
1739     else
1740     {
1741         Parser_Error(pparser, add_expr2 );
1742     }
1743 }
1744 
Parser_Mult_op(Parser * pparser)1745 OpCode Parser_Mult_op(Parser *pparser )
1746 {
1747     if (Parser_Check(pparser, TOKEN_MUL ))
1748     {
1749         Parser_Match(pparser);
1750         return MUL;
1751     }
1752     else if (Parser_Check(pparser, TOKEN_DIV ))
1753     {
1754         Parser_Match(pparser);
1755         return DIV;
1756     }
1757     else if (Parser_Check(pparser, TOKEN_MOD ))
1758     {
1759         Parser_Match(pparser);
1760         return MOD;
1761     }
1762 
1763 
1764 
1765     else
1766     {
1767         Parser_Error(pparser, mult_op );
1768     }
1769 
1770     return ERR;
1771 }
1772 
Parser_Mult_expr(Parser * pparser)1773 void Parser_Mult_expr(Parser *pparser )
1774 {
1775     if (ParserSet_First(&(pparser->theParserSet), unary_expr, pparser->theNextToken.theType ))
1776     {
1777         Parser_Unary_expr(pparser);
1778         Parser_Mult_expr2(pparser );
1779     }
1780     else
1781     {
1782         Parser_Error(pparser, mult_expr );
1783     }
1784 }
1785 
Parser_Mult_expr2(Parser * pparser)1786 void Parser_Mult_expr2(Parser *pparser )
1787 {
1788     OpCode code;
1789     if (ParserSet_First(&(pparser->theParserSet), mult_op, pparser->theNextToken.theType ))
1790     {
1791         code = Parser_Mult_op(pparser );
1792         Parser_Unary_expr(pparser );
1793         Parser_AddInstructionViaToken(pparser, code, (Token *)NULL, NULL );
1794         Parser_Mult_expr2(pparser );
1795     }
1796     else if (ParserSet_Follow(&(pparser->theParserSet), mult_expr2, pparser->theNextToken.theType )) {}
1797     else
1798     {
1799         Parser_Error(pparser, mult_expr2 );
1800     }
1801 }
1802 
Parser_Unary_expr(Parser * pparser)1803 void Parser_Unary_expr(Parser *pparser )
1804 {
1805     static CHAR buf[MAX_TOKEN_LENGTH + 2];
1806     Instruction *pInstruction = NULL;
1807 
1808     if (ParserSet_First(&(pparser->theParserSet), postfix_expr, pparser->theNextToken.theType ))
1809     {
1810         Parser_Postfix_expr(pparser );
1811     }
1812     else if (Parser_Check(pparser, TOKEN_INC_OP ))
1813     {
1814         Parser_Match(pparser);
1815         Parser_Unary_expr(pparser );
1816         pInstruction = (Instruction *)List_Retrieve(pparser->pIList);
1817         Parser_AddInstructionViaToken(pparser, INC, (Token *)NULL, NULL );
1818         Parser_AddInstructionViaToken(pparser, SAVE, pInstruction->theToken, NULL );
1819         Parser_AddInstructionViaToken(pparser, LOAD, pInstruction->theToken, NULL );
1820     }
1821     else if (Parser_Check(pparser, TOKEN_DEC_OP ))
1822     {
1823         Parser_Match(pparser);
1824         Parser_Unary_expr( pparser);
1825         pInstruction = (Instruction *)List_Retrieve(pparser->pIList);
1826         Parser_AddInstructionViaToken(pparser, DEC, (Token *)NULL, NULL );
1827         Parser_AddInstructionViaToken(pparser, SAVE, pInstruction->theToken, NULL );
1828         Parser_AddInstructionViaToken(pparser, LOAD, pInstruction->theToken, NULL );
1829     }
1830     else if (Parser_Check(pparser, TOKEN_ADD ))
1831     {
1832         Parser_Match(pparser);
1833         Parser_Unary_expr( pparser);
1834     }
1835     else if (Parser_Check(pparser, TOKEN_SUB ))
1836     {
1837         Parser_Match(pparser);
1838         Parser_Unary_expr(pparser );
1839         pInstruction = (Instruction *)List_Retrieve(pparser->pIList);
1840         if(pInstruction->OpCode == CONSTINT ||
1841                 pInstruction->OpCode == CONSTDBL )
1842         {
1843             //convert to negative constant
1844             sprintf(buf, "-%s", pInstruction->theToken->theSource);
1845             strcpy(pInstruction->theToken->theSource, buf);
1846         }
1847         else if(pInstruction->OpCode == CONSTSTR)
1848         {
1849             //string constant should not be valid , drop it anyway
1850             Parser_Error(pparser, unary_expr );
1851         }
1852         else
1853         {
1854             Parser_AddInstructionViaToken(pparser, NEG, (Token *)NULL, NULL );
1855         }
1856     }
1857     else if (Parser_Check(pparser, TOKEN_BOOLEAN_NOT ))
1858     {
1859         Parser_Match(pparser);
1860         Parser_Unary_expr(pparser );
1861         pInstruction = (Instruction *)List_Retrieve(pparser->pIList);
1862         if(pInstruction->OpCode == CONSTINT ||
1863                 pInstruction->OpCode == CONSTDBL ||
1864                 pInstruction->OpCode == CONSTSTR)
1865         {
1866             //convert to negative constant
1867             sprintf(buf, "!%s", pInstruction->theToken->theSource);
1868             strcpy(pInstruction->theToken->theSource, buf);
1869         }
1870         else
1871         {
1872             Parser_AddInstructionViaToken(pparser, NOT, (Token *)NULL, NULL );
1873         }
1874     }
1875     else
1876     {
1877         Parser_Error(pparser, unary_expr );
1878     }
1879 }
1880 
Parser_Postfix_expr(Parser * pparser)1881 void Parser_Postfix_expr(Parser *pparser )
1882 {
1883     if (ParserSet_First(&(pparser->theParserSet), primary_expr, pparser->theNextToken.theType ))
1884     {
1885         Parser_Primary_expr(pparser );
1886         Parser_Postfix_expr2(pparser );
1887     }
1888     else
1889     {
1890         Parser_Error(pparser, postfix_expr );
1891     }
1892 }
1893 
Parser_Postfix_expr2(Parser * pparser)1894 void Parser_Postfix_expr2(Parser *pparser )
1895 {
1896     Instruction *pInstruction, *plast;
1897     Label label;
1898     if (Parser_Check(pparser, TOKEN_LPAREN ))
1899     {
1900         //Remove the top instruction so we can get the arguments in first.
1901         pInstruction = (Instruction *)List_Retrieve(pparser->pIList);
1902         plast = (Instruction *)List_GetLast(pparser->pIList);
1903         List_Remove(pparser->pIList);
1904         if(plast != pInstruction)
1905         {
1906             List_GotoPrevious(pparser->pIList);    //walk back, because the list's current node will move if it is the last one
1907         }
1908 
1909         Parser_Match(pparser);
1910         Parser_Arg_expr_list( pparser);
1911         Parser_Check(pparser, TOKEN_RPAREN );
1912         Parser_Match(pparser);
1913 
1914         //Change the type of the instruction we removed from LOAD to CALL, create
1915         //a label for it, and add it back to the instruction list.
1916         label = Parser_CreateLabel(pparser);
1917         pInstruction->OpCode = CALL;
1918         List_InsertAfter(pparser->pIList, pInstruction, label );
1919         //dont forget to free the label
1920         free(label);
1921 
1922         Parser_Postfix_expr2(pparser );
1923     }
1924     else if (Parser_Check(pparser, TOKEN_FIELD ))
1925     {
1926         //cache the token of the field source for assignment expressions.
1927         pInstruction = (Instruction *)List_Retrieve(pparser->pIList);
1928         pparser->theFieldToken = *(pInstruction->theToken);
1929 
1930         Parser_AddInstructionViaToken(pparser, FIELD, &(pparser->theNextToken), NULL );
1931         Parser_Match(pparser);
1932         Parser_Check(pparser, TOKEN_IDENTIFIER );
1933         Parser_AddInstructionViaToken(pparser, LOAD, &(pparser->theNextToken), NULL );
1934         Parser_Match(pparser);
1935         Parser_Postfix_expr2(pparser );
1936     }
1937     else if (Parser_Check(pparser, TOKEN_INC_OP ))
1938     {
1939         pInstruction = (Instruction *)List_Retrieve(pparser->pIList);
1940         Parser_AddInstructionViaToken(pparser, LOAD, pInstruction->theToken, NULL );
1941         Parser_AddInstructionViaToken(pparser, INC, &(pparser->theNextToken), NULL );
1942         Parser_Match(pparser);
1943         Parser_AddInstructionViaToken(pparser, SAVE, pInstruction->theToken, NULL );
1944         Parser_Postfix_expr2(pparser );
1945     }
1946     else if (Parser_Check(pparser, TOKEN_DEC_OP ))
1947     {
1948         pInstruction = (Instruction *)List_Retrieve(pparser->pIList);
1949         Parser_AddInstructionViaToken(pparser, LOAD, pInstruction->theToken, NULL );
1950         Parser_AddInstructionViaToken(pparser, DEC, &(pparser->theNextToken), NULL );
1951         Parser_Match(pparser);
1952         Parser_AddInstructionViaToken(pparser, SAVE, pInstruction->theToken, NULL );
1953         Parser_Postfix_expr2(pparser );
1954     }
1955     else if (ParserSet_Follow(&(pparser->theParserSet), postfix_expr2, pparser->theNextToken.theType )) {}
1956     else
1957     {
1958         Parser_Error(pparser, postfix_expr2 );
1959     }
1960 }
1961 
Parser_Arg_expr_list(Parser * pparser)1962 void Parser_Arg_expr_list(Parser *pparser )
1963 {
1964     int argRange, i;
1965     if (ParserSet_First(&(pparser->theParserSet), assignment_expr, pparser->theNextToken.theType ))
1966     {
1967         argRange = List_GetSize(pparser->pIList);
1968         Parser_Assignment_expr(pparser );
1969         argRange = List_GetSize(pparser->pIList) - argRange;
1970         for (i = 1; i < argRange; i++)
1971         {
1972             List_GotoPrevious(pparser->pIList);
1973         }
1974         Parser_Arg_expr_list2(pparser, 1, argRange);
1975     }
1976     else if (ParserSet_Follow(&(pparser->theParserSet), arg_expr_list, pparser->theNextToken.theType ))
1977     {
1978         //No arguments, so push a zero argument count onto the stack
1979         Parser_AddInstructionViaLabel(pparser, CONSTINT, "0", NULL );
1980     }
1981     else
1982     {
1983         Parser_Error(pparser, arg_expr_list );
1984     }
1985 }
1986 
Parser_Arg_expr_list2(Parser * pparser,int argCount,int range)1987 void Parser_Arg_expr_list2(Parser *pparser, int argCount, int range)
1988 {
1989     //This is going to get us in trouble if we have function calls as arguments.
1990     //static int argCount = 1;
1991 
1992     //We push the arguments onto the stack backwards so they come off right,
1993     //So back up one instruction before inserting.
1994     int argRange, i;
1995     CHAR buffer[4];
1996     List_GotoPrevious(pparser->pIList);
1997 
1998     if (Parser_Check(pparser, TOKEN_COMMA ))
1999     {
2000         Parser_Match(pparser);
2001         argRange = List_GetSize(pparser->pIList);
2002         Parser_Assignment_expr(pparser );
2003         argRange = List_GetSize(pparser->pIList) - argRange;
2004         argCount++;
2005         for (i = 1; i < argRange; i++)
2006         {
2007             List_GotoPrevious(pparser->pIList);
2008         }
2009         range += argRange;
2010         //if( m_pIList->Last()->m_OpCode == CALL) range++;
2011         Parser_Arg_expr_list2(pparser, argCount, range );
2012     }
2013     else if (ParserSet_Follow(&(pparser->theParserSet), arg_expr_list2, pparser->theNextToken.theType ))
2014     {
2015         //Run back down the list to insert the argument count
2016         for (i = 0; i < range; i++)
2017         {
2018             List_GotoNext(pparser->pIList);
2019         }
2020 
2021         sprintf( buffer, "%d", argCount );
2022         Parser_AddInstructionViaLabel(pparser, CONSTINT, buffer, NULL );
2023     }
2024     else
2025     {
2026         Parser_Error(pparser, arg_expr_list2 );
2027     }
2028 }
2029 
Parser_Primary_expr(Parser * pparser)2030 void Parser_Primary_expr(Parser *pparser )
2031 {
2032     if (Parser_Check(pparser, TOKEN_IDENTIFIER ))
2033     {
2034         Parser_AddInstructionViaToken(pparser, LOAD, &(pparser->theNextToken), NULL );
2035         Parser_Match(pparser);
2036     }
2037     else if (ParserSet_First(&(pparser->theParserSet), constant, pparser->theNextToken.theType ))
2038     {
2039         Parser_Constant(pparser);
2040     }
2041     else if (Parser_Check(pparser, TOKEN_LPAREN ))
2042     {
2043         Parser_Match(pparser);
2044         Parser_Expr(pparser );
2045         Parser_Check(pparser, TOKEN_RPAREN );
2046         Parser_Match(pparser);
2047     }
2048     else
2049     {
2050         Parser_Error(pparser, primary_expr );
2051     }
2052 }
2053 
Parser_Constant(Parser * pparser)2054 void Parser_Constant(Parser *pparser )
2055 {
2056     if (Parser_Check(pparser, TOKEN_INTCONSTANT ) || Parser_Check(pparser, TOKEN_HEXCONSTANT ))
2057     {
2058         Parser_AddInstructionViaToken(pparser, CONSTINT, &(pparser->theNextToken), NULL );
2059         Parser_Match(pparser);
2060     }
2061     else if (Parser_Check(pparser, TOKEN_FLOATCONSTANT ))
2062     {
2063         Parser_AddInstructionViaToken(pparser, CONSTDBL, &(pparser->theNextToken), NULL );
2064         Parser_Match(pparser);
2065     }
2066     else if (Parser_Check(pparser, TOKEN_STRING_LITERAL ))
2067     {
2068         Parser_AddInstructionViaToken(pparser, CONSTSTR, &(pparser->theNextToken), NULL );
2069         Parser_Match(pparser);
2070     }
2071     else
2072     {
2073         Parser_Error(pparser, constant );
2074     }
2075 }
2076 
_production_error_message(Parser * pparser,PRODUCTION offender)2077 const char  *_production_error_message(Parser *pparser, PRODUCTION offender)
2078 {
2079     switch(offender)
2080     {
2081     case constant:
2082         return "Invalid constant format";
2083     case start:
2084         return "Invalid start of declaration";
2085     case case_label:
2086         return "Case label must be an integer or string constant";
2087     case postfix_expr2:
2088         return "Invalid function call or expression";
2089     case funcDecl1:
2090         return "Parameters or ')' expected after function declaration";
2091     case external_decl:
2092         return "Invalid external declaration";
2093     case decl_spec:
2094         return "Invalid identifier";
2095     case decl:
2096         return "Invalid declaration(expected comma, semicolon or initializer?)";
2097     default:
2098         return "Unknown error";
2099     }
2100 }
2101 
2102 
Parser_Error2(Parser * pparser,PRODUCTION offender,const char * offenderStr)2103 void Parser_Error2(Parser *pparser, PRODUCTION offender, const char *offenderStr )
2104 {
2105     //Report the offending token to the error handler, along with the production
2106     //it offended in.
2107     if (offender != error)
2108         pp_error(&(pparser->theLexer.preprocessor), "%s '%s' (in production '%s')",
2109                  _production_error_message(pparser, offender), pparser->theNextToken.theSource, offenderStr);
2110 
2111     pparser->errorFound = TRUE;
2112 
2113     //The script is obviously not valid, but it's good to try and find all the
2114     //errors at one time.  Therefore go into Panic Mode error recovery -- keep
2115     //grabbing tokens until we find one we can use
2116     do
2117     {
2118         while (!SUCCEEDED(Lexer_GetNextToken(&(pparser->theLexer), &(pparser->theNextToken))));
2119         if (pparser->theNextToken.theType == TOKEN_EOF)
2120         {
2121             break;
2122         }
2123     }
2124     while (!ParserSet_Follow(&(pparser->theParserSet), offender, pparser->theNextToken.theType));
2125 }
2126