Changeset 22454
- Timestamp:
- 11/01/08 00:02:06 (5 years ago)
- Location:
- lang/javascript/hsp-on-js/trunk/src
- Files:
-
- 4 modified
-
builtin-funcs.js (modified) (2 diffs)
-
compiler.js (modified) (3 diffs)
-
evaluator.js (modified) (4 diffs)
-
instruction.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
lang/javascript/hsp-on-js/trunk/src/builtin-funcs.js
r22332 r22454 7 7 8 8 BuiltinFuncs[Token.Type.PROGCMD] = { 9 0x00: function goto_(label) {10 this.scanArgs(arguments, 'l');11 this.pc = label.toValue().pos - 1;12 },13 0x01: function gosub(label) {14 this.scanArgs(arguments, 'l');15 this.subroutineJump(label.toValue());16 },17 9 0x07: function wait(n) { 18 10 this.scanArgs(arguments, 'N'); … … 68 60 default: 69 61 throw new HSPError(ErrorCode.UNSUPPORTED_FUNCTION); 70 }71 },72 0x18: function exgoto(v, mode, b, label) {73 this.scanArgs(arguments, 'vnnl');74 this.scanArg(v, 'i');75 var a = v.toIntValue()._value;76 mode = mode.toIntValue()._value;77 b = b.toIntValue()._value;78 label = label.toValue();79 if(mode >= 0) {80 if(a >= b) {81 this.pc = label.pos - 1;82 }83 } else {84 if(a <= b) {85 this.pc = label.pos - 1;86 }87 }88 },89 0x19: function on(n, jumpType) {90 this.scanArgs(arguments, 'Njl*');91 n = n ? n.toIntValue()._value : 0;92 if(!(0 <= n && n < arguments.length - 2)) {93 return;94 }95 var label = arguments[n + 2].toValue();96 if(jumpType == JumpType.GOTO) {97 this.pc = label.pos - 1;98 } else {99 this.subroutineJump(label);100 62 } 101 63 } -
lang/javascript/hsp-on-js/trunk/src/compiler.js
r22332 r22454 127 127 this.tokensPos += 2; 128 128 } else { 129 this.compileCommand(sequence); 129 this.tokensPos ++; 130 var argc = this.compileParameters(sequence); 131 if(argc != 1) throw this.error('goto の引数の数が違います', token); 132 this.pushNewInsn(sequence, Instruction.Code.GOTO_EXPR, [], token); 133 } 134 break; 135 case 0x01: // gosub 136 var labelToken = this.ax.tokens[this.tokensPos + 1]; 137 if(labelToken && labelToken.type == Token.Type.LABEL && !labelToken.ex2 && (!this.ax.tokens[this.tokensPos + 2] || this.ax.tokens[this.tokensPos + 2].ex1)) { 138 this.pushNewInsn(sequence, Instruction.Code.GOSUB, 139 [this.labels[labelToken.code]]); 140 this.tokensPos += 2; 141 } else { 142 this.tokensPos ++; 143 var argc = this.compileParameters(sequence); 144 if(argc != 1) throw this.error('gosub の引数の数が違います', token); 145 this.pushNewInsn(sequence, Instruction.Code.GOSUB_EXPR, [], token); 130 146 } 131 147 break; … … 219 235 if(argc != 1) throw this.error('delmod の引数の数が違います', token); 220 236 this.pushNewInsn(sequence, Instruction.Code.DELMOD, [], token); 237 break; 238 case 0x18: // exgoto 239 this.tokensPos ++; 240 // exgoto <添字指定のない静的変数>, p2, p3, <ラベルリテラル> を最適化 241 var pos = this.tokensPos; 242 var varToken = this.ax.tokens[pos]; 243 if(!varToken.ex1 && !varToken.ex2 && 244 varToken.type == Token.Type.VAR && this.ax.tokens[pos + 1].ex2) { 245 pos ++; 246 var secondParamPos = pos; 247 pos += this.skipParameter(pos); 248 var thirdParamPos = pos; 249 pos += this.skipParameter(pos); 250 var labelToken = this.ax.tokens[pos]; 251 if(labelToken && !labelToken.ex1 && 252 labelToken.type == Token.Type.LABEL && this.ax.tokens[pos+1]) { 253 // p2 が整数リテラルの場合はさらに最適化 254 if(secondParamPos + 1 == thirdParamPos && this.ax.tokens[secondParamPos].type == Token.Type.INUM) { 255 this.tokensPos = thirdParamPos; 256 this.compileParameter(sequence); 257 if(this.ax.tokens[secondParamPos].code >= 0) { 258 this.pushNewInsn(sequence, Instruction.Code.EXGOTO_OPT2, 259 [varToken.code, this.labels[labelToken.code]], token); 260 } else { 261 this.pushNewInsn(sequence, Instruction.Code.EXGOTO_OPT3, 262 [varToken.code, this.labels[labelToken.code]], token); 263 } 264 this.tokensPos = pos + 1; 265 break; 266 } 267 this.tokensPos = secondParamPos; 268 this.compileParameter(sequence); 269 this.compileParameter(sequence); 270 this.pushNewInsn(sequence, Instruction.Code.EXGOTO_OPT1, 271 [varToken.code, this.labels[labelToken.code]], token); 272 this.tokensPos = pos + 1; 273 break; 274 } 275 } 276 var argc = this.compileParameters(sequence); 277 if(argc != 4) throw this.error('exgoto の引数の数が違います', token); 278 this.pushNewInsn(sequence, Instruction.Code.EXGOTO, [], token); 279 break; 280 case 0x19: // on 281 this.tokensPos ++; 282 var paramToken = this.ax.tokens[this.tokensPos]; 283 if(paramToken.ex1 || paramToken.ex2) { 284 throw this.error('パラメータは省略できません', token); 285 } 286 this.compileParameter(sequence); 287 var jumpTypeToken = this.ax.tokens[this.tokensPos]; 288 if(jumpTypeToken.ex1 || jumpTypeToken.type != Token.Type.PROGCMD || jumpTypeToken.code > 1) { 289 throw this.error('goto / gosub が指定されていません', token); 290 } 291 var isGosub = jumpTypeToken.code == 1; 292 this.tokensPos ++; 293 var argc = this.compileParametersSub(sequence); 294 this.pushNewInsn(sequence, Instruction.Code.ON, [argc, isGosub], token); 221 295 break; 222 296 default: … … 347 421 token = this.ax.tokens[this.tokensPos]; 348 422 if(token && token.ex2) return; 423 } 424 }, 425 skipParameter: function skipParameter(pos) { 426 var size = 0; 427 var parenLevel = 0; 428 while(true) { 429 var token = this.ax.tokens[pos + size]; 430 if(!token || token.ex1) return size; 431 if(token.type == Token.Type.MARK) { 432 switch(token.val) { 433 case 40: 434 parenLevel ++; 435 break; 436 case 41: 437 if(parenLevel == 0) return size; 438 parenLevel --; 439 if(parenLevel == 0) return size + 1; 440 break; 441 case 63: 442 return size + 1; 443 break; 444 } 445 } 446 size ++; 447 token = this.ax.tokens[pos + size]; 448 if(parenLevel == 0 && token && token.ex2) { 449 return size; 450 } 349 451 } 350 452 }, -
lang/javascript/hsp-on-js/trunk/src/evaluator.js
r22332 r22454 389 389 } 390 390 break; 391 case Instruction.Code.GOSUB: 392 this.subroutineJump(insn.opts[0].pos); 393 break; 394 case Instruction.Code.GOTO_EXPR: 395 this.pc = this.scanArg(this.stack.pop(), 'l').toValue().pos - 1; 396 break; 397 case Instruction.Code.GOSUB_EXPR: 398 this.subroutineJump(this.scanArg(this.stack.pop(), 'l').toValue().pos); 399 break; 400 case Instruction.Code.EXGOTO: 401 var pos = this.scanArg(this.stack.pop(), 'l').toValue().pos; 402 var b = this.scanArg(this.stack.pop(), 'n').toIntValue()._value; 403 var mode = this.scanArg(this.stack.pop(), 'n').toIntValue()._value; 404 var a = this.scanArg(this.scanArg(this.stack.pop(), 'v'), 'i').toIntValue()._value; 405 if(mode >= 0) { 406 if(a >= b) this.pc = pos - 1; 407 } else { 408 if(a <= b) this.pc = pos - 1; 409 } 410 break; 411 case Instruction.Code.EXGOTO_OPT1: 412 var a = this.scanArg(this.variables[insn.opts[0]].at(0), 'i').toIntValue()._value; 413 var pos = insn.opts[1].pos; 414 var b = this.scanArg(this.stack.pop(), 'n').toIntValue()._value; 415 var mode = this.scanArg(this.stack.pop(), 'n').toIntValue()._value; 416 if(mode >= 0) { 417 if(a >= b) this.pc = pos - 1; 418 } else { 419 if(a <= b) this.pc = pos - 1; 420 } 421 break; 422 case Instruction.Code.EXGOTO_OPT2: 423 var a = this.scanArg(this.variables[insn.opts[0]].at(0), 'i').toIntValue()._value; 424 var pos = insn.opts[1].pos; 425 var b = this.scanArg(this.stack.pop(), 'n').toIntValue()._value; 426 if(a >= b) this.pc = pos - 1; 427 break; 428 case Instruction.Code.EXGOTO_OPT3: 429 var a = this.scanArg(this.variables[insn.opts[0]].at(0), 'i').toIntValue()._value; 430 var pos = insn.opts[1].pos; 431 var b = this.scanArg(this.stack.pop(), 'n').toIntValue()._value; 432 if(a <= b) this.pc = pos - 1; 433 break; 434 case Instruction.Code.ON: 435 var argc = insn.opts[0]; 436 var isGosub = insn.opts[1]; 437 for(var i = this.stack.length - argc, l = this.stack.length; i < l; i ++) { 438 this.scanArg(this.stack[i], 'l'); 439 } 440 var n = this.scanArg(this.stack[this.stack.length - argc - 1], 'n').toIntValue()._value; 441 if(!(0 <= n && n < argc)) break; 442 var pos = this.stack[this.stack.length - argc + n].toValue().pos; 443 this.stack.length -= argc + 1; 444 if(isGosub) { 445 this.subroutineJump(pos); 446 } else { 447 this.pc = pos - 1; 448 } 449 break; 391 450 default: 392 451 throw new Error("未対応の命令コード: "+insn.code); … … 465 524 this.pc = userDefFunc.label.pos - 1; 466 525 }, 467 subroutineJump: function subroutineJump( label) {526 subroutineJump: function subroutineJump(pos) { 468 527 if(this.frameStack.length >= 256) { 469 528 throw new HSPError(ErrorCode.STACK_OVERFLOW); 470 529 } 471 530 this.frameStack.push(new Frame(this.pc + 1, null, null)); 472 this.pc = label.pos - 1;531 this.pc = pos - 1; 473 532 }, 474 533 popIndices: function popIndices(argc) { … … 654 713 if(arg == undefined) { 655 714 if(isOptionalArguments) { 656 return ;715 return arg; 657 716 } else { 658 717 throw new HSPError(ErrorCode.NO_DEFAULT); … … 708 767 break; 709 768 } 769 return arg; 710 770 } 711 771 }; -
lang/javascript/hsp-on-js/trunk/src/instruction.js
r22332 r22454 56 56 'BREAK', 57 57 'FOREACH', 58 'EACHCHK' 58 'EACHCHK', 59 'GOSUB', 60 'GOTO_EXPR', 61 'GOSUB_EXPR', 62 'EXGOTO', 63 'EXGOTO_OPT1', 64 'EXGOTO_OPT2', 65 'EXGOTO_OPT3', 66 'ON' 59 67 ]; 60 68
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)