Changeset 28609
- Timestamp:
- 01/18/09 20:15:05 (4 years ago)
- Location:
- lang/javascript/hsp-on-js/trunk/src
- Files:
-
- 3 modified
-
compiler.js (modified) (11 diffs)
-
evaluator.js (modified) (20 diffs)
-
param-info.js (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lang/javascript/hsp-on-js/trunk/src/compiler.js
r28581 r28609 138 138 var varData = this.getVariableData(true); 139 139 ++ this.tokensPos; 140 var index ParamInfos = this.compileNodes(sequence, this.getVariableSubscriptNodes());140 var indexNodes = this.getVariableSubscriptNodes(); 141 141 var token = this.ax.tokens[this.tokensPos++]; 142 142 if(!(token && token.type == Token.Type.MARK)) { 143 143 throw this.error(); 144 144 } 145 if(this.ax.tokens[this.tokensPos].ex1) { 146 if(token.val == 0) { // インクリメント 147 this.pushNewInsn(sequence, Instruction.Code.INC, [varData, indexParamInfos], token); 148 return; 149 } 150 if(token.val == 1) { // デクリメント 151 this.pushNewInsn(sequence, Instruction.Code.DEC, [varData, indexParamInfos], token); 152 return; 153 } 154 } 145 if(this.ax.tokens[this.tokensPos].ex1 && (token.val == 0 || token.val == 1)) { 146 // インクリメント / デクリメント 147 var indexParamInfos = this.compileNodes(sequence, indexNodes); 148 this.pushNewInsn(sequence, Instruction.Code.INC + token.val, [varData, indexParamInfos], token); 149 return; 150 } 151 var rhsParamInfos = this.compileParameters(sequence, true, true); 152 var indexParamInfos = this.compileNodes(sequence, indexNodes); 155 153 if(token.val != 8) { // CALCCODE_EQ 156 154 // 複合代入 157 var rhsParamInfos = this.compileParameters(sequence, true, true);158 155 if(rhsParamInfos.length != 1) { 159 156 throw this.error("複合代入のパラメータの数が間違っています。", token); … … 162 159 return; 163 160 } 164 var rhsParamInfos = this.compileParameters(sequence, true, true);165 161 if(rhsParamInfos.length == 0) { 166 162 throw this.error("代入のパラメータの数が間違っています。", token); … … 271 267 throw this.error('パラメータは省略できません'); 272 268 } 273 var var ParamInfo = this.compileNode(sequence, this.getVarNode(true, false));269 var varNode = this.getVarNode(true, false); 274 270 var structToken = this.ax.tokens[this.tokensPos++]; 275 271 var prmInfo = this.ax.prmsInfo[structToken.code]; … … 287 283 } 288 284 this.pushNewInsn(sequence, Instruction.Code.NEWMOD, 289 [ varParamInfo, module, paramInfos, argc], token);285 [this.compileNode(sequence, varNode), module, paramInfos, argc], token); 290 286 break; 291 287 case 0x18: // exgoto … … 301 297 throw this.error('パラメータは省略できません', token); 302 298 } 303 var posHead = this.tokensPos; 304 this.tokensPos += this.skipParameter(this.tokensPos); 299 var indexParamInfo = this.compileParameter(sequence); 305 300 var jumpTypeToken = this.ax.tokens[this.tokensPos]; 306 301 if(jumpTypeToken.ex1 || jumpTypeToken.type != Token.Type.PROGCMD || jumpTypeToken.code > 1) { … … 310 305 this.tokensPos ++; 311 306 var labelParamInfos = this.compileParametersSub(sequence); 312 var posFoot = this.tokensPos;313 this.tokensPos = posHead;314 var indexParamInfo = this.compileParameter(sequence);315 this.tokensPos = posFoot;316 307 this.pushNewInsn(sequence, Instruction.Code.ON, [isGosub, labelParamInfos, indexParamInfo], token); 317 308 break; … … 396 387 var len = result.length; 397 388 this.getParametersNodes0(cannotBeOmitted, notReceiveVar, result, isHead); 398 for(var i = len; i < result.length; i ++) {389 for(var i = result.length - 1; i >= len; i --) { 399 390 result[i] = this.compileNode(sequence, result[i]); 400 391 } … … 406 397 compileNodes: function compileNodes(sequence, nodes) { 407 398 var paramInfos = []; 408 for(var i = 0; i < nodes.length; i ++) {399 for(var i = nodes.length - 1; i >= 0; i --) { 409 400 paramInfos[i] = this.compileNode(sequence, nodes[i]); 410 401 } … … 421 412 case NodeType.VAR: 422 413 if(node.indexNodes.length > 0) { 423 parent[propname] = new GetStackNode(stackSize++, node); 414 parent[propname] = new GetStackNode(node); 415 stackSize ++; 424 416 self.pushNewInsn(sequence, 425 417 node.onlyValue ? Instruction.Code.GET_VAR : Instruction.Code.PUSH_VAR, … … 435 427 break; 436 428 case NodeType.OPERATE: 429 traverse(node, 'rhsNode'); 437 430 traverse(node, 'lhsNode'); 438 traverse(node, 'rhsNode');439 431 break; 440 432 case NodeType.USERDEF_FUNCALL: 441 parent[propname] = new GetStackNode(stackSize++, node); 433 parent[propname] = new GetStackNode(node); 434 stackSize ++; 442 435 var paramInfos = self.compileNodes(sequence, node.paramNodes); 443 436 self.pushNewInsn(sequence, … … 447 440 break; 448 441 case NodeType.BUILTIN_FUNCALL: 449 parent[propname] = new GetStackNode(stackSize++, node); 442 parent[propname] = new GetStackNode(node); 443 stackSize ++; 450 444 var paramInfos = self.compileNodes(sequence, node.paramNodes); 451 445 if(node.groupId == Token.Type.SYSVAR && node.subId == 0x04) { -
lang/javascript/hsp-on-js/trunk/src/evaluator.js
r28391 r28609 153 153 } 154 154 function pushGettingArrayValueCode(varData, indexParamInfos) { 155 var result = paramInfoGetExprBlock(indexParamInfos, function() { 156 return getArrayAndOffsetExpr(varData, indexParamInfos); 157 }); 155 var result = getArrayAndOffsetExpr(varData, indexParamInfos); 158 156 var arrayExpr = result[0]; 159 157 var offsetExpr = result[1]; … … 162 160 function pushGettingVariableCode(varData, indexParamInfos) { 163 161 var result; 164 paramInfoGetExprBlock(indexParamInfos, function() { 165 if(isVariableAgentVarData(varData)) { 166 result = getVariableAgentExpr(varData); 162 if(isVariableAgentVarData(varData)) { 163 result = getVariableAgentExpr(varData); 164 } else { 165 var variableExpr = getVariableExpr(varData); 166 if(indexParamInfos.length == 0) { 167 result = 'new VariableAgent0D('+variableExpr+')'; 168 } else if(indexParamInfos.length == 1) { 169 var paramInfo = indexParamInfos[0]; 170 push('var offset = '+getStrictIntParamNativeValueExpr(paramInfo)+';'); 171 result = 'new VariableAgent1D('+variableExpr+', offset)'; 167 172 } else { 168 var variableExpr = getVariableExpr(varData); 169 if(indexParamInfos.length == 0) { 170 result = 'new VariableAgent0D('+variableExpr+')'; 171 } else if(indexParamInfos.length == 1) { 172 var paramInfo = indexParamInfos[0]; 173 push('var offset = '+getStrictIntParamNativeValueExpr(paramInfo)+';'); 174 result = 'new VariableAgent1D('+variableExpr+', offset)'; 175 } else { 176 pushGettingIndicesCode(indexParamInfos); 177 result = 'new VariableAgentMD('+variableExpr+', indices)'; 178 } 173 pushGettingIndicesCode(indexParamInfos); 174 result = 'new VariableAgentMD('+variableExpr+', indices)'; 179 175 } 180 } );176 } 181 177 push('stack.push('+result+');'); 182 178 } 183 179 function pushAssignCode(varData, indexParamInfos, rhsParamInfos) { 184 paramInfoGetExprBlock(indexParamInfos, rhsParamInfos, function() { 185 if(isVariableAgentVarData(varData)) { 186 pushVariableAgentAssignCode(varData, rhsParamInfos); 180 if(isVariableAgentVarData(varData)) { 181 pushVariableAgentAssignCode(varData, rhsParamInfos); 182 } else { 183 push('var variable = '+getVariableExpr(varData)+';'); 184 if(indexParamInfos.length == 0) { 185 push0DAssignCode(rhsParamInfos); 186 } else if(indexParamInfos.length == 1) { 187 push1DAssignCode(indexParamInfos[0], rhsParamInfos); 187 188 } else { 188 push('var variable = '+getVariableExpr(varData)+';'); 189 if(indexParamInfos.length == 0) { 190 push0DAssignCode(rhsParamInfos); 191 } else if(indexParamInfos.length == 1) { 192 push1DAssignCode(indexParamInfos[0], rhsParamInfos); 193 } else { 194 pushMDAssignCode(indexParamInfos, rhsParamInfos); 195 } 189 pushMDAssignCode(indexParamInfos, rhsParamInfos); 196 190 } 197 } );191 } 198 192 } 199 193 function pushVariableAgentAssignCode(varData, paramInfos) { … … 205 199 push('if(agent.indices) {'); 206 200 push(' var indices = agent.indices.slice();'); 207 var pos = stackPos;208 201 for(var i = 0; i < paramInfos.length; i ++) { 209 202 push(' variable.assign(indices, '+getParamExpr(paramInfos[i])+');'); … … 214 207 push('} else {'); indent ++; 215 208 push('var offset = agent.offset;'); 216 stackPos = pos;217 209 push1DMultipleAssignCode(paramInfos); 218 210 indent --; push('}'); … … 342 334 } 343 335 function pushCompoundAssignCode(calcCode, varData, indexParamInfos, rhsParamInfo) { 344 paramInfoGetExprBlock(indexParamInfos, rhsParamInfo, function() { 345 pushCompoundAssignCode0(calcCode, varData, indexParamInfos, rhsParamInfo); 346 }); 336 pushCompoundAssignCode0(calcCode, varData, indexParamInfos, rhsParamInfo); 347 337 } 348 338 function pushIncDecCode(methodName, varData, indexParamInfos) { … … 353 343 return; 354 344 } 355 paramInfoGetExprBlock(indexParamInfos, function() { 356 push('var array = '+getVariableExpr(varData)+'.value;'); 357 if(indexParamInfos.length == 0) { 358 push('array.'+methodName+'(0);'); 359 } else if(indexParamInfos.length == 1) { 360 push('var offset = '+getStrictIntParamNativeValueExpr(indexParamInfos[0])+';'); 361 push('array.expand1D(offset);'); 362 push('array.'+methodName+'(offset);'); 363 } else { 364 pushGettingIndicesCode(indexParamInfos); 365 push('array.expand(indices);'); 366 push('var offset = array.getOffset(indices);'); 367 push('array.'+methodName+'(offset);'); 368 } 369 }); 345 push('var array = '+getVariableExpr(varData)+'.value;'); 346 if(indexParamInfos.length == 0) { 347 push('array.'+methodName+'(0);'); 348 } else if(indexParamInfos.length == 1) { 349 push('var offset = '+getStrictIntParamNativeValueExpr(indexParamInfos[0])+';'); 350 push('array.expand1D(offset);'); 351 push('array.'+methodName+'(offset);'); 352 } else { 353 pushGettingIndicesCode(indexParamInfos); 354 push('array.expand(indices);'); 355 push('var offset = array.getOffset(indices);'); 356 push('array.'+methodName+'(offset);'); 357 } 370 358 } 371 359 function pushIncCode(varData, indexParamInfos) { … … 402 390 } 403 391 push('var args = [];'); 404 paramInfoGetExprBlock(paramInfos, function() { 405 pushCallingUserdefFuncCode0(mptypes, paramInfos, constructorThismodExpr); 406 }); 392 pushCallingUserdefFuncCode0(mptypes, paramInfos, constructorThismodExpr); 407 393 push('if(this.frameStack.length >= 256) {'); 408 394 push(' throw new HSPError(ErrorCode.STACK_OVERFLOW);'); … … 543 529 return 'literals['+(literals.length - 1)+']'; 544 530 } 545 function stackSizeSum(paramInfos) {546 var sum = 0;547 for(var i = 0; i < paramInfos.length; i ++) {548 sum += paramInfos[i].stackSize;549 }550 return sum;551 }552 531 function getParamExpr(paramInfo) { 553 if(useStackPop == null) {554 throw new Error('getParamExpr without paramInfoGetExprBlock');555 }556 532 var result = getParamExpr0(paramInfo.node); 557 stackPos -= paramInfo.stackSize;558 533 return result; 559 534 } … … 577 552 return '('+getParamExpr0(node.lhsNode)+').'+getCalcCodeName(node.calcCode)+'('+getParamExpr0(node.rhsNode)+')'; 578 553 case NodeType.GET_STACK: 579 if(useStackPop) { 580 return 'stack.pop()'; 581 } 582 return 'stack[stack.length - '+(stackPos-node.offset)+']'; 554 return 'stack.pop()'; 583 555 default: 584 556 throw new Error('must not happen'); … … 672 644 return 'this.scanArg('+getParamExpr(paramInfo)+', "l").toValue().pos'; 673 645 } 674 function paramInfoGetExprBlock(/*paramInfo0, paramInfo1, ... paramInfoN, callback*/) {675 var callback = arguments[arguments.length - 1];676 var paramInfos = Array.prototype.slice.call(arguments, 0, -1);677 paramInfos = Array.prototype.concat.apply([], paramInfos); // flatten678 if(useStackPop != null) {679 throw new Error('paramInfoGetExprBlock nesting');680 }681 var sum = stackSizeSum(paramInfos);682 useStackPop = sum == 1;683 if(useStackPop) {684 sum = 0;685 }686 stackPos = sum;687 688 var result = callback();689 useStackPop = null;690 pushStackPopCode(sum);691 return result;692 }693 646 function pushStackPopCode(size) { 694 647 if(size == 0) { … … 738 691 var label = insn.opts[0]; 739 692 var paramInfo = insn.opts[1]; 740 var expr; 741 paramInfoGetExprBlock(paramInfo, function() { 742 var stackSize = stackPos; 743 expr = getParamExpr(paramInfo)+'.toIntValue()._value'; 744 if(stackSize > 0) { 745 push('var val = '+expr+';'); 746 expr = 'val'; 747 } 748 }); 693 var expr = getParamExpr(paramInfo)+'.toIntValue()._value'; 749 694 if(insn.code == Instruction.Code.IFEQ) { 750 695 expr = '!' + expr; … … 786 731 push('if(!func) throw new HSPError(ErrorCode.UNSUPPORTED_FUNCTION);'); 787 732 push('var args = [];'); 788 paramInfoGetExprBlock(paramInfos, function() { 789 for(var i = 0; i < paramInfos.length; i ++) { 790 var paramInfo = paramInfos[i]; 791 var node = paramInfo.node; 792 if(node.isDefaultNode()) { 793 push('args['+i+'] = void 0;'); 794 } else if(node.isVarNode() && !node.onlyValue) { 795 push('args['+i+'] = '+getNewVariableAgentExpr(node.varData)+';'); 796 } else { 797 push('args['+i+'] = '+getParamExpr(paramInfo)+';'); 798 } 733 for(var i = 0; i < paramInfos.length; i ++) { 734 var paramInfo = paramInfos[i]; 735 var node = paramInfo.node; 736 if(node.isDefaultNode()) { 737 push('args['+i+'] = void 0;'); 738 } else if(node.isVarNode() && !node.onlyValue) { 739 push('args['+i+'] = '+getNewVariableAgentExpr(node.varData)+';'); 740 } else { 741 push('args['+i+'] = '+getParamExpr(paramInfo)+';'); 799 742 } 800 } );743 } 801 744 if(insn.code == Instruction.Code.CALL_BUILTIN_FUNC) { 802 745 push('stack.push(func.apply(this, args));'); … … 845 788 push('}'); 846 789 if(paramInfo) { 847 paramInfoGetExprBlock(paramInfo, function() { 848 push('var val = '+getParamExpr(paramInfo)+';'); 849 }); 790 push('var val = '+getParamExpr(paramInfo)+';'); 850 791 push('var frame = this.frameStack.pop();'); 851 792 push('this.args = frame.prevArgs;'); … … 883 824 push(' throw new HSPError(ErrorCode.TOO_MANY_NEST);'); 884 825 push('}'); 885 paramInfoGetExprBlock(paramInfos, function() { 886 if(paramInfos.length >= 1 && !paramInfos[0].node.isDefaultNode()) { 887 push('var end = '+getIntParamNativeValueExpr(paramInfos[0])+';'); 888 push('if(end < 0) end = Infinity;'); 889 } else { 890 push('var end = Infinity;'); 891 } 892 if(paramInfos.length == 2) { 893 push('var begin = '+getIntParamNativeValueExpr(paramInfos[1])+';'); 894 } else { 895 push('var begin = 0;'); 896 } 897 }); 826 if(paramInfos.length >= 1 && !paramInfos[0].node.isDefaultNode()) { 827 push('var end = '+getIntParamNativeValueExpr(paramInfos[0])+';'); 828 push('if(end < 0) end = Infinity;'); 829 } else { 830 push('var end = Infinity;'); 831 } 832 if(paramInfos.length == 2) { 833 push('var begin = '+getIntParamNativeValueExpr(paramInfos[1])+';'); 834 } else { 835 push('var begin = 0;'); 836 } 898 837 push('if(end == 0) {'); 899 838 push(' this.pc = '+pos+';'); … … 929 868 push('}'); 930 869 push('var data = this.loopStack[this.loopStack.length - 1];'); 931 function pushContinueCode(newCntExpr) { 932 push('if('+newCntExpr+' >= data.end) {'); 933 push(' this.loopStack.pop();'); 934 push(' this.pc = '+pos+';'); 935 push('} else {'); 936 push(' this.pc = data.pc;'); 937 push('}'); 938 } 870 var newCntExpr; 939 871 if(paramInfo) { 940 paramInfoGetExprBlock(paramInfo, function() { 941 pushContinueCode('(data.cnt = '+getIntParamNativeValueExpr(paramInfo)+')'); 942 }); 943 } else { 944 pushContinueCode('++data.cnt'); 945 } 872 newCntExpr = '(data.cnt = '+getIntParamNativeValueExpr(paramInfo)+')'; 873 } else { 874 newCntExpr = '++data.cnt'; 875 } 876 push('if('+newCntExpr+' >= data.end) {'); 877 push(' this.loopStack.pop();'); 878 push(' this.pc = '+pos+';'); 879 push('} else {'); 880 push(' this.pc = data.pc;'); 881 push('}'); 946 882 push('continue;'); 947 883 }; … … 996 932 pushJumpingSubroutineCode(pc); 997 933 } 998 paramInfoGetExprBlock(paramInfo, function() { 999 push('this.pc = '+getLabelParamNativeValueExpr(paramInfo)+';'); 1000 }); 934 push('this.pc = '+getLabelParamNativeValueExpr(paramInfo)+';'); 1001 935 push('continue;'); 1002 936 }; … … 1014 948 var posExpr; 1015 949 var endExpr; 1016 paramInfoGetExprBlock(paramInfos, function() { 1017 push('var counter = '+getStrictIntParamNativeValueExpr(counterParamInfo)+';'); 1018 stepExpr = getIntParamNativeValueExpr(stepParamInfo); 1019 if(stepParamInfo.stackSize != 0) { 1020 push('var step = '+stepExpr+';'); 1021 stepExpr = 'step'; 1022 } 1023 endExpr = getIntParamNativeValueExpr(endParamInfo); 1024 if(endParamInfo.stackSize != 0) { 1025 push('var end = '+endExpr+';'); 1026 endExpr = 'end'; 1027 } 1028 posExpr = getLabelParamNativeValueExpr(labelParamInfo); 1029 if(labelParamInfo.stackSize != 0) { 1030 push('var pos = '+posExpr+';'); 1031 posExpr = 'pos'; 1032 } 1033 }); 950 push('var counter = '+getStrictIntParamNativeValueExpr(counterParamInfo)+';'); 951 stepExpr = getIntParamNativeValueExpr(stepParamInfo); 952 if(stepParamInfo.stackSize != 0) { 953 push('var step = '+stepExpr+';'); 954 stepExpr = 'step'; 955 } 956 endExpr = getIntParamNativeValueExpr(endParamInfo); 957 if(endParamInfo.stackSize != 0) { 958 push('var end = '+endExpr+';'); 959 endExpr = 'end'; 960 } 961 posExpr = getLabelParamNativeValueExpr(labelParamInfo); 962 if(labelParamInfo.stackSize != 0) { 963 push('var pos = '+posExpr+';'); 964 posExpr = 'pos'; 965 } 1034 966 push('if('+stepExpr+' >= 0) {'); 1035 967 push(' if(counter >= '+endExpr+') { this.pc = '+posExpr+'; continue; }'); … … 1042 974 var labelParamInfos = insn.opts[1]; 1043 975 var indexParamInfo = insn.opts[2]; 1044 paramInfoGetExprBlock(labelParamInfos, indexParamInfo, function() { 1045 var labelsIndex = null; 1046 var labelExprs = []; 1047 for(var i = 0; i < labelParamInfos.length; i ++) { 1048 var paramInfo = labelParamInfos[i]; 1049 if(paramInfo.node.isLiteralNode() && paramInfo.node.val.getType() == VarType.LABEL) { 1050 labelExprs[i] = '' + paramInfo.node.val.pos; 1051 } else { 1052 if(labelsIndex == null) { 1053 push('var labels = [];'); 1054 labelsIndex = 0; 1055 } 1056 push('labels['+labelsIndex+'] = '+getLabelParamNativeValueExpr(labelParamInfos[i])+';'); 1057 labelExprs[i] = 'labels['+labelsIndex+']'; 1058 labelsIndex ++; 976 var labelsIndex = null; 977 var labelExprs = []; 978 for(var i = 0; i < labelParamInfos.length; i ++) { 979 var paramInfo = labelParamInfos[i]; 980 if(paramInfo.node.isLiteralNode() && paramInfo.node.val.getType() == VarType.LABEL) { 981 labelExprs[i] = '' + paramInfo.node.val.pos; 982 } else { 983 if(labelsIndex == null) { 984 push('var labels = [];'); 985 labelsIndex = 0; 1059 986 } 987 push('labels['+labelsIndex+'] = '+getLabelParamNativeValueExpr(labelParamInfos[i])+';'); 988 labelExprs[i] = 'labels['+labelsIndex+']'; 989 labelsIndex ++; 1060 990 } 1061 var indexExpr = getIntParamNativeValueExpr(indexParamInfo);1062 push('switch('+indexExpr+') {');1063 for(var i = 0; i < labelParamInfos.length; i ++) {1064 push('case '+i+': this.pc = '+labelExprs[i]+'; break;');1065 }1066 push('default: this.pc ++;');1067 push('}');1068 });991 } 992 var indexExpr = getIntParamNativeValueExpr(indexParamInfo); 993 push('switch('+indexExpr+') {'); 994 for(var i = 0; i < labelParamInfos.length; i ++) { 995 push('case '+i+': this.pc = '+labelExprs[i]+'; break;'); 996 } 997 push('default: this.pc ++;'); 998 push('}'); 1069 999 if(isGosub) { 1070 1000 pushJumpingSubroutineCode(pc); … … 1081 1011 } 1082 1012 } 1083 var stackPos = 0;1084 1013 var literals = this.literals; 1085 1014 var userDefFuncs = this.userDefFuncs; … … 1087 1016 var indent = 0; 1088 1017 var sequence = this.sequence; 1089 var useStackPop = null;1090 1018 push('for(;;) {'); indent ++; 1091 1019 push('switch(this.pc) {'); -
lang/javascript/hsp-on-js/trunk/src/param-info.js
r28263 r28609 6 6 Utils.objectExtend(ParamInfo.prototype, { 7 7 toString: function toString() { 8 return '<ParamInfo: '+this.node+ (this.stackSize!=0?','+this.stackSize:'')+'>';8 return '<ParamInfo: '+this.node+'>'; 9 9 }, 10 10 isVar: function isVar() { … … 168 168 }); 169 169 170 function GetStackNode(offset, originalNode) { 171 this.offset = offset; 170 function GetStackNode(originalNode) { 172 171 this.originalNode = originalNode; 173 172 } … … 177 176 isGetStackNode: function () { return true; }, 178 177 toString: function toString() { 179 return '<GetStackNode :'+this.offset/*+','+this.originalNode*/+'>';178 return '<GetStackNode'/*+':'+this.originalNode*/+'>'; 180 179 }, 181 180 getValueType: function getValueType() {
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)