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