Changeset 22626

Show
Ignore:
Timestamp:
11/03/08 18:38:22 (5 years ago)
Author:
fujidig
Message:

いちいちbreakせずにfall-throughで落ちていくように

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/javascript/hsp-on-js/branches/source-convert/src/evaluator.js

    r22575 r22626  
    6767                        lines.push(Utils.strTimes('\t', indent) + line); 
    6868                } 
     69                function pushJumpSubroutineCode(posExpr) { 
     70                        push('if(self.frameStack.length >= 256) {'); 
     71                        push('  throw new HSPError(ErrorCode.STACK_OVERFLOW);'); 
     72                        push('}'); 
     73                        push('self.frameStack.push(new Frame(self.pc + 1, null, null));'); 
     74                        push('self.pc = '+posExpr+';'); 
     75                } 
    6976                var lines = []; 
    7077                var indent = 0; 
    7178                var sequence = this.sequence; 
    72                 var operateMethodNames = 'add,sub,mul,div,mod,and,or,xor,eq,ne,gt,lt,gteq,lteq,rsh,lsh'.split(',');  
     79                var operateMethodNames = 'add,sub,mul,div,mod,and,or,xor,eq,ne,gt,lt,gteq,lteq,rsh,lsh'.split(','); 
     80                 
    7381                push('for(;;) {'); indent ++; 
    7482                push('switch(self.pc) {'); 
     
    115123                                break; 
    116124                        case Instruction.Code.GOTO: 
    117                                 push('self.pc = '+(insn.opts[0].pos - 1)+';'); 
     125                                push('self.pc = '+insn.opts[0].pos+';'); 
     126                                push('continue;'); 
    118127                                break; 
    119128                        case Instruction.Code.IFNE: 
    120129                                push('if(stack.pop().toIntValue()._value) {'); 
    121                                 push('    self.pc = '+(insn.opts[0].pos - 1)+';'); 
     130                                push('    self.pc = '+insn.opts[0].pos+';'); 
     131                                push('    continue;'); 
    122132                                push('}'); 
    123133                                break; 
    124134                        case Instruction.Code.IFEQ: 
    125135                                push('if(!stack.pop().toIntValue()._value) {'); 
    126                                 push('    self.pc = '+(insn.opts[0].pos - 1)+';'); 
     136                                push('    self.pc = '+insn.opts[0].pos+';'); 
     137                                push('    continue;'); 
    127138                                push('}'); 
    128139                                break; 
     
    180191                                push('self.callUserDefFunc(userDefFuncs['+userDefFunc.id+'], '+ 
    181192                                         'Utils.aryPopN(stack, '+argc+'));'); 
     193                                push('self.pc ++;'); 
     194                                push('continue;'); 
    182195                                break; 
    183196                        case Instruction.Code.GETARG: 
     
    222235                                        } 
    223236                                        push('self.callUserDefFunc(userDefFuncs['+module.constructor.id+'], args);'); 
     237                                        push('self.pc ++;'); 
     238                                        push('continue;'); 
    224239                                } else if(argc > 1) { 
    225240                                        push('throw new HSPError(ErrorCode.TOO_MANY_PARAMETERS);') 
     
    232247                                        push('self.return_();'); 
    233248                                } 
     249                                push('self.pc ++;'); 
     250                                push('continue;'); 
    234251                                break; 
    235252                        case Instruction.Code.DELMOD: 
     
    239256                                push('}'); 
    240257                                push('self.deleteStruct(v);'); 
     258                                push('self.pc ++;'); 
     259                                push('continue;'); 
    241260                                break; 
    242261                        case Instruction.Code.REPEAT: 
     
    257276                                        push('var end = Infinity;'); 
    258277                                } 
    259                                 push('if(end == 0) {'); indent ++; 
    260                                 push('self.pc = '+(pos - 1)+';'); 
    261                                 push('break;'); 
    262                                 indent --; push('}'); 
     278                                push('if(end == 0) {'); 
     279                                push('    self.pc = '+pos+';'); 
     280                                push('    continue;'); 
     281                                push('}'); 
    263282                                push('end += begin;'); 
    264283                                push('self.loopStack.push(new LoopData(begin, end, '+(pc + 1)+'));'); 
     
    270289                                push('var data = self.loopStack[self.loopStack.length - 1];'); 
    271290                                push('data.cnt ++;'); 
    272                                 push('if(data.cnt >= data.end) {'); indent ++; 
     291                                push('if(data.cnt < data.end) {'); 
     292                                push('    self.pc = data.pc;'); 
     293                                push('    continue;'); 
     294                                push('}'); 
    273295                                push('self.loopStack.pop();'); 
    274                                 push('break;'); 
    275                                 indent --; push('}'); 
    276                                 push('self.pc = data.pc - 1;'); 
    277296                                break; 
    278297                        case Instruction.Code.CNT: 
    279298                                push('if(self.loopStack.length == 0) {'); 
    280299                                push('    stack.push(new IntValue(0));'); 
    281                                 push('    break;'); 
    282                                 push('}'); 
    283                                 push('stack.push(new IntValue(self.loopStack[self.loopStack.length - 1].cnt));'); 
     300                                push('} else {'); 
     301                                push('    stack.push(new IntValue(self.loopStack[self.loopStack.length - 1].cnt));'); 
     302                                push('}'); 
    284303                                break; 
    285304                        case Instruction.Code.CONTINUE: 
     
    298317                                push('if('+newCntExpr+' >= data.end) {'); 
    299318                                push('    self.loopStack.pop();'); 
    300                                 push('    self.pc = ' + (label.pos - 1)+';'); 
    301                                 push('    break;'); 
    302                                 push('}'); 
    303                                 push('self.pc = data.pc - 1;'); 
     319                                push('    self.pc = '+pos+';'); 
     320                                push('} else {'); 
     321                                push('    self.pc = data.pc;'); 
     322                                push('}'); 
     323                                push('continue;'); 
    304324                                break; 
    305325                        case Instruction.Code.BREAK: 
     
    309329                                push('}'); 
    310330                                push('self.loopStack.pop();'); 
    311                                 push('self.pc = '+(label.pos - 1)+';'); 
     331                                push('self.pc = '+label.pos+';'); 
     332                                push('continue;'); 
    312333                                break; 
    313334                        case Instruction.Code.FOREACH: 
     
    326347                                push('if(data.cnt >= v.variable.getL0()) {') 
    327348                                push('    self.loopStack.pop();'); 
    328                                 push('    self.pc = '+(pos - 1)+';'); 
    329                                 push('    break;'); 
     349                                push('    self.pc = '+pos+';'); 
     350                                push('    continue;'); 
    330351                                push('}'); 
    331352                                push('if(v.variable.at([data.cnt]).isUsing() == false) {'); // label 型 や struct 型の empty を飛ばす 
     
    333354                                push('    if(data.cnt >= data.end) {'); 
    334355                                push('        self.loopStack.pop();'); 
    335                                 push('        self.pc = '+(pos - 1)+';'); 
    336                                 push('        break;'); 
     356                                push('        self.pc = '+pos+';'); 
     357                                push('    } else {'); 
     358                                push('        self.pc = data.pc - 1;'); 
    337359                                push('    }'); 
    338                                 push('    self.pc = data.pc - 1;'); 
     360                                push('    continue;'); 
    339361                                push('}'); 
    340362                                break; 
    341363                        case Instruction.Code.GOSUB: 
    342                                 push('self.subroutineJump('+insn.opts[0].pos+');'); 
     364                                pushJumpSubroutineCode(insn.opts[0].pos); 
     365                                push('continue;'); 
    343366                                break; 
    344367                        case Instruction.Code.GOTO_EXPR: 
    345                                 push('self.pc = self.scanArg(stack.pop(), "l").toValue().pos - 1;'); 
     368                                push('self.pc = self.scanArg(stack.pop(), "l").toValue().pos;'); 
     369                                push('continue;'); 
    346370                                break; 
    347371                        case Instruction.Code.GOSUB_EXPR: 
    348                                 push('self.subroutineJump(self.scanArg(stack.pop(), "l").toValue().pos);'); 
     372                                pushJumpSubroutineCode('self.scanArg(stack.pop(), "l").toValue().pos'); 
     373                                push('continue;'); 
    349374                                break; 
    350375                        case Instruction.Code.EXGOTO: 
     
    354379                                push('var a = self.scanArg(self.scanArg(stack.pop(), "v"), "i").toIntValue()._value;'); 
    355380                                push('if(mode >= 0) {'); 
    356                                 push('  if(a >= b) self.pc = pos - 1;'); 
     381                                push('  if(a >= b) { self.pc = pos; continue; }'); 
    357382                                push('} else {'); 
    358                                 push('  if(a <= b) self.pc = pos - 1;'); 
     383                                push('  if(a <= b) { self.pc = pos; continue; }'); 
    359384                                push('}'); 
    360385                                break; 
     
    365390                                push('var mode = self.scanArg(stack.pop(), "n").toIntValue()._value;'); 
    366391                                push('if(mode >= 0) {'); 
    367                                 push('  if(a >= b) self.pc = '+(pos - 1)+';'); 
     392                                push('  if(a >= b) { self.pc = '+pos+'; continue; }'); 
    368393                                push('} else {'); 
    369                                 push('  if(a <= b) self.pc = '+(pos - 1)+';'); 
     394                                push('  if(a <= b) { self.pc = '+pos+'; continue; }'); 
    370395                                push('}'); 
    371396                                break; 
     
    374399                                push('var a = self.scanArg(variables['+insn.opts[0]+'].at(0), "i").toIntValue()._value;'); 
    375400                                push('var b = self.scanArg(stack.pop(), "n").toIntValue()._value;'); 
    376                                 push('if(a >= b) self.pc = '+(pos - 1)+';'); 
     401                                push('if(a >= b) { self.pc = '+pos+'; continue; }'); 
    377402                                break; 
    378403                        case Instruction.Code.EXGOTO_OPT3: 
     
    380405                                push('var a = self.scanArg(variables['+insn.opts[0]+'].at(0), "i").toIntValue()._value;'); 
    381406                                push('var b = self.scanArg(stack.pop(), "n").toIntValue()._value;'); 
    382                                 push('if(a <= b) self.pc = '+(pos - 1)+';'); 
     407                                push('if(a <= b) { self.pc = '+pos+'; continue; }'); 
    383408                                break; 
    384409                        case Instruction.Code.ON: 
     
    394419                                push('stack.length -= '+(argc + 1)+';'); 
    395420                                if(isGosub) { 
    396                                         push('self.subroutineJump(pos);'); 
     421                                        pushJumpSubroutineCode('pos'); 
     422                                        push('continue;'); 
    397423                                } else { 
    398                                         push('self.pc = pos - 1;'); 
     424                                        push('self.pc = pos;'); 
     425                                        push('continue;'); 
    399426                                } 
    400427                                break; 
     
    402429                                throw new Error("未対応の命令コード: "+insn.code); 
    403430                        } 
    404                         push('break;'); 
     431                        push('self.pc ++;'); 
    405432                        indent --; 
    406433                } 
    407434                push('}'); 
    408                 push('self.pc ++;'); 
    409435                indent --; push('}'); 
    410436                //print(lines.join("\n")); 
     
    519545                        runCallback(); 
    520546                } 
    521         }, 
    522         subroutineJump: function subroutineJump(pos) { 
    523                 if(this.frameStack.length >= 256) { 
    524                         throw new HSPError(ErrorCode.STACK_OVERFLOW); 
    525                 } 
    526                 this.frameStack.push(new Frame(this.pc + 1, null, null)); 
    527                 this.pc = pos - 1; 
    528547        }, 
    529548        popIndices: function popIndices(argc) {