root/as2/E3Engine/Parser.as

リビジョン 482, 64.6 kB (コミッタ: yossy, コミット時期: 4 年 前)

E3Engine: Parser の CallExpression? 解析がおかしかったの修正

Line 
1 class Parser implements IParser
2 {
3         private var scanner:IScanner;
4         private var generator:CodeGenerator;
5        
6         private var token:Token;
7        
8         public function Parser (scanner:IScanner)
9         {
10                 this.scanner = scanner;
11         }
12        
13         private function getToken () : Token
14         {
15                 return token;
16         }
17         private function nextToken () : Token
18         {
19                 return (token = scanner.getToken());
20         }
21         private function isToken (type:String) : Boolean
22         {
23                 return (token.type == type);
24         }
25         private function isNextToken (type:String) : Boolean
26         {
27                 return (nextToken().type == type);
28         }
29        
30         private function initialize () : Void
31         {
32                 scanner.rewind();
33                 generator = new CodeGenerator();
34                 breakLabelList = new Array();
35                 continueLabelList = new Array();
36                 functionStack = new Array();
37                 nextToken();
38         }
39        
40         public function parse () : Array
41         {
42                 initialize();
43                
44                 parse_program();
45                
46                 return generator.getCode();
47         }
48        
49         private function syntaxError (message:String) : Void
50         {
51                 throw new SyntaxError('Parser [SyntaxError] on line'+scanner.getLineNumber()+' '+message+' ('+getToken().type+')'+newline+scanner.getLine());
52         }
53        
54         private var breakLabelList:Array;
55         private function pushBreakLabel (label:Label) : Void
56         {
57                 breakLabelList.unshift(label);
58         }
59         private function popBreakLabel () : Label
60         {
61                 return Label(breakLabelList.shift());
62         }
63         private function getBreakLabel () : Label
64         {
65                 if (breakLabelList.length < 1) {
66                         syntaxError('その位置でbreakは使用できません');
67                 }
68                 return breakLabelList[0];
69         }
70         private var continueLabelList:Array;
71         private function pushContinueLabel (label:Label) : Void
72         {
73                 continueLabelList.unshift(label);
74         }
75         private function popContinueLabel () : Label
76         {
77                 return Label(continueLabelList.shift());
78         }
79         private function getContinueLabel () : Label
80         {
81                 if (continueLabelList.length < 1) {
82                         syntaxError('その位置でcontinueは使用できません');
83                 }
84                 return continueLabelList[0];
85         }
86        
87         private var functionStack:Array;
88         private function beginFunction () : Void
89         {
90                 functionStack.unshift(true);
91         }
92         private function endFunction () : Void
93         {
94                 functionStack.shift();
95         }
96         private function beginCoroutine () : Void
97         {
98                 functionStack.unshift(false);
99         }
100         private function endCoroutine () : Void
101         {
102                 functionStack.shift();
103         }
104         private function isAllowReturn () : Boolean
105         {
106                 return functionStack.length > 0;
107         }
108         private function isInFunction () : Boolean
109         {
110                 return (functionStack.length > 0 && functionStack[0]);
111         }
112        
113         // ContinueStatementから
114        
115         // Program ::= SourceElements
116         //
117         // First(Program) ::= First(SourceElements)
118         // Follow(Program) ::= EOF
119         private function parse_program () : Void
120         {
121                 parse_sourceElements();
122         }
123        
124         // SourceElements ::= SourceElement
125         //      ::= SourceElements SourceElement
126         //
127         // First(SourceElements) ::= First(SourceElement)
128         private function parse_sourceElements () : Void
129         {
130                 parse_sourceElement();
131                
132                 // ここを常に回すようにしておかないと、コード中に予期しないトークンが
133                 // 出現したときにエラーを出せない
134                 // while (isStatementFirst(getToken().type) || isToken('function')) {
135                 while (getToken() != null) {
136                         // Follow from FunctionBody
137                         if (isToken('}')) {
138                                 return;
139                         }
140                        
141                         parse_sourceElement();
142                 }
143         }
144        
145         // SourceElement ::= Statement
146         //      ::= FunctionDeclaration
147         //      ::= CorutineDeclaration (original)
148         //
149         // First(SourceElement) ::= First(Statement) First(FunctionDeclaration) First(CorutineDeclaration)
150         private function parse_sourceElement () : Void
151         {
152                 if (isToken('function')) {
153                         parse_functionDeclaration();
154                 }
155                 else if (isToken('coroutine')) {
156                         parse_coroutineDeclaration();
157                 }
158                 else if (isStatementFirst(getToken().type)) {
159                         parse_statement();
160                 }
161                 else {
162                         syntaxError('SourceElementに謎のトークン');
163                 }
164         }
165        
166         // FunctionDeclaration ::= 'function' Identifier '(' FormalParameterList? ')' '{' FunctionBody '}'
167         //
168         // First(FunctionDeclaration) ::= 'function'
169         private function parse_functionDeclaration () : Void
170         {
171                 if (!isToken('function')) {
172                         syntaxError('関数宣言なのに"function"が無い??');
173                 }
174                
175                 if (!isNextToken('identifier')) {
176                         syntaxError('関数宣言に関数名が無い');
177                 }
178                
179                 var funcName:String = String(getToken().value);
180                
181                 var label:Label = generator.putFunction();
182                
183                 beginFunction();
184                
185                 generator.beginNewScope();
186                
187                 if (!isNextToken('(')) {
188                         syntaxError('関数宣言で"("を忘れている');
189                 }
190                
191                 if (isNextToken('identifier')) {
192                         parse_formalParameterList();
193                 }
194                
195                 if (!isToken(')')) {
196                         syntaxError('関数宣言で")"を忘れている');
197                 }
198                
199                 if (!isNextToken('{')) {
200                         syntaxError('関数宣言で"{"を忘れている');
201                 }
202                
203                 if (!isNextToken('}')) {
204                         parse_functionBody();
205                 }
206                
207                 if (!hasLastReturn) {
208                         generator.putReturnFunction(ExpressionResult.createLiteral(undefined));
209                 }
210                
211                 if (!isToken('}')) {
212                         syntaxError('関数宣言で"}"を忘れている');
213                 }
214                
215                 endFunction();
216                
217                 generator.closeScope();
218                
219                 generator.setLabel(label);
220                
221                 generator.putSetLocalVariable(funcName, ExpressionResult.createStack());
222                 generator.popAndDestroyStack();
223                
224                 nextToken();
225         }
226        
227         // FunctionExpression ::= 'function' Identifier? '(' FormalParamaterList? ')' '{' FunctionBody '}'
228         //
229         // First(FunctionExpression) ::= 'function'
230         private function parse_functionExpression (expressionResult:ExpressionResult) : Void
231         {
232                 if (!isToken('function')) {
233                         syntaxError('関数宣言なのに"function"が無い??');
234                 }
235                
236                 var funcName:String = null;
237                
238                 if (isNextToken('identifier')) {
239                         funcName = String(getToken().value);
240                         nextToken();
241                 }
242                
243                 var label:Label = generator.putFunction();
244                
245                 beginFunction();
246                
247                 generator.beginNewScope();
248                
249                 if (!isToken('(')) {
250                         syntaxError('関数宣言で"("を忘れている');
251                 }
252                
253                 if (isNextToken('identifier')) {
254                         parse_formalParameterList();
255                 }
256                
257                 if (!isToken(')')) {
258                         syntaxError('関数宣言で")"を忘れている');
259                 }
260                
261                 if (!isNextToken('{')) {
262                         syntaxError('関数宣言で"{"を忘れている');
263                 }
264                
265                 if (!isNextToken('}')) {
266                         parse_functionBody();
267                 }
268                
269                 if (!hasLastReturn) {
270                         generator.putReturnFunction(ExpressionResult.createLiteral(undefined));
271                 }
272                
273                 if (!isToken('}')) {
274                         syntaxError('関数宣言で"}"を忘れている');
275                 }
276                
277                 generator.closeScope();
278                
279                 endFunction();
280                
281                 generator.setLabel(label);
282                
283                 if (funcName != null) {
284                         generator.putSetLocalVariable(funcName, ExpressionResult.createStack());
285                 }
286                
287                 expressionResult.setTypeStack();
288                
289                 nextToken();
290         }
291        
292         // CoroutineDeclaration ::= 'coroutine' Identifier? '(' FormalParamaterList? ')' '{' FunctionBody '}'
293         //
294         // First(CoroutineDeclaration) ::= 'coroutine'
295         private function parse_coroutineDeclaration (expressionResult:ExpressionResult) : Void
296         {
297                 if (!isToken('coroutine')) {
298                         syntaxError('コルーチン宣言なのに"coroutine"が無い??');
299                 }
300                
301                 if (!isNextToken('identifier')) {
302                         syntaxError('コルーチン宣言に関数名が無い');
303                 }
304                
305                 var funcName:String = String(getToken().value);
306                
307                 var label:Label = generator.putCoroutine();
308                
309                 beginCoroutine();
310                
311                 generator.beginNewScope();
312                
313                 if (!isNextToken('(')) {
314                         syntaxError('コルーチン宣言で"("を忘れている');
315                 }
316                
317                 if (isNextToken('identifier')) {
318                         parse_formalParameterList();
319                 }
320                
321                 if (!isToken(')')) {
322                         syntaxError('コルーチン宣言で")"を忘れている');
323                 }
324                
325                 if (!isNextToken('{')) {
326                         syntaxError('コルーチン宣言で"{"を忘れている');
327                 }
328                
329                 if (!isNextToken('}')) {
330                         parse_functionBody();
331                 }
332                
333                 if (!hasLastReturn) {
334                         generator.putReturnCoroutine(ExpressionResult.createLiteral(undefined));
335                 }
336                
337                 if (!isToken('}')) {
338                         syntaxError('コルーチン宣言で"}"を忘れている');
339                 }
340                
341                 generator.closeScope();
342                
343                 endCoroutine();
344                
345                 generator.setLabel(label);
346                
347                 generator.putSetLocalVariable(funcName, ExpressionResult.createStack());
348                 generator.popAndDestroyStack();
349                
350                 expressionResult.setTypeStack();
351                
352                 nextToken();
353         }
354        
355         // CoroutineExpression ::= 'coroutine' Identifier? '(' FormalParamaterList? ')' '{' FunctionBody '}'
356         //
357         // First(CoroutineExpression) ::= 'coroutine'
358         private function parse_coroutineExpression (expressionResult:ExpressionResult) : Void
359         {
360                 if (!isToken('coroutine')) {
361                         syntaxError('コルーチン宣言なのに"coroutine"が無い??');
362                 }
363                
364                 var funcName:String = null;
365                
366                 if (isNextToken('identifier')) {
367                         funcName = String(getToken().value);
368                         nextToken();
369                 }
370                
371                 var label:Label = generator.putCoroutine();
372                
373                 beginCoroutine();
374                
375                 generator.beginNewScope();
376                
377                 if (!isToken('(')) {
378                         syntaxError('コルーチン宣言で"("を忘れている');
379                 }
380                
381                 if (isNextToken('identifier')) {
382                         parse_formalParameterList();
383                 }
384                
385                 if (!isToken(')')) {
386                         syntaxError('コルーチン宣言で")"を忘れている');
387                 }
388                
389                 if (!isNextToken('{')) {
390                         syntaxError('コルーチン宣言で"{"を忘れている');
391                 }
392                
393                 if (!isNextToken('}')) {
394                         parse_functionBody();
395                 }
396                
397                 if (!hasLastReturn) {
398                         generator.putReturnCoroutine(ExpressionResult.createLiteral(undefined));
399                 }
400                
401                 if (!isToken('}')) {
402                         syntaxError('コルーチン宣言で"}"を忘れている');
403                 }
404                
405                 generator.closeScope();
406                
407                 endCoroutine();
408                
409                 generator.setLabel(label);
410                
411                 if (funcName != null) {
412                         generator.putSetLocalVariable(funcName, ExpressionResult.createStack());
413                 }
414                
415                 expressionResult.setTypeStack();
416                
417                 nextToken();
418         }
419        
420         // FormalParameterList ::= Identifier
421         //      ::= FormalParameterList ',' Identifier
422         //
423         // First(FormalParameterList) ::= identifier
424         private function parse_formalParameterList () : Void
425         {
426                 var argumentIndex:Number = 0;
427                
428                 for (;;) {
429                         if (!isToken('identifier')) {
430                                 syntaxError('パラメータ名が必要です');
431                         }
432                        
433                         generator.putArgument(argumentIndex, String(getToken().value));
434                        
435                         argumentIndex++;
436                        
437                         if (isNextToken(',')) {
438                                 nextToken();
439                                 continue;
440                         }
441                         break;
442                 }
443         }
444        
445         // FunctionBody ::= SourceElements
446         //
447         // First(FunctionBody) ::= First(SourceElements)
448         private function parse_functionBody () : Void
449         {
450                 parse_sourceElements();
451         }
452        
453         private var hasLastReturn:Boolean;
454        
455         // Statement ::= Block
456         //      ::= VariableStatement
457         //      ::= EmptyStatement
458         //      ::= ExpressionStatement
459         //      ::= IfStatement
460         //      ::= IterationStatement
461         //      ::= ContinueStatement
462         //      ::= BreakStatement
463         //      ::= ReturnStatement
464         //      ::= WithStatement
465         //      ::= LabelledStatement (not support)
466         //      ::= SwitchStatement
467         //      ::= SuspendStatement (original)
468         //      ::= LoopStatement (original)
469         //      ::= ThrowStatement (not support)
470         //      ::= TryStatement (not support)
471         //
472         // First(Statement) ::= ...
473         private function parse_statement () : Void
474         {
475                 hasLastReturn = false;  // for FunctionExpression, FunctionDeclaration
476                
477                 var stackBegin:Number = generator.getStackLength();
478                
479                 switch (getToken().type) {
480                         case '{':               parse_block(); break;
481                         case 'var':     parse_variableStatement(); break;
482                         case ';':               parse_emptyStatement(); break;
483                         case 'if':              parse_ifStatement(); break;
484                         case 'do':
485                         case 'while':
486                         case 'for':     parse_iterationStatement(); break;
487                         case 'continue':        parse_continueStatement(); break;
488                         case 'break':   parse_breakStatement(); break;
489                         case 'return':  parse_returnStatement(); break;
490                         case 'with':    parse_withStatement(); break;
491                         case 'switch':  parse_switchStatement(); break;
492                        
493                         case 'yield':   parse_yieldStatement(); break;
494                         case 'suspend': parse_suspendStatement(); break;
495                        
496                         case 'loop':    parse_loopStatement(); break;
497                        
498                         default:
499                         {
500                                 if (isExpressionFirst(getToken().type)) {
501                                         parse_expressionStatement();
502                                         break;
503                                 }
504                                
505                                 syntaxError('ステートメントに予期しないトークンがあります');
506                         }
507                         case 'function':
508                         {
509                                 syntaxError('ステートメント内では関数を定義できません');
510                                 break;
511                         }
512                 }
513                
514                 generator.cleanUpStack(stackBegin);
515         }
516         private function isStatementFirst (type:String) : Boolean
517         {
518                 return (type == '{' || type == 'var' || type == ';' || type == 'if' || type == 'do' ||
519                         type == 'while' || type == 'for' || type == 'for' || type == 'continue' ||
520                         type == 'break' || type == 'return' || type == 'with' || type == 'switch' ||
521                         type == 'yield' || type == 'suspend' || type == 'loop' ||
522                         (type != 'function' && type != 'coroutine' && /*type != '{' &&*/ isExpressionFirst(type))
523                         );
524         }
525        
526         // Block ::= '{' StatementList? '}'
527         //
528         // First(Block) ::= '{'
529         private function parse_block () : Void
530         {
531                 if (!isToken('{')) {
532                         syntaxError('ブロック開始で"{"が無い??');
533                 }
534                
535                 if (!isNextToken('}')) {
536                         parse_statementList();
537                 }
538                
539                 if (!isToken('}')) {
540                         syntaxError('ブロック終了の"}"を忘れている');
541                 }
542                
543                 nextToken();
544         }
545        
546         // StatementList ::= Statement
547         //      ::= StatementList Statement
548         //
549         // First(StatementList) ::= First(Statement)
550         private function parse_statementList () : Void
551         {
552                 parse_statement();
553                
554                 for (;;) {
555                         // Follow from Block, CaseClause, DefaultClause
556                         if (isToken('}')) {
557                                 return;
558                         }
559                        
560                         if (isStatementFirst(getToken().type)) {
561                                 parse_statement();
562                                 continue;
563                         }
564                         break;
565                 }
566         }
567        
568         // VariableStatement ::= 'var' VariableDeclarationList ';'
569         //
570         // First(VariableStatement) ::= 'var'
571         private function parse_variableStatement () : Void
572         {
573                 if (!isToken('var')) {
574                         syntaxError('変数宣言で"var"が無い??');
575                 }
576                
577                 nextToken();
578                
579                 parse_variableDeclarationList();
580                
581                 if (!isToken(';')) {
582                         syntaxError('変数宣言で";"を忘れている');
583                 }
584                
585                 nextToken();
586         }
587        
588         // VariableDeclarationList ::= VariableDeclaration
589         //      ::= VariableDeclarationList ',' VariableDeclaration
590         //
591         // First(VariableDeclarationList) ::= First(VariableDeclaration)
592         private function parse_variableDeclarationList () : Void
593         {
594                 parse_variableDeclaration();
595                
596                 for (;;) {
597                         if (isToken(',')) {
598                                 nextToken();
599                                 parse_variableDeclaration();
600                                 continue;
601                         }
602                         break;
603                 }
604         }
605        
606         // VariableDeclaration ::= Identifier Initialiser?
607         //
608         // First(VariableDeclaration) ::= identifier
609         private function parse_variableDeclaration () : Void
610         {
611                 if (!isToken('identifier')) {
612                         syntaxError('変数宣言で変数名が無い');
613                 }
614                
615                 var identifier:String = String(getToken().value);
616                
617                 if (isNextToken('=')) {
618                         var rightExpression:ExpressionResult  = new ExpressionResult();
619                         parse_initialiser(rightExpression);
620                         generator.putExpressionResult(rightExpression);
621                         generator.putSetLocalVariable(identifier, rightExpression);
622                         generator.popAndDestroyStack();
623                 }
624                 else {
625                         generator.putSetLocalVariable(identifier, ExpressionResult.createLiteral(undefined));
626                         generator.popAndDestroyStack();
627                 }
628         }
629        
630         // initialiser ::= '=' AssignmentExpression
631         //
632         // First(Initialiser) ::= '='
633         private function parse_initialiser (expressionResult:ExpressionResult) : Void
634         {
635                 if (!isToken('=')) {
636                         syntaxError('イニシャライザで"="が無い??');
637                 }
638                
639                 nextToken();
640                
641                 parse_assignmentExpression(expressionResult);
642         }
643        
644         // EmptyStatement ::= ';'
645         //
646         // First(EmptyStatement) ::= ';'
647         private function parse_emptyStatement () : Void
648         {
649                 if (!isToken(';')) {
650                         syntaxError('空ステートメントで";"が無い??');
651                 }
652                
653                 nextToken();
654         }
655        
656         // ExpressionStatement ::= [lookahead { '{' , 'function' } ] Expression ';'
657         //
658         // First(ExpressionStatement) ::= First(Expression)
659         private function parse_expressionStatement () : Void
660         {
661                 if (isToken('{') || isToken('function')) {
662                         syntaxError('ExpressionStatementで曖昧トークン');
663                 }
664                
665                 var expressionResult:ExpressionResult = new ExpressionResult();
666                 parse_expression(expressionResult);
667                 generator.putExpressionResult(expressionResult);
668                
669                 if (!isToken(';')) {
670                         syntaxError('式ステートメントで";"を忘れている');
671                 }
672                
673                 nextToken();
674         }
675        
676         // IfStatement ::= 'if' '(' Expression ')' Statement 'else' Statement
677         //      ::= 'if' '(' Expression ')' Statement
678         //
679         // First(IfStatement) ::= 'if'
680         private function parse_ifStatement () : Void
681         {
682                 if (!isToken('if')) {
683                         syntaxError('ifステートメントで"if"が無い??');
684                 }
685                
686                 if (!isNextToken('(')) {
687                         syntaxError('ifステートメントで"("が無い');
688                 }
689                
690                 nextToken();
691                
692                 var condition:ExpressionResult  = new ExpressionResult();
693                 parse_expression(condition);
694                
695                 if (!isToken(')')) {
696                         syntaxError('ifステートメントで")"を忘れている');
697                 }
698                
699                 generator.putExpressionResult(condition);
700                
701                 var endIfLabel:Label  = new Label();
702                
703                 generator.putIf(condition, endIfLabel);
704                
705                 nextToken();
706                
707                 parse_statement();
708                
709                 if (isToken('else')) {
710                         var endElseLabel:Label = new Label();
711                          generator.putJump(endElseLabel);
712                        
713                         generator.setLabel(endIfLabel);
714                        
715                         nextToken();
716                         parse_statement();
717                        
718                         generator.setLabel(endElseLabel);
719                 }
720                 else {
721                         generator.setLabel(endIfLabel);
722                 }
723         }
724        
725         // IterationiStatement ::= 'do' Statement 'while' '(' Expression ')'
726         //      ::= 'while' '(' Expression ')' Statement
727         //      ::= 'for' '(' Expression? ';' Expression? ':' Expression? ')' Statement
728         //      ::= 'for' '(' 'var' VariableDeclaration ';' Expression? ';' Expression? ')' Statement
729         //
730         // First(IterationStatement) ::= 'do' 'while' 'for'
731         private function parse_iterationStatement () : Void
732         {
733                 if (isToken('for')) {
734                         parse_forStatement();
735                 }
736                 else if (isToken('while')) {
737                         parse_whileStatement();
738                 }
739                 else if (isToken('do')) {
740                         parse_doStatement();
741                 }
742                 else {
743                         syntaxError('ループステートメントで謎のトークン');
744                 }
745         }
746         private function parse_forStatement () : Void
747         {
748                 if (!isNextToken('(')) {
749                         syntaxError('for文の"("が無い');
750                 }
751                
752                 var conditionLabel:Label = new Label();
753                 var continueLabel:Label = new Label();
754                 var startLabel:Label = new Label();
755                 var endLabel:Label = new Label();
756                
757                 pushBreakLabel(endLabel);
758                 pushContinueLabel(continueLabel);
759                
760                 // initialize expression, or variable declaration
761                 if (isNextToken('var')) {
762                         nextToken();
763                         parse_variableDeclaration();
764                 }
765                 else {
766                         if (!isToken(';')) {
767                                 var stackBegin:Number = generator.getStackLength();
768                                 var initializeExpression:ExpressionResult = new ExpressionResult();
769                                 parse_expression(initializeExpression);
770                                 generator.putExpressionResult(initializeExpression);
771                                 generator.cleanUpStack(stackBegin);
772                         }
773                 }
774                 if (!isToken(';')) {
775                         syntaxError('for文の最初の";"が無い');
776                 }
777                
778                 generator.setLabel(conditionLabel);
779                
780                 // condition expression
781                 if (!isNextToken(';')) {
782                         var stackBegin:Number = generator.getStackLength();
783                         var conditionExpression:ExpressionResult = new ExpressionResult();
784                         parse_expression(conditionExpression);
785                         generator.putExpressionResult(conditionExpression);
786                         generator.putIf(conditionExpression, endLabel);
787                         generator.cleanUpStack(stackBegin);
788                 }
789                 if (!isToken(';')) {
790                         syntaxError('for文のふたつめの";"が無い');
791                 }
792                
793                 generator.putJump(startLabel);
794                
795                 generator.setLabel(continueLabel);
796                
797                 // continue expression
798                 if (!isNextToken(')')) {
799                         var stackBegin:Number = generator.getStackLength();
800                         var continueExpression:ExpressionResult = new ExpressionResult();
801                         parse_expression(continueExpression);
802                         generator.putExpressionResult(continueExpression);
803                         generator.cleanUpStack(stackBegin);
804                 }
805                
806                 generator.putJump(conditionLabel);
807                
808                 if (!isToken(')')) {
809                         syntaxError('for文の")"を忘れている');
810                 }
811                
812                 nextToken();
813                
814                 generator.setLabel(startLabel);
815                
816                 parse_statement();
817                 generator.putJump(continueLabel);
818                
819                 generator.setLabel(endLabel);
820                
821                 popContinueLabel();
822                 popBreakLabel();
823         }
824         private function parse_whileStatement () : Void
825         {
826                 if (!isNextToken('(')) {
827                         syntaxError('while文の"("が無い');
828                 }
829                
830                 nextToken();
831                
832                 var startLabel:Label = new Label();
833                 var endLabel:Label = new Label();
834                
835                 pushBreakLabel(endLabel);
836                 pushContinueLabel(startLabel);
837                
838                 generator.setLabel(startLabel);
839                
840                 var condition:ExpressionResult = new ExpressionResult();
841                 parse_expression(condition);
842                 generator.putExpressionResult(condition);
843                 generator.putIf(condition, endLabel);
844                
845                 if (!isToken(')')) {
846                         syntaxError('while文の")"を忘れている');
847                 }
848                 nextToken();
849                
850                 parse_statement();
851                
852                 generator.putJump(startLabel);
853                
854                 generator.setLabel(endLabel);
855                
856                 popContinueLabel();
857                 popBreakLabel();
858         }
859         private function parse_doStatement () : Void
860         {
861                 nextToken();
862                
863                 var startLabel:Label = new Label();
864                 var continueLabel:Label = new Label();
865                 var endLabel:Label = new Label();
866                
867                 pushBreakLabel(endLabel);
868                 pushContinueLabel(continueLabel);
869                
870                 generator.setLabel(startLabel);
871                
872                 parse_statement();
873                
874                 if (!isToken('while')) {
875                         syntaxError('doに対応するwhileが無い');
876                 }
877                
878                 if (!isNextToken('(')) {
879                         syntaxError('do-whileの"("が無い');
880                 }
881                
882                 nextToken();
883                
884                 generator.setLabel(continueLabel);
885                
886                 var condition:ExpressionResult = new ExpressionResult();
887                 parse_expression(condition);
888                 generator.putExpressionResult(condition);
889                 generator.putIf(condition, endLabel);
890                 generator.putJump(startLabel);
891                
892                 if (!isToken(')')) {
893                         syntaxError('do-whileの")"を忘れている');
894                 }
895                
896                 generator.setLabel(endLabel);
897                
898                 popContinueLabel();
899                 popBreakLabel();
900                
901                 nextToken();
902         }
903        
904         // ContinueStatement ::= 'continue' Identifier? ';'
905         // *not support Identifier
906         //
907         // First(ContinueStatement) ::= 'continue'
908         private function parse_continueStatement () : Void
909         {
910                 if (!isToken('continue')) {
911                         syntaxError('continueで"continue"が無い??');
912                 }
913                 if (!isNextToken(';')) {
914                         syntaxError('continueで";"を忘れている');
915                 }
916                
917                 generator.putJump(getContinueLabel());
918                
919                 nextToken();
920         }
921        
922         // BreakStatement ::= 'break' Identifier? ';'
923         // *not support Identifier
924         //
925         // First(BreakStatement) ::= 'break'
926         private function parse_breakStatement () : Void
927         {
928                 if (!isToken('break')) {
929                         syntaxError('breakで"break"が無い??');
930                 }
931                 if (!isNextToken(';')) {
932                         syntaxError('breakで";"を忘れている');
933                 }
934                
935                 generator.putJump(getBreakLabel());
936                
937                 nextToken();
938         }
939        
940         // ReturnStatement ::= 'return' Expression? ';'
941         //
942         // FIrst(ReturnStatement) ::= 'return'
943         private function parse_returnStatement () : Void
944         {
945                 if (!isToken('return')) {
946                         syntaxError('returnで"return"が無い??');
947                 }
948                
949                 if (!isAllowReturn()) {
950                         syntaxError('returnは関数又はコルーチン内でのみ使えます');
951                 }
952                
953                 hasLastReturn = true;   // for FunctionExpression, FunctionDeclaration
954                
955                 var returnValue:ExpressionResult;
956                
957                 if (isExpressionFirst(nextToken().type)) {
958                         returnValue = new ExpressionResult();
959                         parse_expression(returnValue);
960                         generator.putExpressionResult(returnValue);
961                 }
962                 else {
963                         returnValue = ExpressionResult.createLiteral(undefined);
964                 }
965                
966                 if (isInFunction()) {
967                         generator.putReturnFunction(returnValue);
968                 }
969                 else {
970                         generator.putReturnCoroutine(returnValue);
971                 }
972                
973                 if (!isToken(';')) {
974                         syntaxError('returnで";"を忘れている');
975                 }
976                
977                 nextToken();
978         }
979        
980         // WithStatement ::= 'with' '(' Expression ')' Statement
981         //
982         // First(WithStatement) ::= 'with'
983         private function parse_withStatement () : Void
984         {
985                 if (!isToken('with')) {
986                         syntaxError('withで"with"が無い??');
987                 }
988                 if (!isNextToken('(')) {
989                         syntaxError('withで"("が無い');
990                 }
991                
992                 nextToken();
993                 var objectExpression:ExpressionResult = new ExpressionResult();
994                 parse_expression(objectExpression);
995                 generator.putExpressionResult(objectExpression);
996                 generator.putWith(objectExpression);
997                
998                 generator.beginNewScope();
999                
1000                 if (!isToken(')')) {
1001                         syntaxError('withで")"を忘れている');
1002                 }
1003                
1004                 nextToken();
1005                 parse_statement();
1006                
1007                 generator.closeScope();
1008                
1009                 generator.putEndWith();
1010         }
1011        
1012         // SwitchStatement ::= 'switch' '(' Expression ')' CaseBlock
1013         //
1014         // First(SwitchStatement) ::= 'switch'
1015         private function parse_switchStatement () : Void
1016         {
1017                 if (!isToken('switch')) {
1018                         syntaxError('switchで"switch"が無い??');
1019                 }
1020                 if (!isNextToken('(')) {
1021                         syntaxError('switchで"("を忘れている');
1022                 }
1023                
1024                 nextToken();
1025                 var condition:ExpressionResult = new ExpressionResult();
1026                 parse_expression(condition);
1027                 generator.putExpressionResult(condition);
1028                
1029                 if (!isToken(')')) {
1030                         syntaxError('switchで")"を忘れている');
1031                 }
1032                
1033                 var endLabel:Label = new Label();
1034                
1035                 pushBreakLabel(endLabel);
1036                
1037                 nextToken();
1038                 parse_caseBlock(condition);
1039                
1040                 generator.setLabel(endLabel);
1041                
1042                 popBreakLabel();
1043         }
1044        
1045         // CaseBlcok ::= '{' CaseClauses? '}'
1046         //      ::= '{' CaseClauses? DefaultClause CaseClauses? '}'
1047         //
1048         // First(CaseBlock) ::= '{'
1049         private function parse_caseBlock (condition:ExpressionResult) : Void
1050         {
1051                 if (!isToken('{')) {
1052                         syntaxError('switch-caseの"{"が無い');
1053                 }
1054                
1055                 var caseLabel:Label = new Label();
1056                 var bodyLabel:Label = new Label();
1057                
1058                 if (isNextToken('case')) {
1059                         parse_caseClauses(condition, caseLabel, bodyLabel);
1060                 }
1061                 if (isToken('default')) {
1062                         var defaultLabel:Label = new Label();
1063                        
1064                         generator.setLabel(defaultLabel);
1065                        
1066                         parse_defaultClause(bodyLabel);
1067                        
1068                         if (isToken('case')) {
1069                                 parse_caseClauses(condition, caseLabel, bodyLabel);
1070                         }
1071                        
1072                         generator.setLabelAddress(caseLabel, defaultLabel.address);
1073                        
1074                         generator.setLabel(bodyLabel);
1075                 }
1076                 else {
1077                         generator.setLabel(caseLabel);
1078                         generator.setLabel(bodyLabel);
1079                 }
1080                
1081                 if (!isToken('}')) {
1082                         syntaxError('switch-caseで"}"を忘れている');
1083                 }
1084                 nextToken();
1085         }
1086        
1087         // CaseClauses ::= CaseClause
1088         //      ::= CaseClauses CaseClause
1089         //
1090         // First(CaseClauses) ::= First(CaseClause)
1091         private function parse_caseClauses (condition:ExpressionResult, caseLabel:Label, bodyLabel:Label) : Void
1092         {
1093                 while (isToken('case')) {
1094                         parse_caseClause(condition, caseLabel, bodyLabel);
1095                 }
1096         }
1097        
1098         // CaseClause ::= 'case' Expression ':' StatementList?
1099         //
1100         // First(CaseClause) ::= 'case'
1101         private function parse_caseClause (condition:ExpressionResult, caseLabel:Label, bodyLabel:Label) : Void
1102         {
1103                 if (!isToken('case')) {
1104                         syntaxError('caseで"case"が無い??');
1105                 }
1106                
1107                 generator.setLabel(caseLabel);
1108                 caseLabel.initialize();
1109                
1110                 if (!condition.isLiteral()) {
1111                         generator.putDuplicate(condition);
1112                 }
1113                
1114                 nextToken();
1115                 var caseCondition:ExpressionResult = new ExpressionResult();
1116                 parse_expression(caseCondition);
1117                 generator.putExpressionResult(caseCondition);
1118                 generator.putBinaryOperation('CSEQ', condition, caseCondition);
1119                 generator.putIf(ExpressionResult.createStack(), caseLabel);
1120                
1121                 if (!isToken(':')) {
1122                         syntaxError('caseで":"が無い');
1123                 }
1124                
1125                 generator.setLabel(bodyLabel);
1126                 bodyLabel.initialize();
1127                
1128                 if (isStatementFirst(nextToken().type)) {
1129                         parse_statementList();
1130                 }
1131                
1132                 generator.putJump(bodyLabel);
1133         }
1134        
1135         // DefaultClause ::= 'default' ':' StatementList?
1136         //
1137         // First(DefaultClause) ::= 'default'
1138         private function parse_defaultClause (bodyLabel:Label) : Void
1139         {
1140                 if (!isToken('default')) {
1141                         syntaxError('defaultで"default"が無い??');
1142                 }
1143                
1144                 if (!isNextToken(':')) {
1145                         syntaxError('defaultで":"を忘れている');
1146                 }
1147                
1148                 generator.setLabel(bodyLabel);
1149                 bodyLabel.initialize();
1150                
1151                 if (isStatementFirst(nextToken().type)) {
1152                         parse_statementList();
1153                 }
1154                
1155                 generator.putJump(bodyLabel);
1156         }
1157        
1158         // YieldStatement ::= 'yield' ';'
1159         // *original
1160         //
1161         // First(YieldStatement) ::= 'yield'
1162         private function parse_yieldStatement () : Void
1163         {
1164                 if (!isToken('yield')) {
1165                         syntaxError('yieldで"yield"が無い??');
1166                 }
1167                 if (!isNextToken(';')) {
1168                         syntaxError('yieldで";"を忘れている');
1169                 }
1170                
1171                 if (isInFunction()) {
1172                         syntaxError('関数内でyieldする事は出来ません。coroutineを使う必要があります。');
1173                 }
1174                
1175                 generator.putSuspend();
1176                
1177                 nextToken();
1178         }
1179        
1180         // SuspendStatement ::= 'suspend' ';'
1181         // *original
1182         //
1183         // First(SuspendStatement) ::= 'suspend'
1184         private function parse_suspendStatement () : Void
1185         {
1186                 if (!isToken('suspend')) {
1187                         syntaxError('suspendで"suspend"が無い??');
1188                 }
1189                 if (!isNextToken(';')) {
1190                         syntaxError('suspendで";"を忘れている');
1191                 }
1192                
1193                 if (isInFunction()) {
1194                         syntaxError('関数内でsuspendする事は出来ません。coroutineを使う必要があります。');
1195                 }
1196                
1197                 generator.putSuspend();
1198                
1199                 nextToken();
1200         }
1201        
1202         // LoopStatement ::= 'loop' 'Statement
1203         // *original
1204         //
1205         // First(LoopStatement) ::= 'loop'
1206         private function parse_loopStatement () : Void
1207         {
1208                 if (!isToken('loop')) {
1209                         syntaxError('loopで"loop"が無い??');
1210                 }
1211                
1212                 nextToken();
1213                
1214                 var startLabel:Label = new Label();
1215                 var endLabel:Label = new Label();
1216                
1217                 pushBreakLabel(endLabel);
1218                 pushContinueLabel(startLabel);
1219                
1220                 generator.setLabel(startLabel);
1221                
1222                 parse_statement();
1223                
1224                 generator.putJump(startLabel);
1225                
1226                 generator.setLabel(endLabel);
1227                
1228                 popContinueLabel();
1229                 popBreakLabel();
1230         }
1231        
1232         // Expression ::= AssignmentExpression
1233         //      ::= Expression ',' AssignmentExpression
1234         //
1235         // First(Expression) ::= First(AssignmentExpression)
1236         private function parse_expression (expressionResult:ExpressionResult) : Void
1237         {
1238                 parse_assignmentExpression(expressionResult);
1239                
1240                 while (isToken(',')) {
1241                         nextToken();
1242                        
1243                         generator.putExpressionResult(expressionResult);
1244                         generator.popAndDestroyStack();
1245                        
1246                         expressionResult.initialize();
1247                         parse_assignmentExpression(expressionResult);
1248                 }
1249         }
1250         private function isExpressionFirst (type:String) : Boolean
1251         {
1252                 return isUnaryExpressionFirst(type);
1253         }
1254        
1255         private function areBothLiteral (a:ExpressionResult, b:ExpressionResult) : Boolean
1256         {
1257                 return (a.isType('literal') && b.isType('literal'));
1258         }
1259        
1260         // AssignmentExpression ::= ConditionalExpression
1261         //      ::= LeftHandSideExpression AssignmentOperator AssignmentExpression
1262         // AssignmentOperator ::= '=' '*=' '/=' '%=' '+=' '-=' '<<=' '>>=' '>>>=' '&=' '^=' '|='
1263         //
1264         // First(AssignmentExpression) ::= First(ConditionalExpression) First(LeftHandSideExpression)
1265         private function parse_assignmentExpression (expressionResult:ExpressionResult) : Void
1266         {
1267                 parse_conditionalExpression(expressionResult);
1268                
1269                 switch (getToken().type) {
1270                         case '=': {
1271                                 nextToken();
1272                                
1273                                 switch (expressionResult.type) {
1274                                         case 'member': {
1275                                                 var objectExpression:ExpressionResult = expressionResult.getObjectExpression();
1276                                                 var memberExpression:ExpressionResult = expressionResult.getMemberExpression();
1277                                                 generator.putExpressionResult(memberExpression);
1278                                                 var rightExpression:ExpressionResult = new ExpressionResult();
1279                                                 parse_assignmentExpression(rightExpression);
1280                                                 generator.putExpressionResult(rightExpression);
1281                                                 generator.putSetMember(objectExpression, memberExpression, rightExpression);
1282                                         }
1283                                         break;
1284                                        
1285                                         case 'variable': {
1286                                                 var rightExpression:ExpressionResult = new ExpressionResult();
1287                                                 parse_assignmentExpression(rightExpression);
1288                                                 generator.putExpressionResult(rightExpression);
1289                                                 generator.putSetVariable(String(expressionResult.value), rightExpression);
1290                                         }
1291                                         break;
1292                                        
1293                                         default: {
1294                                                 syntaxError('左辺値は変数又はプロパティでなければなりません');
1295                                         }
1296                                 }
1297                                 expressionResult.setTypeStack();
1298                         }
1299                         break;
1300                        
1301                         case '*=': case '/=': case '%=': case '+=': case '-=':
1302                         case '<<=': case '>>=': case '>>>=': case '&=': case '^=':
1303                         case '|=': {
1304                                 var operation:String;
1305                                
1306                                 switch (getToken().type) {
1307                                         case '*=': operation = 'MUL'; break;
1308                                         case '/=': operation = 'DIV'; break;
1309                                         case '%=': operation = 'MOD'; break;
1310                                         case '+=': operation = 'ADD'; break;
1311                                         case '-=': operation = 'SUB'; break;
1312                                         case '<<=': operation = 'LSH'; break;
1313                                         case '>>=': operation = 'RSH'; break;
1314                                         case '>>>=': operation = 'URSH'; break;
1315                                         case '&=': operation = 'AND'; break;
1316                                         case '^=': operation = 'XOR'; break;
1317                                         case '|=': operation = 'OR'; break;
1318                                 }
1319                                
1320                                 nextToken();
1321                                
1322                                 switch (expressionResult.type) {
1323                                         case 'member': {
1324                                                 var objectExpression:ExpressionResult = expressionResult.getObjectExpression();
1325                                                 var memberExpression:ExpressionResult = expressionResult.getMemberExpression();
1326                                                 if (!memberExpression.isLiteral()) {
1327                                                         generator.putExpressionResult(memberExpression);
1328                                                         var s:Number = generator.popStack();
1329                                                         generator.putDuplicate(memberExpression);
1330                                                         generator.pushStack(s);
1331                                                         generator.putDuplicate(objectExpression);
1332                                                         generator.swapStack(1, 2);
1333                                                 }
1334                                                 else {
1335                                                         generator.putDuplicate(objectExpression);
1336                                                 }
1337                                                 generator.putGetMember(objectExpression, memberExpression);
1338                                                 expressionResult.setTypeStack();
1339                                                 var rightExpression:ExpressionResult = new ExpressionResult();
1340                                                 parse_assignmentExpression(rightExpression);
1341                                                 generator.putExpressionResult(rightExpression);
1342                                                 generator.putBinaryOperation(operation, expressionResult, rightExpression);
1343                                                 generator.putSetMember(objectExpression, memberExpression, expressionResult);
1344                                         }
1345                                         break;
1346                                        
1347                                         case 'variable': {
1348                                                 var identifier:String = String(expressionResult.value);
1349                                                 generator.putGetVariable(identifier);
1350                                                 expressionResult.setTypeStack();
1351                                                 var rightExpression:ExpressionResult = new ExpressionResult();
1352                                                 parse_assignmentExpression(rightExpression);
1353                                                 generator.putExpressionResult(rightExpression);
1354                                                 generator.putBinaryOperation(operation, expressionResult, rightExpression);
1355                                                 generator.putSetVariable(identifier, expressionResult);
1356                                         }
1357                                         break;
1358                                        
1359                                         default: {
1360                                                 syntaxError('左辺値は変数又はプロパティでなければなりません');
1361                                         }
1362                                 }
1363                                 expressionResult.setTypeStack();
1364                         }
1365                         break;
1366                        
1367                         default:
1368                         break;
1369                 }
1370         }
1371        
1372         // ConditionalExpression ::= LogicalORExpression
1373         //      ::= LogicalORExpression '?' AssignmentExpression ':' AssignmentExpression
1374         //
1375         // First(ConditionalExpression) ::= First(LogicalORExpression)
1376         private function parse_conditionalExpression (expressionResult:ExpressionResult) : Void
1377         {
1378                 parse_logicalORExpression(expressionResult);
1379                
1380                 if (isToken('?')) {
1381                        
1382                         generator.putExpressionResult(expressionResult);
1383                         var label:Label = new Label();
1384                         generator.putIf(expressionResult, label);
1385                        
1386                         nextToken();
1387                         expressionResult.initialize();
1388                         parse_assignmentExpression(expressionResult);
1389                         if (expressionResult.isType('literal')) {
1390                                 generator.putLiteral(expressionResult);
1391                         }
1392                         else {
1393                                 generator.putExpressionResult(expressionResult);
1394                         }
1395                         var patch:Number = generator.popStack();
1396                        
1397                         var label2:Label = new Label();
1398                         generator.putJump(label2);
1399                        
1400                         generator.setLabel(label);
1401                        
1402                         if (!isToken(':')) {
1403                                 syntaxError('3項演算式で":"が無い');
1404                         }
1405                        
1406                         nextToken();
1407                         expressionResult.initialize();
1408                         parse_assignmentExpression(expressionResult);
1409                         if (expressionResult.isType('literal')) {
1410                                 generator.putLiteral(expressionResult);
1411                         }
1412                         else {
1413                                 generator.putExpressionResult(expressionResult);
1414                         }
1415                         expressionResult.setType('stack');
1416                         generator.setStackPatch(patch);
1417                        
1418                         generator.setLabel(label2);
1419                 }
1420         }
1421        
1422         // LogicalORExpression ::= LogicalANDExpression
1423         //      ::= LogicalORExpression '||' LogicalANDExpression
1424         //
1425         // First(LogicalORExpression) ::= First(LogicalANDExpression)
1426         private function parse_logicalORExpression (expressionResult:ExpressionResult) : Void
1427         {
1428                 parse_logicalANDExpression(expressionResult);
1429                
1430                 while (isToken('||')) {
1431                         nextToken();
1432                        
1433                         // ここどうにかならんかなぁ・・・
1434                        
1435                         generator.putExpressionResult(expressionResult);
1436                         generator.putDuplicate(expressionResult);
1437                         var patch:Number = generator.popStack();
1438                         expressionResult.setType('stack');
1439                         var label:Label = new Label();
1440                         generator.putNif(expressionResult, label);
1441                        
1442                         expressionResult.initialize();
1443                         parse_logicalANDExpression(expressionResult);
1444                        
1445                         if (expressionResult.isType('literal')) {
1446                                 generator.putLiteral(expressionResult);
1447                         }
1448                         else {
1449                                 generator.putExpressionResult(expressionResult);
1450                         }
1451                         generator.setStackPatch(patch);
1452                         expressionResult.setType('stack');
1453                        
1454                         generator.setLabel(label);
1455                 }
1456         }
1457        
1458         // LogicalANDExpression ::= BitwiseORExpression
1459         //      ::= LogicalANDExpression '&&' BitwiseORExpression
1460         //
1461         // First(LogicalANDExpression) ::= First(BitwiseORExpression)
1462         private function parse_logicalANDExpression (expressionResult:ExpressionResult) : Void
1463         {
1464                 parse_bitwiseORExpression(expressionResult);
1465                
1466                 while (isToken('&&')) {
1467                         nextToken();
1468                        
1469                         // ここどうにかならんかなぁ・・・
1470                        
1471                         generator.putExpressionResult(expressionResult);
1472                         generator.putDuplicate(expressionResult);
1473                         var patch:Number = generator.popStack();
1474                         expressionResult.setType('stack');
1475                         var label:Label = new Label();
1476                         generator.putIf(expressionResult, label);
1477                        
1478                         expressionResult.initialize();
1479                         parse_bitwiseORExpression(expressionResult);
1480                        
1481                         if (expressionResult.isType('literal')) {
1482                                 generator.putLiteral(expressionResult);
1483                         }
1484                         else {
1485                                 generator.putExpressionResult(expressionResult);
1486                         }
1487                         generator.setStackPatch(patch);
1488                         expressionResult.setType('stack');
1489                        
1490                         generator.setLabel(label);
1491                 }
1492         }
1493        
1494         // BitwiseORExpression ::= BitwiseXORExpression
1495         //      ::= BitwiseORExpression '|' BitwiseXORExpression
1496         //
1497         // First(BitwiseORExpression) ::= First(BitwiseXORExpression)
1498         private function parse_bitwiseORExpression (expressionResult:ExpressionResult) : Void
1499         {
1500                 parse_bitwiseXORExpression(expressionResult);
1501                
1502                 while (isToken('|')) {
1503                         var operation:String = getToken().type;
1504                        
1505                         nextToken();
1506                        
1507                         generator.putExpressionResult(expressionResult);
1508                        
1509                         var rightExpressionResult:ExpressionResult = new ExpressionResult();
1510                        
1511                         parse_bitwiseXORExpression(rightExpressionResult);
1512                        
1513                         generator.putExpressionResult(rightExpressionResult);
1514                        
1515                         // 定数畳み込み
1516                         if (areBothLiteral(expressionResult, rightExpressionResult)) {
1517                                 expressionResult.setValue(expressionResult.value | rightExpressionResult.value);
1518                         }
1519                         // 通常コード
1520                         else {
1521                                 generator.putBinaryOperation('OR', expressionResult, rightExpressionResult);
1522                                 expressionResult.setType('stack');
1523                         }
1524                 }
1525         }
1526        
1527         // BitwiseXORExpression ::= BitwiseANDExpression
1528         //      ::= BitiwseXORExpression '^' BitwiseANDExpression
1529         //
1530         // First(BitwiseXORExpression) ::= First(BitwiseANDExpression)
1531         private function parse_bitwiseXORExpression (expressionResult:ExpressionResult) : Void
1532         {
1533                 parse_bitwiseANDExpression(expressionResult);
1534                
1535                 while (isToken('^')) {
1536                         var operation:String = getToken().type;
1537                        
1538                         nextToken();
1539                        
1540                         generator.putExpressionResult(expressionResult);
1541                        
1542                         var rightExpressionResult:ExpressionResult = new ExpressionResult();
1543                        
1544                         parse_bitwiseANDExpression(rightExpressionResult);
1545                        
1546                         generator.putExpressionResult(rightExpressionResult);
1547                        
1548                         // 定数畳み込み
1549                         if (areBothLiteral(expressionResult, rightExpressionResult)) {
1550                                 expressionResult.setValue(expressionResult.value ^ rightExpressionResult.value);
1551                         }
1552                         else {
1553                                 generator.putBinaryOperation('XOR', expressionResult, rightExpressionResult);
1554                                 expressionResult.setType('stack');
1555                         }
1556                 }
1557         }
1558        
1559         // BitwiseANDExpression ::= EqualityExpression
1560         //      ::= BitwiseANDExpression '&' EqualityExpression
1561         //
1562         // First(BitwiseANDExpression) ::= First(EqualityEpxression)
1563         private function parse_bitwiseANDExpression (expressionResult:ExpressionResult) : Void
1564         {
1565                 parse_equalityExpression(expressionResult);
1566                
1567                 while (isToken('&')) {
1568                         var operation:String = getToken().type;
1569                        
1570                         nextToken();
1571                        
1572                         generator.putExpressionResult(expressionResult);
1573                        
1574                         var rightExpressionResult:ExpressionResult  = new ExpressionResult();
1575                         parse_equalityExpression(rightExpressionResult);
1576                        
1577                         generator.putExpressionResult(rightExpressionResult);
1578                        
1579                         // 定数畳み込み
1580                         if (areBothLiteral(expressionResult, rightExpressionResult)) {
1581                                 expressionResult.setValue(expressionResult.value & rightExpressionResult.value);
1582                         }
1583                         else {
1584                                 generator.putBinaryOperation('AND', expressionResult, rightExpressionResult);
1585                                 expressionResult.setType('stack');
1586                         }
1587                 }
1588         }
1589        
1590         // EqualityExpression ::= RelationalExpression
1591         //      ::= EqualityExpression '==' RelationalExpression
1592         //      ::= EqualityExpression '!=' RelationalExpression
1593         //      ::= EqualityExpression '===' RelationalExpression
1594         //      ::= EqualityExpression '!==' RelationalExpression
1595         //
1596         // FIrst(EqualityEpxression) ::= First(RelationalExpression)
1597         private function parse_equalityExpression (expressionResult:ExpressionResult) : Void
1598         {
1599                 parse_relationalExpression(expressionResult);
1600                
1601                 while (isToken('==') || isToken('!=') || isToken('===') || isToken('!==')) {
1602                         var operation:String = getToken().type;
1603                        
1604                         nextToken();
1605                        
1606                         generator.putExpressionResult(expressionResult);
1607                        
1608                         var rightExpressionResult:ExpressionResult = new ExpressionResult();
1609                         parse_relationalExpression(rightExpressionResult);
1610                        
1611                         generator.putExpressionResult(rightExpressionResult);
1612                        
1613                         if (areBothLiteral(expressionResult, rightExpressionResult)) {
1614                                 switch (operation) {
1615                                         case '==': expressionResult.setValue(expressionResult.value == rightExpressionResult.value); break;
1616                                         case '!=': expressionResult.setValue(expressionResult.value != rightExpressionResult.value); break;
1617                                         case '===': expressionResult.setValue(expressionResult.value === rightExpressionResult.value); break;
1618                                         case '!==': expressionResult.setValue(expressionResult.value !== rightExpressionResult.value); break;
1619                                 }
1620                         }
1621                         else {
1622                                 switch (operation) {
1623                                         case '==': generator.putBinaryOperation('CEQ', expressionResult, rightExpressionResult); break;
1624                                         case '!=': generator.putBinaryOperation('CNE', expressionResult, rightExpressionResult); break;
1625                                         case '===': generator.putBinaryOperation('CSEQ', expressionResult, rightExpressionResult); break;
1626                                         case '!==': generator.putBinaryOperation('CSNE', expressionResult, rightExpressionResult); break;
1627                                 }
1628                                 expressionResult.setType('stack');
1629                         }
1630                 }
1631         }
1632        
1633         // RelationalExpression ::= ShiftExpression
1634         //      ::= RelationalExpression '<' ShiftExpression
1635         //      ::= RelationalExpressioin '>' ShiftExpression
1636         //      ::= RelationalExpression '<=' ShiftExpression
1637         //      ::= RelationalExpression '>=' ShiftExpression
1638         //      ::= RelationalExpression 'instanceof' ShiftExpression
1639         //      ::= RelationalExpression 'in' ShiftExpression (not support)
1640         //
1641         // First(RelationalExpression) ::= First(ShiftExpression)
1642         private function parse_relationalExpression (expressionResult:ExpressionResult) : Void
1643         {
1644                 parse_shiftExpression(expressionResult);
1645                
1646                 while (isToken('<') || isToken('>') || isToken('<=') || isToken('>=') || isToken('instanceof')) {
1647                         var operation:String = getToken().type;
1648                        
1649                         nextToken();
1650                        
1651                         generator.putExpressionResult(expressionResult);
1652                        
1653                         var rightExpressionResult:ExpressionResult = new ExpressionResult();
1654                         parse_shiftExpression(rightExpressionResult);
1655                        
1656                         generator.putExpressionResult(rightExpressionResult);
1657                        
1658                         if (areBothLiteral(expressionResult, rightExpressionResult)) {
1659                                 switch (operation) {
1660                                         case '<': expressionResult.setValue(expressionResult.value < rightExpressionResult.value); break;
1661                                         case '>': expressionResult.setValue(expressionResult.value > rightExpressionResult.value); break;
1662                                         case '<=': expressionResult.setValue(expressionResult.value <= rightExpressionResult.value); break;
1663                                         case '>=': expressionResult.setValue(expressionResult.value >= rightExpressionResult.value); break;
1664                                         case 'instanceof': expressionResult.setValue(expressionResult.value instanceof rightExpressionResult.value); break;
1665                                 }
1666                         }
1667                         else {
1668                                 switch (operation) {
1669                                         case '<': generator.putBinaryOperation('CLT', expressionResult, rightExpressionResult); break;
1670                                         case '>': generator.putBinaryOperation('CGT', expressionResult, rightExpressionResult); break;
1671                                         case '<=': generator.putBinaryOperation('CLE', expressionResult, rightExpressionResult); break;
1672                                         case '>=': generator.putBinaryOperation('CGE', expressionResult, rightExpressionResult); break;
1673                                         case 'instanceof': generator.putBinaryOperation('INSOF', expressionResult, rightExpressionResult); break;
1674                                 }
1675                                 expressionResult.setType('stack');
1676                         }
1677                 }
1678         }
1679        
1680         // ShiftExpression ::= AdditiveExpression
1681         //      ::= ShiftExpression '<<' AdditiveExpression
1682         //      ::= ShiftExpression '>>' AdditiveExpression
1683         //      ::= ShiftExpression '>>>' AdditiveExpression
1684         //
1685         // First(ShiftExpression) ::= First(AdditiveExpression)
1686         private function parse_shiftExpression (expressionResult:ExpressionResult) : Void
1687         {
1688                 parse_additiveExpression(expressionResult);
1689                
1690                 while (isToken('<<') || isToken('>>') || isToken('>>>')) {
1691                         var operation:String = getToken().type;
1692                        
1693                         nextToken();
1694                        
1695                         generator.putExpressionResult(expressionResult);
1696                        
1697                         var rightExpressionResult:ExpressionResult = new ExpressionResult();
1698                         parse_additiveExpression(rightExpressionResult);
1699                        
1700                         generator.putExpressionResult(rightExpressionResult);
1701                        
1702                         if (areBothLiteral(expressionResult, rightExpressionResult)) {
1703                                 switch (operation) {
1704                                         case '<<': expressionResult.setValue(expressionResult.value << rightExpressionResult.value); break;
1705                                         case '>>': expressionResult.setValue(expressionResult.value >> rightExpressionResult.value); break;
1706                                         case '>>>': expressionResult.setValue(expressionResult.value >>> rightExpressionResult.value); break;
1707                                 }
1708                         }
1709                         else {
1710                                 switch (operation) {
1711                                         case '<<': generator.putBinaryOperation('LSH', expressionResult, rightExpressionResult); break;
1712                                         case '>>': generator.putBinaryOperation('RSH', expressionResult, rightExpressionResult); break;
1713                                         case '>>>': generator.putBinaryOperation('URSH', expressionResult, rightExpressionResult); break;
1714                                 }
1715                                 expressionResult.setType('stack');
1716                         }
1717                 }
1718         }
1719        
1720         // AdditiveExpression ::= MultiplicativeExpression
1721         //      ::= AdditiveExpression '+' MultiplicativeExpression
1722         //      ::= AddtivieExpression '-' MultiplicativeExpression
1723         //
1724         // First(AdditiveExpression) ::= First(MultiplicativeExpression)
1725         private function parse_additiveExpression (expressionResult:ExpressionResult) : Void
1726         {
1727                 parse_multiplicativeExpression(expressionResult);
1728                
1729                 while (isToken('+') || isToken('-')) {
1730                         var operation:String = getToken().type;
1731                        
1732                         nextToken();
1733                        
1734                         generator.putExpressionResult(expressionResult);
1735                        
1736                         var rightExpressionResult:ExpressionResult = new ExpressionResult();
1737                         parse_multiplicativeExpression(rightExpressionResult);
1738                        
1739                         generator.putExpressionResult(rightExpressionResult);
1740                        
1741                         if (areBothLiteral(expressionResult, rightExpressionResult)) {
1742                                 switch (operation) {
1743                                         case '+': expressionResult.setValue(expressionResult.value + rightExpressionResult.value); break;
1744                                         case '-': expressionResult.setValue(expressionResult.value - rightExpressionResult.value); break;
1745                                 }
1746                         }
1747                         else {
1748                                 switch (operation) {
1749                                         case '+': generator.putBinaryOperation('ADD', expressionResult, rightExpressionResult); break;
1750                                         case '-': generator.putBinaryOperation('SUB', expressionResult, rightExpressionResult); break;
1751                                 }
1752                                 expressionResult.setType('stack');
1753                         }
1754                 }
1755         }
1756        
1757         // MultiplicativeExpression ::= UnaryExpression
1758         //      ::= MultiplicativeExpression '*' UnaryExpression
1759         //      ::= MultiplicativeExpression '/' UnaryExpression
1760         //      ::= MultiplicativeExpression '%' UnaryExpression
1761         //
1762         // First(MultiplicativeExpression) ::= First(UnaryEpxression)
1763         private function parse_multiplicativeExpression (expressionResult:ExpressionResult) : Void
1764         {
1765                 parse_unaryExpression(expressionResult);
1766                
1767                 while (isToken('*') || isToken('/') || isToken('%')) {
1768                         var operation:String = getToken().type;
1769                        
1770                         nextToken();
1771                        
1772                         generator.putExpressionResult(expressionResult);
1773                        
1774                         var rightExpressionResult:ExpressionResult = new ExpressionResult();
1775                         parse_unaryExpression(rightExpressionResult);
1776                        
1777                         generator.putExpressionResult(rightExpressionResult);
1778                        
1779                         if (areBothLiteral(expressionResult, rightExpressionResult)) {
1780                                 switch (operation) {
1781                                         case '*': expressionResult.setValue(expressionResult.value * rightExpressionResult.value); break;
1782                                         case '/': expressionResult.setValue(expressionResult.value / rightExpressionResult.value); break;
1783                                         case '%': expressionResult.setValue(expressionResult.value % rightExpressionResult.value); break;
1784                                 }
1785                         }
1786                         else {
1787                                 switch (operation) {
1788                                         case '*': generator.putBinaryOperation('MUL', expressionResult, rightExpressionResult); break;
1789                                         case '/': generator.putBinaryOperation('DIV', expressionResult, rightExpressionResult); break;
1790                                         case '%': generator.putBinaryOperation('MOD', expressionResult, rightExpressionResult); break;
1791                                 }
1792                                 expressionResult.setType('stack');
1793                         }
1794                 }
1795         }
1796        
1797         // UnaryExpression ::= PostfixExpression
1798         //      ::= 'delete' UnaryExpression
1799         //      ::= 'void' UnaryExpression
1800         //      ::= 'typeof' UnaryExpression
1801         //      ::= '++' UnaryExpression
1802         //      ::= '--' UnaryExpression
1803         //      ::= '+' UnaryExpression
1804         //      ::= '-' UnaryExpression
1805         //      ::= '~' UnaryExpression
1806         //      ::= '!' UnaryExpression
1807         //
1808         // First(UnaryExpression) ::= First(PostfixExpression) 'delete' 'void' 'typeof' '++' '--' '-+' '-' '~' '!'
1809         private function parse_unaryExpression (expressionResult:ExpressionResult) : Void
1810         {
1811                 switch (getToken().type) {
1812                         case 'delete': {
1813                                 nextToken();
1814                                 parse_unaryExpression(expressionResult);
1815                                
1816                                 switch (expressionResult.type) {
1817                                         case 'member': {
1818                                                 var objectExpression:ExpressionResult = expressionResult.getObjectExpression();
1819                                                 var memberExpression:ExpressionResult = expressionResult.getMemberExpression();
1820                                                 generator.putExpressionResult(memberExpression);
1821                                                 generator.putDeleteMember(objectExpression, memberExpression);
1822                                         }
1823                                         break;
1824                                        
1825                                         case 'variable': {
1826                                                 generator.putDelete(expressionResult);
1827                                         }
1828                                         break;
1829                                        
1830                                         default: {
1831                                                 generator.putExpressionResult(expressionResult);
1832                                                 generator.putDelete(expressionResult);
1833                                         }
1834                                         break;
1835                                 }
1836                                 expressionResult.setTypeStack();
1837                         }
1838                         break;
1839                        
1840                         case 'void': {
1841                                 // 今の所無視
1842                                 nextToken();
1843                                 parse_unaryExpression(expressionResult);
1844                         }
1845                         break;
1846                        
1847                         case 'typeof': {
1848                                 nextToken();
1849                                 parse_unaryExpression(expressionResult);
1850                                
1851                                 generator.putExpressionResult(expressionResult);
1852                                
1853                                 if (expressionResult.isType('literal')) {
1854                                         expressionResult.setValue(typeof expressionResult.value);
1855                                 }
1856                                 else {
1857                                         generator.putUnaryOperation('TYPEOF', expressionResult);
1858                                         expressionResult.setTypeStack();
1859                                 }
1860                         }
1861                         break;
1862                        
1863                         case '++': {
1864                                 nextToken();
1865                                 parse_unaryExpression(expressionResult);
1866                                
1867                                 generator.putIncrement(expressionResult);
1868                                
1869                                 expressionResult.setTypeStack();
1870                         }
1871                         break;
1872                        
1873                         case '--': {
1874                                 nextToken();
1875                                 parse_unaryExpression(expressionResult);
1876                                
1877                                 generator.putDecrement(expressionResult);
1878                                
1879                                 expressionResult.setTypeStack();
1880                         }
1881                         break;
1882                        
1883                         case '+': {
1884                                 nextToken();
1885                                 parse_unaryExpression(expressionResult);
1886                         }
1887                         break;
1888                        
1889                         case '-': {
1890                                 nextToken();
1891                                 parse_unaryExpression(expressionResult);
1892                                
1893                                 generator.putExpressionResult(expressionResult);
1894                                
1895                                 if (expressionResult.isType('literal')) {
1896                                         expressionResult.setValue(-expressionResult.value);
1897                                 }
1898                                 else {
1899                                         var zeroLiteral:ExpressionResult = new ExpressionResult();
1900                                         zeroLiteral.setTypeAndValue('literal', 0);
1901                                        
1902                                         generator.putBinaryOperation('SUB', zeroLiteral, expressionResult);
1903                                         expressionResult.setType('stack');
1904                                 }
1905                         }
1906                         break;
1907                        
1908                         case '~': {
1909                                 nextToken();
1910                                 parse_unaryExpression(expressionResult);
1911                                
1912                                 generator.putExpressionResult(expressionResult);
1913                                
1914                                 if (expressionResult.isType('literal')) {
1915                                         expressionResult.setValue(~expressionResult.value);
1916                                 }
1917                                 else {
1918                                         generator.putUnaryOperation('NOT', expressionResult);
1919                                         expressionResult.setType('stack');
1920                                 }
1921                         }
1922                         break;
1923                        
1924                         case '!':
1925                         {
1926                                 nextToken();
1927                                 parse_unaryExpression(expressionResult);
1928                                
1929                                 generator.putExpressionResult(expressionResult);
1930                                
1931                                 if (expressionResult.isType('literal')) {
1932                                         expressionResult.setValue(!expressionResult.value);
1933                                 }
1934                                 else {
1935                                         generator.putUnaryOperation('LNOT', expressionResult);
1936                                         expressionResult.setType('stack');
1937                                 }
1938                         }
1939                         break;
1940                        
1941                         default: {
1942                                 parse_postfixExpression(expressionResult);
1943                         }
1944                         break;
1945                 }
1946         }
1947         private function isUnaryExpressionFirst (type:String) : Boolean
1948         {
1949                 return (type == 'delete' || type == 'void' || type == 'typeof' ||
1950                         type == '++' || type == '--' || type == '+' || type == '-' ||
1951                         type == '~' || type == '!' ||
1952                         isMemberExpressionFirst(type)
1953                         );
1954         }
1955        
1956         // PostfixExpression ::= LeftHandSideExpression
1957         //      ::= LeftHandSideExpression '++'
1958         //      ::= LeftHandSideExpression '--'
1959         //
1960         // First(PostfixExpression) ::= First(LeftHandSideExpression)
1961         private function parse_postfixExpression (expressionResult:ExpressionResult) : Void
1962         {
1963                 parse_leftHandSideExpression(expressionResult);
1964                
1965                 if (isToken('++') || isToken('--')) {
1966                         switch (getToken().type) {
1967                                 case '++': generator.putPostfixIncrement(expressionResult); break;
1968                                 case '--': generator.putPostfixDecrement(expressionResult); break;
1969                         }
1970                         expressionResult.setTypeStack();
1971                         nextToken();
1972                 }
1973         }
1974        
1975         // LeftHandSideExpression ::= NewExpression
1976         //      ::= CallExpression
1977         // NewExpression ::= MemberExpression
1978         //      ::= 'new' NewExpression (not support)
1979         // CallExpression ::= MemberExpression Arguments
1980         //      ::= CallExpression Arguments
1981         //      ::= CallExpression '[' Expression ']'
1982         //      ::= CallExpression '.' Identifier
1983         //
1984         // ↑じゃ解析できないので
1985         //
1986         // LeftHandSideExpression ::= CallExpression
1987         // CallExpression ::= MemberExpression
1988         //      ::= CallExpression Arguments
1989         //      ::= CallExpression '[' Expression ']'
1990         //      ::= CallExpression '.' Identifier
1991         // MemberExpression ::= PrimaryExpression
1992         //      ::= FunctionExpression
1993         //      ::= CoroutineExpression
1994         //      ::= 'new' MemberExpression Arguments?
1995         //
1996         // First(LeftHandSideExpression) ::= First(CallExpression)
1997         // First(CallExpression) ::= First(MemberExpression)
1998         // First(MemberExpression) ::= First(PrimaryExpression) First(FunctionExpression) First(CoroutineExpression) 'new'
1999         private function parse_leftHandSideExpression (expressionResult:ExpressionResult) : Void
2000         {
2001                 parse_callExpression(expressionResult);
2002         }
2003         private function parse_callExpression (expressionResult:ExpressionResult) : Void
2004         {
2005                 parse_memberExpression(expressionResult);
2006                
2007                 for (;;) {
2008                         if (isToken('(')) {
2009                                 var numOfArguments:Number = parse_arguments();
2010                                
2011                                 switch (expressionResult.type) {
2012                                         case 'member': {
2013                                                 var objectExpression:ExpressionResult = expressionResult.getObjectExpression();
2014                                                 var memberExpression:ExpressionResult = expressionResult.getMemberExpression();
2015                                                 generator.putExpressionResult(memberExpression);
2016                                                 generator.putCallMember(objectExpression, memberExpression, numOfArguments);
2017                                         }
2018                                         break;
2019                                        
2020                                         case 'stack': {
2021                                                 generator.putCallFunctor(numOfArguments);
2022                                         }
2023                                         break;
2024                                        
2025                                         default: {
2026                                                 generator.putCall(expressionResult, numOfArguments);
2027                                         }
2028                                 }
2029                                
2030                                 expressionResult.setType('stack');
2031                                
2032                                 continue;
2033                         }
2034                         if (isToken('[')) {
2035                                 nextToken();
2036                                
2037                                 generator.putExpressionResult(expressionResult);
2038                                
2039                                 var memberExpression:ExpressionResult = new ExpressionResult();
2040                                 parse_expression(memberExpression);
2041                                 expressionResult.setTypeMember(expressionResult.clone(), memberExpression);
2042                                 // expressionResult.setTypeAndValue('member', memberExpression);
2043                                
2044                                 if (!isToken(']')) {
2045                                         syntaxError('配列アクセス演算子の"]"を忘れている');
2046                                 }
2047                                
2048                                 nextToken();
2049                                 continue;
2050                         }
2051                         if (isToken('.')) {
2052                                
2053                                 generator.putExpressionResult(expressionResult);
2054                                
2055                                 if (!isNextToken('identifier')) {
2056                                         syntaxError('プロパティアクセスで"."の後の識別子が無い');
2057                                 }
2058                                
2059                                 expressionResult.setTypeMember(expressionResult.clone(), ExpressionResult.createLiteral(getToken().value));
2060                                 // expressionResult.setTypeAndValue('member', ExpressionResult.createLiteral(getToken().value));
2061                                
2062                                 nextToken();
2063                                 continue;
2064                         }
2065                         break;
2066                 }
2067         }
2068         private function parse_memberExpression (expressionResult:ExpressionResult) : Void
2069         {
2070                 switch (getToken().type) {
2071                         case 'function': {
2072                                 parse_functionExpression(expressionResult);
2073                         }
2074                         break;
2075                        
2076                         case 'coroutine': {
2077                                 parse_coroutineExpression(expressionResult);
2078                         }
2079                         break;
2080                        
2081                         case 'new': {
2082                                 nextToken();
2083                                
2084                                 parse_memberExpression(expressionResult);
2085                                 generator.putExpressionResult(expressionResult);
2086                                
2087                                 var numOfArguments:Number = 0;
2088                                
2089                                 if (isToken('(')) {
2090                                         numOfArguments += parse_arguments();
2091                                 }
2092                                
2093                                 generator.putNew(numOfArguments);
2094                                
2095                                 expressionResult.setType('stack');
2096                         }
2097                         break;
2098                        
2099                         default: {
2100                                 parse_primaryExpression(expressionResult);
2101                         }
2102                 }
2103         }
2104         private function isMemberExpressionFirst (type:String) : Boolean
2105         {
2106                 return (type == 'new' || type == 'function' || isPrimaryExpressionFirst(type));
2107         }
2108        
2109         // Arguments ::= '(' ')'
2110         //      ::= '(' ArgumentList ')'
2111         //
2112         // First(Arguments) ::= '('
2113         private function parse_arguments () : Number
2114         {
2115                 if (!isToken('(')) {
2116                         syntaxError('呼び出し引数で"("が無い');
2117                 }
2118                
2119                 var numOfArguments:Number = 0;
2120                
2121                 if (!isNextToken(')')) {
2122                         numOfArguments += parse_argumentList();
2123                 }
2124                
2125                 if (!isToken(')')) {
2126                         syntaxError('呼び出し引数で")"が無い');
2127                 }
2128                 nextToken();
2129                
2130                 return numOfArguments;
2131         }
2132        
2133         // ArgumentList ::= AssignmentExpression
2134         //      ::= ArgumentList ',' AssignmentExpression
2135         //
2136         // First(ArgumentList) ::= First(AssignmentExpression)
2137         private function parse_argumentList () : Number
2138         {
2139                 var numOfArguments:Number = 0;
2140                
2141                 for (;;) {
2142                         var expressionResult:ExpressionResult = new ExpressionResult();
2143                         parse_assignmentExpression(expressionResult);
2144                         generator.putExpressionResult(expressionResult);
2145                         generator.putPush(expressionResult);
2146                        
2147                         numOfArguments++;
2148                        
2149                         if (isToken(',')) {
2150                                 nextToken();
2151                                 continue;
2152                         }
2153                         break;
2154                 }
2155                
2156                 return numOfArguments;
2157         }
2158        
2159        
2160         // PrimaryExpression ::= 'this'
2161         //      ::= Identifier
2162         //      ::= Literal
2163         //      ::= ArrayLiteral
2164         //      ::= ObjectLiteral
2165         //      ::= '(' Expression ')'
2166         //
2167         // First(PrimaryExpression) ::= 'this' Identifier Literal First(ArrayLiteral) First(ObjectLiteral) '('
2168         private function parse_primaryExpression (expressionResult:ExpressionResult) : Void
2169         {
2170                 switch (getToken().type) {
2171                         case 'this': {
2172                                 generator.putThis();
2173                                 expressionResult.setType('stack');
2174                                 nextToken();
2175                         }
2176                         break;
2177                        
2178                         case 'identifier': {
2179                                 expressionResult.setTypeAndValue('variable', getToken().value);
2180                                 nextToken();
2181                         }
2182                         break;
2183                        
2184                         case 'string':
2185                         case 'number':
2186                         case 'bool':
2187                         case 'null':
2188                         case 'undefined': {
2189                                 expressionResult.setTypeAndValue('literal', getToken().value);
2190                                 nextToken();
2191                         }
2192                         break;
2193                        
2194                         case '[': {
2195                                 var numOfElements:Number = parse_arrayLiteral();
2196                                 generator.putArrayLiteral(numOfElements);
2197                                 expressionResult.setType('stack');
2198                         }
2199                         break;
2200                        
2201                         case '{': {
2202                                 var numOfProperties:Number = parse_objectLiteral();
2203                                 generator.putObjectLiteral(numOfProperties);
2204                                 expressionResult.setType('stack');
2205                         }
2206                         break;
2207                        
2208                         case '(': {
2209                                 nextToken();
2210                                 parse_expression(expressionResult);
2211                                 if (!isToken(')')) {
2212                                         syntaxError('式で")"を忘れている');
2213                                 }
2214                                 nextToken();
2215                         }
2216                         break;
2217                        
2218                         default: {
2219                                 syntaxError('式中に謎のトークン');
2220                         }
2221                         break;
2222                 }
2223         }
2224         private function isPrimaryExpressionFirst (type:String) : Boolean
2225         {
2226                 return (type == 'this' || type == 'identifier' ||
2227                         type == 'string' || type == 'number' || type == 'bool' || type == 'undefined' ||
2228                         type == 'null' || type == '{' || type == '[' || type == '('
2229                         );
2230         }
2231        
2232         // ArrayLiteral ::= '[' Elision? ']'
2233         //      ::= '[' ElementList ']'
2234         //      ::= '[' ElementList ',' Elision? ']'
2235         //
2236         // First(ArrayLiteral) ::= '['
2237         private function parse_arrayLiteral () : Number
2238         {
2239                 if (!isToken('[')) {
2240                         syntaxError('配列初期化子で"["が無い??');
2241                 }
2242                
2243                 var numOfElements:Number = 0;
2244                
2245                 if (!isNextToken(']')) {
2246                         if (isToken(',')) {
2247                                 numOfElements += parse_elision();
2248                         }
2249                        
2250                         if (!isToken(']')) {
2251                                 numOfElements += parse_elementList();
2252                         }
2253                        
2254                         if (isToken(',')) {
2255                                 numOfElements += parse_elision();
2256                         }
2257                 }
2258                 if (!isToken(']')) {
2259                         syntaxError('配列初期化子で"]"を忘れている');
2260                 }
2261                 nextToken();
2262                
2263                 return numOfElements;
2264         }
2265        
2266         // Elision ::= ','
2267         //      ::= Elision ','
2268         //
2269         // First(Elision) ::= ','
2270         private function parse_elision () : Number
2271         {
2272                 if (!isToken(',')) {
2273                         syntaxError('Elisionで","が無い??');
2274                 }
2275                
2276                 var numOfElements:Number = 1;
2277                
2278                 var undefinedLiteral:ExpressionResult = ExpressionResult.createLiteral(undefined);
2279                
2280                 for (;;) {
2281                         generator.putPush(undefinedLiteral);
2282                         numOfElements++;
2283                        
2284                         if (isNextToken(',')) {
2285                                 continue;
2286                         }
2287                         break;
2288                 }
2289                
2290                 if (isToken(']')) {
2291                         generator.putPush(undefinedLiteral);
2292                         numOfElements++;
2293                 }
2294                
2295                 return numOfElements;
2296         }
2297        
2298         // ElementList ::= Elision? AssignmentExpression
2299         //      ::= ElementList ',' Elision? AssignmentExpression
2300         //
2301         // First(ElementList) ::= First(Elision) First(AssignmentExpression)
2302         private function parse_elementList () : Number
2303         {
2304                 var numOfElements:Number = 0;
2305                
2306                 for (;;) {
2307                         if (isToken(',')) {
2308                                 numOfElements += parse_elision();
2309                                 continue;
2310                         }
2311                         if (isToken(']')) {
2312                                 break;
2313                         }
2314                        
2315                         var expressionResult:ExpressionResult = new ExpressionResult();
2316                         parse_assignmentExpression(expressionResult);
2317                         generator.putExpressionResult(expressionResult);
2318                         generator.putPush(expressionResult);
2319                        
2320                         numOfElements++;
2321                        
2322                         if (isToken(',')) {
2323                                 nextToken();
2324                                 continue;
2325                         }
2326                         break;
2327                 }
2328                
2329                 return numOfElements;
2330         }
2331        
2332         // ObjectLiteral ::= '{' '}'
2333         //      ::= '{' PropertyNameAndValueList '}'
2334         //
2335         // First(ObjectLiteral) ::= '{'
2336         private function parse_objectLiteral () : Number
2337         {
2338                 if (!isToken('{')) {
2339                         syntaxError('オブジェクト初期化子で"{"が無い??');
2340                 }
2341                
2342                 var numOfProperties:Number = 0;
2343                
2344                 if (!isNextToken('}')) {
2345                         numOfProperties += parse_propertyNameAndValueList();
2346                 }
2347                
2348                 if (!isToken('}')) {
2349                         syntaxError('オブジェクト初期化子で"}"を忘れている');
2350                 }
2351                 nextToken();
2352                
2353                 return numOfProperties;
2354         }
2355        
2356         // PropertyNameAndValueList ::= PropertyName ':' AssignmentExpression
2357         //      ::= PropertyNameAndValueList ',' PropertyName ':' AssignmentExpression
2358         //
2359         // First(PropertyNameAndValueList) ::= First(PropertyName)
2360         private function parse_propertyNameAndValueList () : Number
2361         {
2362                 var numOfProperties:Number = 0;
2363                
2364                 for (;;) {
2365                         parse_propertyName();
2366                        
2367                         if (!isToken(':')) {
2368                                 syntaxError('オブジェクト初期化子で":"が無い');
2369                         }
2370                         nextToken();
2371                        
2372                         var expressionResult:ExpressionResult = new ExpressionResult();
2373                         parse_assignmentExpression(expressionResult);
2374                         generator.putExpressionResult(expressionResult);
2375                         generator.putPush(expressionResult);
2376                        
2377                         numOfProperties++;
2378                        
2379                         if (isToken(',')) {
2380                                 nextToken();
2381                                 continue;
2382                         }
2383                         break;
2384                 }
2385                
2386                 return numOfProperties;
2387         }
2388        
2389         // PropertyName ::= Identifier
2390         //      ::= StringLiteral
2391         //      ::= NumericLiteral
2392         //
2393         // First(PropertyName) ::= Identifier StringLiteral NumericLiteral
2394         private function parse_propertyName () : Void
2395         {
2396                 switch (getToken().type) {
2397                         case 'identifier':
2398                         case 'string':
2399                         case 'number': {
2400                                 var propertyName:ExpressionResult = ExpressionResult.createLiteral(getToken().value);
2401                                
2402                                 generator.putPush(propertyName);
2403                                
2404                                 nextToken();
2405                         }
2406                         break;
2407                        
2408                         default: {
2409                                 syntaxError('プロパティ名で謎のトークン');
2410                         }
2411                         break;
2412                 }
2413         }
2414 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。