Changeset 28040
- Timestamp:
- 01/06/09 23:53:43 (4 years ago)
- Location:
- lang/javascript/hsp-on-js/branches/param-info/src
- Files:
-
- 1 added
- 6 modified
-
builtin-funcs.js (modified) (1 diff)
-
calc-code.js (added)
-
compiler.js (modified) (10 diffs)
-
create-package (modified) (1 diff)
-
evaluator.js (modified) (21 diffs)
-
param-info.js (modified) (5 diffs)
-
run-in-shell (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
lang/javascript/hsp-on-js/branches/param-info/src/builtin-funcs.js
r26377 r28040 60 60 this.scanArgs(arguments, ''); 61 61 throw new StopException; 62 }, 63 0x14: function delmod(v) { 64 this.scanArgs(arguments, 'v'); 65 if(v.getType() != VarType.STRUCT) { 66 throw new HSPError(ErrorCode.TYPE_MISMATCH); 67 } 68 v.assign(StructValue.EMPTY); 62 69 }, 63 70 0x16: function mref(v, id) { -
lang/javascript/hsp-on-js/branches/param-info/src/compiler.js
r27948 r28040 136 136 compileAssignment: function compileAssignment(sequence) { 137 137 var varToken = this.ax.tokens[this.tokensPos]; 138 var varParamInfo = this.compileNode(sequence, this.getVarNode(true, false)); 138 var varData = this.getVariableData(true); 139 ++ this.tokensPos; 140 var indexParamInfos = this.compileNodes(sequence, this.getVariableSubscriptNodes()); 139 141 var token = this.ax.tokens[this.tokensPos++]; 140 142 if(!(token && token.type == Token.Type.MARK)) { … … 143 145 if(this.ax.tokens[this.tokensPos].ex1) { 144 146 if(token.val == 0) { // インクリメント 145 this.pushNewInsn(sequence, Instruction.Code.INC, [var ParamInfo], token);147 this.pushNewInsn(sequence, Instruction.Code.INC, [varData, indexParamInfos], token); 146 148 return; 147 149 } 148 150 if(token.val == 1) { // デクリメント 149 this.pushNewInsn(sequence, Instruction.Code.DEC, [var ParamInfo], token);151 this.pushNewInsn(sequence, Instruction.Code.DEC, [varData, indexParamInfos], token); 150 152 return; 151 153 } … … 153 155 if(token.val != 8) { // CALCCODE_EQ 154 156 // 複合代入 155 var paramInfos = this.compileParameters(sequence, true, true);156 if( paramInfos.length != 1) {157 var rhsParamInfos = this.compileParameters(sequence, true, true); 158 if(rhsParamInfos.length != 1) { 157 159 throw this.error("複合代入のパラメータの数が間違っています。", token); 158 160 } 159 this.pushNewInsn(sequence, Instruction.Code.COMPOUND_ASSIGN, [token.val, var ParamInfo, paramInfos[0]], token);161 this.pushNewInsn(sequence, Instruction.Code.COMPOUND_ASSIGN, [token.val, varData, indexParamInfos, rhsParamInfos[0]], token); 160 162 return; 161 163 } 162 var paramInfos = this.compileParameters(sequence, true, true);163 if( paramInfos.length == 0) {164 var rhsParamInfos = this.compileParameters(sequence, true, true); 165 if(rhsParamInfos.length == 0) { 164 166 throw this.error("代入のパラメータの数が間違っています。", token); 165 167 } 166 this.pushNewInsn(sequence, Instruction.Code.ASSIGN, [var ParamInfo, paramInfos], token);168 this.pushNewInsn(sequence, Instruction.Code.ASSIGN, [varData, indexParamInfos, rhsParamInfos], token); 167 169 }, 168 170 compileProgramCommand: function compileProgramCommand(sequence) { … … 222 224 throw this.error(); 223 225 } 224 var paramInfos = []; 225 if(this.ax.tokens[this.tokensPos].ex2) { 226 paramInfos.push(new ParamInfo(new LiteralNode(new IntValue(-1)))); 227 this.compileParametersSub(sequence, false, false, paramInfos); 228 } else { 229 this.compileParameters(sequence, false, false, paramInfos); 230 } 226 var paramInfos = this.compileParameters(sequence, false, false, paramInfos); 231 227 if(paramInfos.length > 2) throw this.error('repeat の引数が多すぎます', token); 232 228 this.pushNewInsn(sequence, Instruction.Code.REPEAT, … … 292 288 this.pushNewInsn(sequence, Instruction.Code.NEWMOD, 293 289 [varParamInfo, module, paramInfos, argc], token); 294 break;295 case 0x14: // delmod296 this.tokensPos ++;297 var paramInfos = this.compileParameters(sequence);298 if(paramInfos.length != 1) throw this.error('delmod の引数の数が違います', token);299 this.pushNewInsn(sequence, Instruction.Code.DELMOD, [paramInfos[0]], token);300 290 break; 301 291 case 0x18: // exgoto … … 433 423 } 434 424 break; 425 case NodeType.ARG: 426 break; 435 427 case NodeType.LITERAL: 436 428 break; … … 452 444 parent[propname] = new GetStackNode(stackSize++, node); 453 445 var paramInfos = self.compileNodes(sequence, node.paramNodes); 446 if(node.groupId == Token.Type.SYSVAR && node.subId == 0x04) { 447 self.pushNewInsn(sequence, Instruction.Code.CNT, [], node.token); 448 break; 449 } 454 450 self.pushNewInsn(sequence, 455 451 Instruction.Code.CALL_BUILTIN_FUNC, … … 661 657 var varData = this.getVariableData(mustBeVar); 662 658 ++ this.tokensPos; 659 if(varData.proxyVarType == ProxyVarType.ARG_NOTVAR) { 660 return new ArgNode(varData.id); 661 } 663 662 var indexNodes = this.getVariableSubscriptNodes(); 664 663 return new VarNode(varData, indexNodes, onlyValue, token); … … 671 670 return this.compileSysvar(); 672 671 } 673 },674 compileStruct: function compileStruct(sequence, useGetVar) {675 var token = this.ax.tokens[this.tokensPos];676 var prmInfo = this.ax.prmsInfo[token.code];677 var usedPushVar = this.compileProxyVariable(sequence, useGetVar);678 if(usedPushVar == null) {679 var funcInfo = this.ax.funcsInfo[this.getFinfoIdByMinfoId(token.code)];680 this.pushNewInsn(sequence, Instruction.Code.GETARG,681 [token.code - funcInfo.prmindex], token);682 }683 return usedPushVar;684 672 }, 685 673 getSysvarCallNode: function getSysvarCallNode() { … … 835 823 return ProxyVarType.ARG_VAR; 836 824 default: 825 if(this.isLeftParenToken(this.ax.tokens[this.tokensPos + 1])) { 826 throw this.error('変数でないエイリアスに添字を指定しています'); 827 } 837 828 return ProxyVarType.ARG_NOTVAR; 838 829 } -
lang/javascript/hsp-on-js/branches/param-info/src/create-package
r27866 r28040 46 46 variable-agent.js 47 47 param-info.js 48 calc-code.js 48 49 compiler.js 49 50 evaluator.js -
lang/javascript/hsp-on-js/branches/param-info/src/evaluator.js
r27936 r28040 50 50 } 51 51 52 function throwHSPError(errorCode) { 53 throw new HSPError(errorCode); 54 } 55 52 56 Evaluator.prototype = { 53 57 evaluate: function evaluate() { … … 142 146 lines.push(Utils.strTimes('\t', indent) + line); 143 147 } 144 function pushJumpingSubroutineCode( posExpr) {148 function pushJumpingSubroutineCode() { 145 149 push('if(this.frameStack.length >= 256) {'); 146 150 push(' throw new HSPError(ErrorCode.STACK_OVERFLOW);'); 147 151 push('}'); 148 152 push('this.frameStack.push(new Frame(this.pc + 1, null, this.args));'); 149 push('this.pc = '+posExpr+';'); 150 } 151 function pushGettingArrayValueCode(arrayExpr, indicesCount) { 152 if(indicesCount == 0) { 153 push('stack.push('+arrayExpr+'.at(0));'); 154 } else if(indicesCount == 1) { 155 push('var offset = this.scanArg(stack.pop(), "i").toIntValue()._value;'); 156 push('if(!(0 <= offset && offset < '+arrayExpr+'.getL0())) {'); 157 push(' throw new HSPError(ErrorCode.ARRAY_OVERFLOW);'); 158 push('}'); 159 push('stack.push('+arrayExpr+'.at(offset));'); 153 } 154 function pushGettingArrayValueCode(varData, indexParamInfos) { 155 var sum = stackPos = stackSizeSum(indexParamInfos); 156 var result = getArrayAndOffsetExpr(varData, indexParamInfos); 157 var arrayExpr = result[0]; 158 var offsetExpr = result[1]; 159 pushStackPopCode(sum); 160 push('stack.push('+arrayExpr+'.at('+offsetExpr+'));'); 161 } 162 function pushGettingVariableCode(varData, indexParamInfos) { 163 var result; 164 var sum = stackPos = stackSizeSum(indexParamInfos); 165 if(isVariableAgentVarData(varData)) { 166 result = getVariableAgentExpr(varData); 160 167 } else { 161 pushGettingIndicesCode(indicesCount, 0); 162 push('stack.length -= '+indicesCount+';'); 163 push('var offset = '+arrayExpr+'.getOffset(indices);'); 164 push('if(offset == null) throw new HSPError(ErrorCode.ARRAY_OVERFLOW);'); 165 push('stack.push('+arrayExpr+'.at(offset));'); 166 } 167 } 168 function pushGettingVariableCode(variableExpr, indicesCount) { 169 if(indicesCount == 0) { 170 push('stack.push(new VariableAgent0D('+variableExpr+'));'); 171 } else if(indicesCount == 1) { 172 push('var offset = this.scanArg(stack.pop(), "i").toIntValue()._value;'); 173 push('stack.push(new VariableAgent1D('+variableExpr+', offset));'); 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 = '+getStrictIntParamExpr(paramInfo)+';'); 174 result = 'new VariableAgent1D('+variableExpr+', offset)'; 175 } else { 176 pushGettingIndicesCode(indexParamInfos); 177 result = 'new VariableAgentMD('+variableExpr+', indices)'; 178 } 179 } 180 pushStackPopCode(sum); 181 push('stack.push('+result+');'); 182 } 183 function pushAssignCode(varData, indexParamInfos, rhsParamInfos) { 184 var sum = stackPos = stackSizeSum(indexParamInfos) + stackSizeSum(rhsParamInfos); 185 if(isVariableAgentVarData(varData)) { 186 pushVariableAgentAssignCode(varData, rhsParamInfos); 174 187 } else { 175 pushGettingIndicesCode(indicesCount, 0); 176 push('stack.length -= '+indicesCount+';'); 177 push('stack.push(new VariableAgentMD('+variableExpr+', indices));'); 178 } 179 } 180 function pushGettingIndicesCode(indicesCount, offset) { 181 push('var len = stack.length;'); 182 push('var indices = [];'); 183 for(var i = 0; i < indicesCount; i ++) { 184 push('var val = stack[len - '+(offset+indicesCount-i)+'];'); 185 push('if(val.getType() != '+VarType.INT+') throw new HSPError(ErrorCode.TYPE_MISMATCH);'); 186 push('indices['+i+'] = val.toIntValue()._value;'); 187 } 188 } 189 function push1DMultipleAssignCode(argc) { 190 push('var type = stack[len - '+argc+'].getType();'); 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 } 196 } 197 pushStackPopCode(sum); 198 } 199 function pushVariableAgentAssignCode(varData, paramInfos) { 200 if(paramInfos.length == 1) { 201 push(getVariableAgentExpr(varData)+'.assign('+getParamExpr(paramInfos[0])+');'); 202 } else { 203 push('var agent = '+getVariableAgentExpr(varData)+';'); 204 push('var variable = agent.variable;'); 205 push('if(agent.indices) {'); 206 push(' var indices = agent.indices.slice();'); 207 for(var i = 0; i < paramInfos.length; i ++) { 208 push(' variable.assign(indices, '+getParamExpr(paramInfos[i])+');'); 209 if(i != paramInfos.length - 1) { 210 push(' indices[0] ++;'); 211 } 212 } 213 push('} else {'); indent ++; 214 push('var offset = agent.offset;'); 215 push1DMultipleAssignCode(paramInfos); 216 indent --; push('}'); 217 } 218 } 219 function push0DAssignCode(paramInfos) { 220 if(paramInfos.length == 1) { 221 push('var rhs = '+getParamExpr(paramInfos[0])+';'); 222 push('if(variable.value.getType() != rhs.getType()) {'); 223 push(' variable.reset(rhs.getType());'); 224 push('}'); 225 push('variable.value.assign(0, rhs);'); 226 } else { 227 push('var rhs = '+getParamExpr(paramInfos[0])+';'); 228 push('var type = rhs.getType();'); 229 push('if(variable.value.getType() != type) {'); 230 push(' variable.reset(type);'); 231 push('}'); 232 push('var array = variable.value;'); 233 push('array.expand1D('+(paramInfos.length-1)+');'); 234 push('array.assign(0, rhs);'); 235 for(var i = 1; i < paramInfos.length; i ++) { 236 push('var rhs = '+getParamExpr(paramInfos[i])+';'); 237 push('if(rhs.getType() != type) throw new HSPError(ErrorCode.INVALID_ARRAYSTORE);'); 238 push('array.assign('+i+', rhs);'); 239 } 240 } 241 } 242 function push1DAssignCode(indexParamInfo, rhsParamInfos) { 243 push('var offset = '+getStrictIntParamExpr(indexParamInfo)+';'); 244 if(rhsParamInfos.length == 1) { 245 push('var rhs = '+getParamExpr(rhsParamInfos[0])+';'); 246 push('if(variable.value.getType() != rhs.getType()) {'); 247 push(' if(offset == 0) {'); 248 push(' variable.reset(rhs.getType());'); 249 push(' } else {'); 250 push(' throw new HSPError(ErrorCode.INVALID_ARRAYSTORE);'); 251 push(' }'); 252 push('}'); 253 push('variable.value.assign(offset, rhs);'); 254 } else { 255 push1DMultipleAssignCode(rhsParamInfos); 256 } 257 } 258 function pushMDAssignCode(indexParamInfos, rhsParamInfos) { 259 pushGettingIndicesCode(indexParamInfos); 260 for(var i = 0; i < rhsParamInfos.length; i ++) { 261 push('variable.assign(indices, '+getParamExpr(rhsParamInfos[i])+');'); 262 if(i != rhsParamInfos.length - 1) { 263 push('indices[0] ++;'); 264 } 265 } 266 } 267 function push1DMultipleAssignCode(paramInfos) { 268 push('if(offset < 0) throw new HSPError(ErrorCode.ARRAY_OVERFLOW);'); 269 push('var rhs = '+getParamExpr(paramInfos[0])+';'); 270 push('var type = rhs.getType();'); 191 271 push('if(variable.value.getType() != type) {'); 192 272 push(' if(offset == 0) {'); … … 197 277 push('}'); 198 278 push('var array = variable.value;'); 199 push('array.expand1D(offset + '+(argc-1)+');'); 200 push('array.assign(offset, stack[len - '+argc+']);'); 201 for(var i = 1; i < argc; i ++) { 202 push('var arg = stack[len - '+(argc-i)+'];'); 203 push('if(arg.getType() != type) throw new HSPError(ErrorCode.INVALID_ARRAYSTORE);'); 204 push('array.assign(offset + '+i+', arg);'); 205 } 206 } 207 function pushAssignCode(indicesCount, argc) { 208 if(indicesCount == 0) { 209 if(argc == 1) { 210 push('var arg = stack.pop();'); 211 push('if(variable.value.getType() != arg.getType()) variable.reset(arg.getType());'); 212 push('variable.value.assign(0, arg);'); 213 } else { 214 push('var len = stack.length;'); 215 push('var type = stack[len - '+argc+'].getType();'); 216 push('if(variable.value.getType() != type) variable.reset(type);'); 217 push('var array = variable.value;'); 218 push('array.expand1D('+(argc-1)+');'); 219 push('array.assign(0, stack[len - '+argc+']);'); 220 for(var i = 1; i < argc; i ++) { 221 push('var arg = stack[len - '+(argc-i)+'];'); 222 push('if(arg.getType() != type) throw new HSPError(ErrorCode.INVALID_ARRAYSTORE);'); 223 push('array.assign('+i+', arg);'); 224 } 225 push('stack.length -= '+argc+';'); 226 } 227 } else if(indicesCount == 1) { 228 if(argc == 1) { 229 push('var arg = stack.pop();'); 230 push('var offset = this.scanArg(stack.pop(), "i").toIntValue()._value;'); 231 push('if(variable.value.getType() != arg.getType()) {'); 232 push(' if(offset == 0) {'); 233 push(' variable.reset(arg.getType());'); 234 push(' } else {'); 235 push(' throw new HSPError(ErrorCode.INVALID_ARRAYSTORE);'); 236 push(' }'); 237 push('}'); 238 push('variable.value.expand1D(offset);'); 239 push('variable.value.assign(offset, arg);'); 240 } else { 241 push('var len = stack.length;'); 242 push('var offset = this.scanArg(stack[len-'+(argc+1)+'], "i").toIntValue()._value;'); 243 push('if(offset < 0) throw new HSPError(ErrorCode.ARRAY_OVERFLOW);'); 244 push1DMultipleAssignCode(argc); 245 push('stack.length -= '+(argc+1)+';'); 246 } 247 } else { 248 pushGettingIndicesCode(indicesCount, argc); 249 for(var i = 0; i < argc; i ++) { 250 push('variable.assign(indices, stack[len - '+(argc-i)+']);'); 251 if(i != argc - 1) push('indices[0] ++;'); 252 } 253 push('stack.length -= '+(argc+indicesCount)+';'); 254 } 255 } 256 function pushCompoundAssignCode(calcCode, indicesCount, variableExpr) { 257 push('var arg = stack.pop();'); 258 if(!(8 <= calcCode && calcCode <= 13)) { 259 // 比較演算以外は同じ型の値が返ってくることに依存して型チェックをしない 260 push('var array = '+variableExpr+'.value;'); 261 if(indicesCount == 0) { 262 push('array.assign(0, array.at(0).'+operateMethodNames[calcCode]+'(arg));'); 263 } else if(indicesCount == 1) { 264 push('var offset = this.scanArg(stack.pop(), "i").toIntValue()._value;'); 265 push('array.expand1D(offset);'); 266 push('array.assign(offset, array.at(offset).'+operateMethodNames[calcCode]+'(arg));'); 267 } else { 268 pushGettingIndicesCode(indicesCount, 0); 269 push('stack.length -= '+indicesCount+';'); 270 push('array.expand(indices);'); 271 push('var offset = array.getOffset(indices);'); 272 push('array.assign(offset, array.at(offset).'+operateMethodNames[calcCode]+'(arg));'); 273 } 274 } else { 275 // 比較演算は必ず int 型の値が返ってくることに依存 276 push('var variable = '+variableExpr+';'); 277 if(indicesCount == 0) { 278 push('if(variable.value.getType() != '+VarType.INT+') variable.reset('+VarType.INT+');'); 279 push('variable.value.assign(0, variable.value.at(0).'+operateMethodNames[calcCode]+'(arg));'); 280 } else if(indicesCount == 1) { 281 push('var offset = this.scanArg(stack.pop(), "i").toIntValue()._value;'); 282 push('if(variable.value.getType() != '+VarType.INT+') {'); 283 push(' if(offset == 0) {'); 284 push(' variable.reset('+VarType.INT+');'); 285 push(' } else {'); 286 push(' throw new HSPError(ErrorCode.INVALID_ARRAYSTORE);'); 287 push(' }'); 288 push('}'); 289 push('variable.value.expand1D(offset);'); 290 push('variable.value.assign(offset, variable.value.at(offset).'+operateMethodNames[calcCode]+'(arg));'); 291 } else { 292 pushGettingIndicesCode(indicesCount, 0); 293 push('stack.length -= '+indicesCount+';'); 294 push('var array = variable.value;'); 295 push('array.expand(indices);'); 296 push('var offset = array.getOffset(indices);'); 297 push('if(array.getType() != '+VarType.INT+') {'); 298 push(' if(offset == 0) {'); 299 push(' variable.reset('+VarType.INT+');'); 300 push(' array = variable.value;'); 301 push(' array.expand(indices);'); 302 push(' } else {'); 303 push(' throw new HSPError(ErrorCode.INVALID_ARRAYSTORE);'); 304 push(' }'); 305 push('}'); 306 push('array.assign(offset, array.at(offset).'+operateMethodNames[calcCode]+'(arg));'); 307 } 308 } 309 } 310 function pushIncCode(indicesCount) { 311 if(indicesCount == 0) { 312 push('array.inc(0);'); 313 } else if(indicesCount == 1) { 314 push('var offset = this.scanArg(stack.pop(), "i").toIntValue()._value;'); 315 push('array.expand1D(offset);'); 316 push('array.inc(offset);'); 317 } else { 318 pushGettingIndicesCode(indicesCount, 0); 319 push('stack.length -= '+indicesCount+';'); 320 push('array.expand(indices);'); 321 push('var offset = array.getOffset(indices);'); 322 push('array.inc(offset);'); 323 } 324 } 325 function pushDecCode(indicesCount) { 326 if(indicesCount == 0) { 327 push('array.dec(0);'); 328 } else if(indicesCount == 1) { 329 push('var offset = this.scanArg(stack.pop(), "i").toIntValue()._value;'); 330 push('array.expand1D(offset);'); 331 push('array.dec(offset);'); 332 } else { 333 pushGettingIndicesCode(indicesCount, 0); 334 push('stack.length -= '+indicesCount+';'); 335 push('array.expand(indices);'); 336 push('var offset = array.getOffset(indices);'); 337 push('array.dec(offset);'); 338 } 339 } 340 function pushCallingUserdefFuncCode(userDefFunc, paramsInfo, constructorThismodExpr) { 341 if(!userDefFuncs[userDefFunc.id]) { 342 userDefFuncs[userDefFunc.id] = userDefFunc; 343 } 344 var paramTypes = paramsInfo[0]; 345 var paramVals = paramsInfo[1]; 346 var argc = paramTypes.length; // 実引数の数 347 var stackArgsMax = argc; // スタックに存在する実引数の数 (省略された引数やリテラルのみの引数はスタックを使わない) 348 var stackArgsCount = 0; 349 var origArgsCount = 0; 350 var mptypes = userDefFunc.paramTypes; 351 var argMax = mptypes.length; 352 var recvArgMax = 0; // local を除いた仮引数の数 353 for(var i = 0; i < argMax; i ++) { 354 var mptype = mptypes[i]; 355 var paramType = paramTypes[recvArgMax] || Compiler.ParamType.OMMITED; 356 var paramVal = paramVals[recvArgMax]; 357 if(mptype == MPType.LOCALVAR || mptype == MPType.IMODULEVAR) continue; 358 if(mptype == MPType.ARRAYVAR) { 359 if(recvArgMax < paramTypes.length) { 360 if(paramType != Compiler.ParamType.VARIABLE) { 361 push('throw new HSPError(ErrorCode.VARIABLE_REQUIRED);'); 362 return; 363 } 364 stackArgsMax --; 365 } 366 } else if(paramType == Compiler.ParamType.OMMITED) { 367 if(mptype != MPType.INUM) { 368 push('throw new HSPError(ErrorCode.NO_DEFAULT);'); 369 return; 370 } 371 if(recvArgMax < paramTypes.length) { 372 stackArgsMax --; 373 } 374 } else if(paramVal) { 375 stackArgsMax --; 376 } 377 recvArgMax ++; 378 } 379 if(recvArgMax < argc) { 380 push('throw new HSPError(ErrorCode.TOO_MANY_PARAMETERS);'); 381 return; 382 } 383 push('var args = [];'); 384 push('var len = stack.length;'); 385 for(var i = 0; i < argMax; i ++) { 386 var mptype = mptypes[i]; 387 var paramType = paramTypes[origArgsCount] || Compiler.ParamType.OMMITED; 388 var paramVal = paramVals[origArgsCount]; 389 var argExpr = 'stack[len - '+(stackArgsMax-stackArgsCount)+']'; 390 if(paramVal && mptype != MPType.ARRAYVAR) { 391 argExpr = getLiteralExpr(paramVal); 392 } 393 switch(mptype) { 394 case MPType.DNUM: 395 if(paramVal) { 396 if(paramVal.getType() == VarType.INT || paramVal.getType() == VarType.DOUBLE) { 397 push('args['+i+'] = '+getLiteralExpr(paramVal.toDoubleValue())+';'); 398 } else { 399 push('throw this.typeMismatchErrorIntOrDouble('+paramVal.getType()+');'); 400 } 401 } else { 402 push('args['+i+'] = this.scanArg('+argExpr+', "n").toDoubleValue();'); 403 stackArgsCount ++; 404 } 405 break; 406 case MPType.INUM: 407 if(paramVal) { 408 if(paramVal.getType() == VarType.INT || paramVal.getType() == VarType.DOUBLE) { 409 push('args['+i+'] = '+getLiteralExpr(paramVal.toIntValue())+';'); 410 } else { 411 push('throw this.typeMismatchErrorIntOrDouble('+paramVal.getType()+');'); 412 } 413 } else if(paramType == Compiler.ParamType.OMMITED) { 414 push('args['+i+'] = IntValue.of(0);'); 415 } else { 416 push('args['+i+'] = this.scanArg('+argExpr+', "n").toIntValue();') 417 stackArgsCount ++; 418 } 419 break; 420 case MPType.LOCALVAR: 421 push('args['+i+'] = new Variable;'); 422 continue; 423 case MPType.ARRAYVAR: 424 push('args['+i+'] = '+getVariableExpr(paramVal)+';'); 425 break; 426 case MPType.SINGLEVAR: 427 case MPType.MODULEVAR: 428 if(paramType == Compiler.ParamType.VARIABLE) { 429 push('var arg = '+argExpr+';'); 430 push('arg.expand();'); 431 push('args['+i+'] = arg;'); 432 } else { 433 push('var arg = new VariableAgent0D(new Variable);'); 434 if(paramVal) { 435 push('arg.assign('+getLiteralExpr(paramVal)+')'); 436 } else { 437 push('arg.assign('+argExpr+')'); 438 } 439 push('args['+i+'] = arg;'); 440 } 441 if(!paramVal) stackArgsCount ++; 442 break; 443 case MPType.LOCALSTRING: 444 if(paramVal) { 445 if(paramVal.getType() == VarType.STR) { 446 push('args['+i+'] = '+getLiteralExpr(paramVal.toStrValue())+';'); 447 } else { 448 push('throw this.typeMismatchError('+paramVal.getType()+','+VarType.STR+');'); 449 } 450 } else { 451 push('args['+i+'] = this.scanArg('+argExpr+', "s").toStrValue();'); 452 stackArgsCount ++; 453 } 454 break; 455 case MPType.IMODULEVAR: 456 push('args['+i+'] = '+constructorThismodExpr+';'); 457 continue; 458 default: 459 throw new Error('未対応のパラメータタイプ: '+mptype); 460 } 461 origArgsCount ++; 462 } 463 if(stackArgsMax != 0) { 464 push('stack.length -= '+stackArgsMax+';'); 465 } 466 push('if(this.frameStack.length >= 256) {'); 467 push(' throw new HSPError(ErrorCode.STACK_OVERFLOW);'); 468 push('}'); 469 push('this.frameStack.push(new Frame('+(pc + 1)+', userDefFuncs['+userDefFunc.id+'], args, this.args));'); 470 push('this.args = args;'); 471 push('this.pc = '+userDefFunc.label.pos+';'); 279 push('array.expand1D(offset + '+(paramInfos.length-1)+');'); 280 push('array.assign(offset, rhs);'); 281 for(var i = 1; i < paramInfos.length; i ++) { 282 push('var rhs = stack[len - '+getParamExpr(paramInfos[i])+'];'); 283 push('if(rhs.getType() != type) throw new HSPError(ErrorCode.INVALID_ARRAYSTORE);'); 284 push('array.assign(offset + '+i+', rhs);'); 285 } 286 } 287 function pushCompoundAssignCode(calcCode, varData, indexParamInfos, rhsParamInfo) { 288 // TODO 289 } 290 function pushIncDecCode(methodName, varData, indexParamInfos) { 291 var sum = stackPos = stackSizeSum(indexParamInfos); 292 var result = getArrayAndOffsetExpr(varData, indexParamInfos); 293 var arrayExpr = result[0]; 294 var offsetExpr = result[1]; 295 pushStackPopCode(sum); 296 push(arrayExpr+'.'+methodName+'('+offsetExpr+')'); 297 } 298 function pushIncCode(varData, indexParamInfos) { 299 pushIncDecCode('inc', varData, indexParamInfos); 300 } 301 function pushDecCode(varData, indexParamInfos) { 302 pushIncDecCode('dec', varData, indexParamInfos); 303 } 304 function pushCallingUserdefFuncCode(userDefFunc, paramInfos) { 305 // TODO 306 } 307 function pushGettingIndicesCode(indexParamInfos) { 308 push('var indices = [];'); 309 for(var i = 0; i < indexParamInfos.length; i ++) { 310 push('indices['+i+'] = '+getStrictIntParamExpr(indexParamInfos[i])+';'); 311 } 472 312 } 473 313 function getVariableExpr(varData) { 474 var type = varData[0]; 475 var no = varData[1]; 314 if(isVariableAgentVarData(varData)) { 315 return getVariableAgentExpr(varData)+'.variable'; 316 } 317 var type = varData.proxyVarType; 318 var id = varData.id; 476 319 switch(type) { 477 case Compiler.ProxyVarType.STATIC: 478 return 'variables['+no+']'; 479 case Compiler.ProxyVarType.THISMOD: 480 return 'this.getThismod().variable'; 481 case Compiler.ProxyVarType.MEMBER: 482 return 'this.getThismod().toValue().members['+no+']'; 483 case Compiler.ProxyVarType.ARG_VAR: 484 return 'this.getArg('+no+').variable'; 485 case Compiler.ProxyVarType.ARG_ARRAY: 486 case Compiler.ProxyVarType.ARG_LOCAL: 487 return 'this.getArg('+no+')'; 320 case ProxyVarType.STATIC: 321 return 'variables['+id+']'; 322 case ProxyVarType.MEMBER: 323 return 'this.getThismod().toValue().members['+id+']'; 324 case ProxyVarType.ARG_ARRAY: 325 case ProxyVarType.ARG_LOCAL: 326 return 'this.getArg('+id+')'; 488 327 default: 489 328 throw new Error('must not happen'); 490 329 } 330 } 331 function isVariableAgentVarData(varData) { 332 var type = varData.proxyVarType; 333 return type == ProxyVarType.THISMOD || type == ProxyVarType.ARG_VAR; 334 } 335 function getVariableAgentExpr(varData) { 336 switch(varData.proxyVarType) { 337 case ProxyVarType.THISMOD: 338 return 'this.getThismod()'; 339 case ProxyVarType.ARG_VAR: 340 return 'this.getArg('+id+')'; 341 default: 342 throw new Error('must not happen'); 343 } 344 } 345 function getArrayAndOffsetExpr(varData, indexParamInfos) { 346 if(isVariableAgentVarData(varData)) { 347 push('var agent = '+getVariableAgentExpr(varData)+';'); 348 return ['agent.variable.value', 'agent.getOffset()']; 349 } 350 var arrayExpr = getVariableExpr(varData)+'.value'; 351 var offsetExpr = 'offset'; 352 if(indexParamInfos.length == 0) { 353 offsetExpr = '0'; 354 } else if(indexParamInfos.length == 1) { 355 var paramInfo = indexParamInfos[0]; 356 push('var array = '+arrayExpr+';'); 357 arrayExpr = 'array'; 358 push('var offset = '+getStrictIntParamExpr(paramInfo)+';'); 359 push('if(!(0 <= offset && offset < array.getL0())) {'); 360 push(' throw new HSPError(ErrorCode.ARRAY_OVERFLOW);'); 361 push('}'); 362 } else { 363 push('var array = '+arrayExpr+';'); 364 arrayExpr = 'array'; 365 pushGettingIndicesCode(indexNodes); 366 push('var offset = array.getOffset(indices);'); 367 push('if(offset == null) throw new HSPError(ErrorCode.ARRAY_OVERFLOW);'); 368 } 369 return [arrayExpr, offsetExpr]; 491 370 } 492 371 function getLiteralExpr(literal) { … … 494 373 return 'literals['+(literals.length - 1)+']'; 495 374 } 375 function stackSizeSum(paramInfos) { 376 var sum = 0; 377 for(var i = 0; i < paramInfos.length; i ++) { 378 sum += paramInfos[i].stackSize; 379 } 380 return sum; 381 } 382 function getParamExpr(paramInfo) { 383 return getParamExpr0(paramInfo.node); 384 } 385 function getParamExpr0(node) { 386 switch(node.nodeType) { 387 case NodeType.VAR: 388 if(node.indexNodes.length > 0) { 389 throw new Error('must not happen'); 390 } 391 return getVariableExpr(node.varData)+'.value.at(0)'; 392 case NodeType.ARG: 393 return 'this.getArg('+node.id+')'; 394 case NodeType.LITERAL: 395 return getLiteralExpr(node.val); 396 case NodeType.DEFAULT: 397 return 'throwHSPError('+ErrorCode.NO_DEFAULT+')'; 398 case NodeType.OPERATE: 399 return '('+getParamExpr0(node.lhsNode)+').'+getCalcCodeName(node.calcCode)+'('+getParamExpr0(node.rhsNode)+')'; 400 case NodeType.GET_STACK: 401 return 'stack[stack.length - '+(stackPos-node.offset)+']'; 402 default: 403 throw new Error('must not happen'); 404 } 405 } 406 function getNoSubscriptVariableExpr(paramInfo) { 407 var node = paramInfo.node; 408 if(node.isGetStackNode()) { 409 node = node.originalNode; 410 } 411 if(!node.isVarNode() || node.onlyValue) { 412 push('throw new HSPError(ErrorCode.VARIABLE_REQUIRED);'); 413 return null; 414 } 415 if(node.indexNodes.length > 0) { 416 push('throw new HSPError(ErrorCode.BAD_ARRAY_EXPRESSION);'); 417 return null; 418 } 419 var varData = node.varData; 420 if(isVariableAgentVarData(varData)) { 421 push('var agent = '+getVariableAgentExpr(varData)+';'); 422 push('if(agent.existSubscript) {') 423 push(' throw new HSPError(ErrorCode.BAD_ARRAY_EXPRESSION);'); 424 push('}'); 425 return 'agent.variable'; 426 } 427 return getVariableExpr(varData); 428 } 429 function getIntParamExpr(paramInfo) { 430 var node = paramInfo.node; 431 if(node.isLiteralNode() && 432 (node.val.getType() == VarType.INT || node.val.getType() == VarType.DOUBLE)) { 433 return '' + node.val.toIntValue()._value; 434 } 435 if(node.getValueType() == VarType.INT || node.getValueType() == VarType.DOUBLE) { 436 return getParamExpr(paramInfo)+'.toIntValue()._value'; 437 } 438 return 'this.scanArg('+getParamExpr(paramInfo)+', "n").toIntValue()._value'; 439 } 440 function getStrictIntParamExpr(paramInfo) { 441 var node = paramInfo.node; 442 if(node.isLiteralNode() && node.val.getType() == VarType.INT) { 443 return '' + node.val._value; 444 } 445 if(node.getValueType() == VarType.INT) { 446 return getParamExpr(paramInfo)+'.toIntValue()._value'; 447 } 448 return 'this.scanArg('+getParamExpr(paramInfo)+', "i").toIntValue()._value'; 449 } 450 function getLabelParamExpr(paramInfo) { 451 if(node.isLiteralNode() && node.val.getType() == VarType.LABEL) { 452 return '' + node.val.pos; 453 } 454 return 'this.scanArg('+getParamExpr(paramInfo)+', "l").toValue()._value'; 455 } 456 function pushStackPopCode(size) { 457 if(size == 0) { 458 // nothing 459 } else if(size == 1) { 460 push('-- stack.length;'); 461 } else { 462 push('stack.length -= '+size+';'); 463 } 464 } 465 var stackPos = 0; 496 466 var literals = this.literals; 497 467 var userDefFuncs = this.userDefFuncs; … … 499 469 var indent = 0; 500 470 var sequence = this.sequence; 501 var operateMethodNames = 'add,sub,mul,div,mod,and,or,xor,eq,ne,gt,lt,gteq,lteq,rsh,lsh'.split(',');502 471 503 472 push('for(;;) {'); indent ++; … … 509 478 case Instruction.Code.NOP: 510 479 break; 511 case Instruction.Code.PUSH:512 push('stack.push('+getLiteralExpr(insn.opts[0])+');');513 break;514 case Instruction.Code.PUSH_DEFAULT:515 push('stack.push(void 0);');516 break;517 480 case Instruction.Code.PUSH_VAR: 518 var var Id= insn.opts[0];519 var ind icesCount= insn.opts[1];520 pushGettingVariableCode( 'variables['+varId+']', indicesCount);481 var varData = insn.opts[0]; 482 var indexParamInfos = insn.opts[1]; 483 pushGettingVariableCode(varData, indexParamInfos); 521 484 break; 522 485 case Instruction.Code.GET_VAR: 523 var varId = insn.opts[0]; 524 var indicesCount = insn.opts[1]; 525 push('var array = variables['+varId+'].value;'); 526 pushGettingArrayValueCode('array', indicesCount); 486 var varData = insn.opts[0]; 487 var indexParamInfos = insn.opts[1]; 488 pushGettingArrayValueCode(varData, indexParamInfos); 527 489 break; 528 490 case Instruction.Code.POP: … … 530 492 break; 531 493 case Instruction.Code.POP_N: 532 push ('stack.length -= '+insn.opts[0]+';');494 pushStackPopCode(insn.opts[0]); 533 495 break; 534 496 case Instruction.Code.DUP: 535 497 push('stack.push(stack[stack.length-1]);'); 536 break;537 case Instruction.Code.ADD:538 case Instruction.Code.SUB:539 case Instruction.Code.MUL:540 case Instruction.Code.DIV:541 case Instruction.Code.MOD:542 case Instruction.Code.AND:543 case Instruction.Code.OR:544 case Instruction.Code.XOR:545 case Instruction.Code.EQ:546 case Instruction.Code.NE:547 case Instruction.Code.GT:548 case Instruction.Code.LT:549 case Instruction.Code.GTEQ:550 case Instruction.Code.LTEQ:551 case Instruction.Code.RSH:552 case Instruction.Code.LSH:553 push('var rhs = stack.pop();');554 push('stack[stack.length - 1] = stack[stack.length - 1].'+555 operateMethodNames[insn.code - Instruction.Code.ADD]+'(rhs);');556 498 break; 557 499 case Instruction.Code.GOTO: … … 560 502 break; 561 503 case Instruction.Code.IFNE: 562 push('if(stack.pop().toIntValue()._value) {'); 504 case Instruction.Code.IFEQ: 505 var label = insn.opts[0]; 506 var paramInfo = insn.opts[1]; 507 stackPos = paramInfo.stackSize; 508 var expr = getParamExpr(paramInfo)+'.toIntValue()._value'; 509 if(paramInfo.stackSize) { 510 push('var val = '+expr+';'); 511 expr = 'val'; 512 pushStackPopCode(paramInfo.stackSize); 513 } 514 if(insn.code == Instruction.Code.IFEQ) { 515 expr = '!' + expr; 516 } 517 push('if('+expr+') {'); 563 518 push(' this.pc = '+insn.opts[0].pos+';'); 564 519 push(' continue;'); 565 520 push('}'); 566 521 break; 567 case Instruction.Code.IFEQ:568 push('if(!stack.pop().toIntValue()._value) {');569 push(' this.pc = '+insn.opts[0].pos+';');570 push(' continue;');571 push('}');572 break;573 522 case Instruction.Code.ASSIGN: 574 var argc = insn.opts[0]; 575 if(argc > 1) { 576 push('var len = stack.length;'); 577 push('var agent = stack[len - '+(argc+1)+'];'); 578 push('var variable = agent.variable;'); 579 push('if(agent.indices) {'); 580 push(' var indices = agent.indices.slice();'); 581 for(var i = 0; i < argc; i ++) { 582 push(' variable.assign(indices, stack[len - '+(argc-i)+']);'); 583 if(i != argc - 1) push(' indices[0] ++;'); 584 } 585 push('} else {'); indent ++; 586 push('var offset = agent.offset;'); 587 push1DMultipleAssignCode(argc); 588 indent --; push('}'); 589 push('stack.length -= '+(argc+1)+';'); 590 } else { 591 push('var arg = stack.pop();'); 592 push('var agent = stack.pop();'); 593 push('agent.assign(arg);'); 594 } 595 break; 596 case Instruction.Code.ASSIGN_STATIC_VAR: 597 var varId = insn.opts[0]; 598 var indicesCount = insn.opts[1]; 599 var argc = insn.opts[2]; 600 push('var variable = variables['+varId+'];'); 601 pushAssignCode(indicesCount, argc); 602 break; 603 case Instruction.Code.ASSIGN_ARG_ARRAY: 604 var argNum = insn.opts[0]; 605 var indicesCount = insn.opts[1]; 606 var argc = insn.opts[2]; 607 push('var variable = this.getArg('+argNum+');'); 608 pushAssignCode(indicesCount, argc); 609 break; 610 case Instruction.Code.ASSIGN_MEMBER: 611 var memberNum = insn.opts[0]; 612 var indicesCount = insn.opts[1]; 613 var argc = insn.opts[2]; 614 push('var variable = this.getThismod().toValue().members['+memberNum+'];'); 615 pushAssignCode(indicesCount, argc); 523 var varData = insn.opts[0]; 524 var indexParamInfos = insn.opts[1]; 525 var rhsParamInfos = insn.opts[2]; 526 pushAssignCode(varData, indexParamInfos, rhsParamInfos); 616 527 break; 617 528 case Instruction.Code.COMPOUND_ASSIGN: 618 push('var arg = stack.pop();');619 push('var agent = stack.pop();');620 push('agent.expand();');621 push('agent.assign(agent.'+operateMethodNames[insn.opts[0]]+'(arg));');622 break;623 case Instruction.Code.COMPOUND_ASSIGN_STATIC_VAR:624 529 var calcCode = insn.opts[0]; 625 var varId = insn.opts[1]; 626 var indicesCount = insn.opts[2]; 627 pushCompoundAssignCode(calcCode, indicesCount, 'variables['+varId+']'); 628 break; 629 case Instruction.Code.COMPOUND_ASSIGN_ARG_ARRAY: 630 var calcCode = insn.opts[0]; 631 var argNum = insn.opts[1]; 632 var indicesCount = insn.opts[2]; 633 pushCompoundAssignCode(calcCode, indicesCount, 'this.getArg('+argNum+')'); 634 break; 635 case Instruction.Code.COMPOUND_ASSIGN_MEMBER: 636 var calcCode = insn.opts[0]; 637 var memberNum = insn.opts[1]; 638 var indicesCount = insn.opts[2]; 639 pushCompoundAssignCode(calcCode, indicesCount, 'this.getThismod().toValue().members['+memberNum+']'); 530 var varData = insn.opts[1]; 531 var indexParamInfos = insn.opts[2]; 532 var rhsParamInfo = insn.opts[3]; 533 pushCompoundAssignCode(calcCode, varData, indexParamInfos, rhsParamInfo); 640 534 break; 641 535 case Instruction.Code.INC: 642 push('var agent = stack.pop();'); 643 push('agent.expand();'); 644 push('agent.inc();'); 645 break; 646 case Instruction.Code.INC_STATIC_VAR: 647 var varId = insn.opts[0]; 648 var indicesCount = insn.opts[1]; 649 push('var array = variables['+varId+'].value;'); 650 pushIncCode(indicesCount); 651 break; 652 case Instruction.Code.INC_ARG_ARRAY: 653 var argNum = insn.opts[0]; 654 var indicesCount = insn.opts[1]; 655 push('var array = this.getArg('+argNum+').value;'); 656 pushIncCode(indicesCount); 657 break; 658 case Instruction.Code.INC_MEMBER: 659 var memberNum = insn.opts[0]; 660 var indicesCount = insn.opts[1]; 661 push('var array = this.getThismod().toValue().members['+memberNum+'].value;'); 662 pushIncCode(indicesCount); 536 var varData = insn.opts[0]; 537 var indexParamInfos = insn.opts[1]; 538 pushIncCode(varData, indexParamInfos); 663 539 break; 664 540 case Instruction.Code.DEC: 665 push('var agent = stack.pop();'); 666 push('agent.expand();'); 667 push('agent.dec();'); 668 break; 669 case Instruction.Code.DEC_STATIC_VAR: 670 var varId = insn.opts[0]; 671 var indicesCount = insn.opts[1]; 672 push('var array = variables['+varId+'].value;'); 673 pushDecCode(indicesCount); 674 break; 675 case Instruction.Code.DEC_ARG_ARRAY: 676 var argNum = insn.opts[0]; 677 var indicesCount = insn.opts[1]; 678 push('var array = this.getArg('+argNum+').value;'); 679 pushDecCode(indicesCount); 680 break; 681 case Instruction.Code.DEC_MEMBER: 682 var memberNum = insn.opts[0]; 683 var indicesCount = insn.opts[1]; 684 push('var array = this.getThismod().toValue().members['+memberNum+'].value;'); 685 pushDecCode(indicesCount); 541 var varData = insn.opts[0]; 542 var indexParamInfos = insn.opts[1]; 543 pushDecCode(varData, indexParamInfos); 686 544 break; 687 545 case Instruction.Code.CALL_BUILTIN_CMD: … … 689 547 var type = insn.opts[0]; 690 548 var subid = insn.opts[1]; 691 var argc= insn.opts[2];549 var paramInfos = insn.opts[2]; 692 550 push('var func = BuiltinFuncs['+type+']['+subid+'];'); 693 551 push('if(!func) throw new HSPError(ErrorCode.UNSUPPORTED_FUNCTION);'); 694 push('var args = Utils.aryPopN(stack, '+argc+');'); 552 push('var args = [];'); 553 var sum = stackPos = stackSizeSum(paramInfos); 554 for(var i = 0; i < paramInfos.length; i ++) { 555 var paramInfo = paramInfos[i]; 556 var node = paramInfo.node; 557 if(node.isDefaultNode()) { 558 push('args['+i+'] = void 0;'); 559 } else if(node.isVarNode() && !node.onlyValue) { 560 push('args['+i+'] = new VariableAgent0D('+getVariableExpr(node.varData)+');'); 561 } else { 562 push('args['+i+'] = '+getParamExpr(paramInfo)+';'); 563 } 564 } 565 pushStackPopCode(sum); 695 566 if(insn.code == Instruction.Code.CALL_BUILTIN_FUNC) { 696 567 push('stack.push(func.apply(this, args));'); … … 702 573 case Instruction.Code.CALL_USERDEF_FUNC: 703 574 var userDefFunc = insn.opts[0]; 704 var param sInfo= insn.opts[1];705 pushCallingUserdefFuncCode(userDefFunc, param sInfo);575 var paramInfos = insn.opts[1]; 576 pushCallingUserdefFuncCode(userDefFunc, paramInfos); 706 577 push('continue;'); 707 578 break; 708 case Instruction.Code.GETARG:709 var argNum = insn.opts[0];710 push('stack.push(this.getArg('+argNum+'));');711 break;712 case Instruction.Code.PUSH_ARG_VAR:713 var argNum = insn.opts[0];714 var indicesCount = insn.opts[1];715 pushGettingVariableCode('this.getArg('+argNum+')', indicesCount);716 break;717 case Instruction.Code.GET_ARG_VAR:718 var argNum = insn.opts[0];719 var indicesCount = insn.opts[1];720 push('var array = this.getArg('+argNum+').value;');721 pushGettingArrayValueCode('array', indicesCount);722 break;723 case Instruction.Code.PUSH_MEMBER:724 var memberNum = insn.opts[0];725 var indicesCount = insn.opts[1];726 pushGettingVariableCode('this.getThismod().toValue().members['+memberNum+']', indicesCount);727 break;728 case Instruction.Code.GET_MEMBER:729 var memberNum = insn.opts[0];730 var indicesCount = insn.opts[1];731 push('var struct = this.getThismod().toValue();');732 push('var array = struct.members['+memberNum+'].value;');733 pushGettingArrayValueCode('array', indicesCount);734 break;735 case Instruction.Code.THISMOD:736 push('stack.push(this.getThismod());');737 break;738 579 case Instruction.Code.NEWMOD: 739 var var Data= insn.opts[0];580 var varParamInfo = insn.opts[0]; 740 581 var module = insn.opts[1]; 741 var param sInfo= insn.opts[2];582 var paramInfos = insn.opts[2]; 742 583 var argc = insn.opts[3]; 743 584 if(!userDefFuncs[module.id]) { … … 750 591 break; 751 592 } 752 push('var variable = '+getVariableExpr(varData)+';'); 593 var variableExpr = getNoSubscriptVariableExpr(varParamInfo); 594 if(!variableExpr) break; 595 push('var variable = '+variableExpr+';'); 753 596 push('if(variable.getType() != '+VarType.STRUCT+') {'); 754 597 push(' variable.value = new StructArray();'); … … 757 600 push('var offset = array.newmod('+moduleExpr+');'); 758 601 if(constructor) { 759 pushCallingUserdefFuncCode(constructor, param sInfo, 'new VariableAgent1D(variable, offset)');602 pushCallingUserdefFuncCode(constructor, paramInfos, 'new VariableAgent1D(variable, offset)'); 760 603 push('continue;'); 761 604 } 762 605 break; 763 606 case Instruction.Code.RETURN: 764 var existReturnVal = insn.opts[0]; 765 var usedPushVar = insn.opts[1]; 607 var paramInfo = insn.opts[0]; 766 608 push('if(this.frameStack.length == 0) {'); 767 609 push(' throw new HSPError(ErrorCode.RETURN_WITHOUT_GOSUB);'); … … 769 611 push('var frame = this.frameStack.pop();'); 770 612 push('this.args = frame.prevArgs;'); 771 if(existReturnVal) { 613 if(paramInfo) { 614 stackPos = paramInfo.stackSize; 615 push('var val = '+getParamExpr(paramInfo)+';'); 616 pushStackPopCode(paramInfo.stackSize); 772 617 push('if(frame.userDefFunc && frame.userDefFunc.isCType) {'); 773 if(usedPushVar) { 774 push(' stack[stack.length - 1] = stack[stack.length - 1].toValue();'); 775 } 776 push('} else {'); indent ++ 777 push('var val = stack.pop();'); 618 push('stack.push(val);'); 619 push('} else {'); indent ++; 778 620 push('switch(val.getType()) {'); 779 621 push('case '+VarType.STR+':'); … … 798 640 push('continue;'); 799 641 break; 800 case Instruction.Code.DELMOD:801 push('var v = this.scanArg(stack.pop(), "v");');802 push('if(v.getType() != VarType.STRUCT) {');803 push(' throw new HSPError(ErrorCode.TYPE_MISMATCH);');804 push('}');805 push('v.assign(StructValue.EMPTY);');806 break;807 642 case Instruction.Code.REPEAT: 808 643 var pos = insn.opts[0].pos; 809 var argc= insn.opts[1];644 var paramInfos = insn.opts[1]; 810 645 push('if(this.loopStack.length >= 31) {'); 811 646 push(' throw new HSPError(ErrorCode.TOO_MANY_NEST);'); 812 647 push('}'); 813 if(argc == 2) { 814 push('var begin = this.scanArg(stack.pop(), "n").toIntValue()._value;'); 815 } else { 816 push('var begin = 0;'); 817 } 818 if(argc >= 1) { 819 push('var end = this.scanArg(stack.pop(), "n").toIntValue()._value;'); 648 var sum = stackPos = stackSizeSum(paramInfos); 649 if(paramInfos.length >= 1 && !paramInfos[0].node.isDefaultNode()) { 650 push('var end = '+getIntParamExpr(paramInfos[0])+';'); 820 651 push('if(end < 0) end = Infinity;'); 821 652 } else { 822 653 push('var end = Infinity;'); 654 } 655 if(paramInfos.length == 2) { 656 push('var begin = '+getIntParamExpr(paramInfos[1])+';'); 657 } else { 658 push('var begin = 0;'); 823 659 } 824 660 push('if(end == 0) {'); … … 850 686 case Instruction.Code.CONTINUE: 851 687 var pos = insn.opts[0].pos; 852 var argc= insn.opts[1];688 var paramInfo = insn.opts[1]; 853 689 push('if(this.loopStack.length == 0) {'); 854 690 push(' throw new HSPError(ErrorCode.LOOP_WITHOUT_REPEAT);'); … … 856 692 push('var data = this.loopStack[this.loopStack.length - 1];'); 857 693 var newCntExpr; 858 if(argc) { 859 newCntExpr = '(data.cnt = this.scanArg(this.stack.pop(), "n").toIntValue()._value)'; 694 if(paramInfo) { 695 stackPos = paramInfo.stackSize; 696 newCntExpr = '(data.cnt = '+getIntParamExpr(paramInfo)+')'; 860 697 } else { 861 698 newCntExpr = '++data.cnt'; … … 867 704 push(' this.pc = data.pc;'); 868 705 push('}'); 706 if(paramInfo) { 707 pushStackPopCode(paramInfo.stackSize); 708 } 869 709 push('continue;'); 870 710 break; … … 889 729 push('}') 890 730 var pos = insn.opts[0].pos; 891 push('var v = this.scanArg(stack.pop(), "v");'); 731 var paramInfo = insn.opts[1]; 732 push('var v = '+getNoSubscriptVariableExpr(paramInfo)+';'); 892 733 push('var data = this.loopStack[this.loopStack.length - 1];'); 893 734 push('if(data.cnt >= v.variable.getL0()) {') … … 908 749 break; 909 750 case Instruction.Code.GOSUB: 910 pushJumpingSubroutineCode(insn.opts[0].pos); 751 pushJumpingSubroutineCode(); 752 push('this.pc = '+insn.opts[0].pos+';'); 911 753 push('continue;'); 912 754 break; 913 755 case Instruction.Code.GOTO_EXPR: 914 push('this.pc = this.scanArg(stack.pop(), "l").toValue().pos;'); 756 case Instruction.Code.GOSUB_EXPR: 757 var paramInfo = insn.opts[0]; 758 if(insn.code == Instruction.Code.GOSUB_EXPR) { 759 pushJumpingSubroutineCode(); 760 } 761 stackPos = paramInfo.stackSize; 762 push('this.pc = '+getLabelParamExpr(paramInfo)+';'); 763 pushStackPopCode(paramInfo.stackSize); 915 764 push('continue;'); 916 765 break; 917 case Instruction.Code.GOSUB_EXPR:918 pushJumpingSubroutineCode('this.scanArg(stack.pop(), "l").toValue().pos');919 push('continue;');920 break;921 766 case Instruction.Code.EXGOTO: 922 push('var pos = this.scanArg(stack.pop(), "l").toValue().pos;'); 923 push('var b = this.scanArg(stack.pop(), "n").toIntValue()._value;'); 924 push('var mode = this.scanArg(stack.pop(), "n").toIntValue()._value;'); 925 push('var a = this.scanArg(this.scanArg(stack.pop(), "v"), "i").toIntValue()._value;'); 926 push('if(mode >= 0) {'); 927 push(' if(a >= b) { this.pc = pos; continue; }'); 928 push('} else {'); 929 push(' if(a <= b) { this.pc = pos; continue; }'); 930 push('}'); 931 break; 932 case Instruction.Code.EXGOTO_OPT1: 933 var pos = insn.opts[1].pos; 934 push('var a = this.scanArg(variables['+insn.opts[0]+'].at(0), "i").toIntValue()._value;'); 935 push('var b = this.scanArg(stack.pop(), "n").toIntValue()._value;'); 936 push('var mode = this.scanArg(stack.pop(), "n").toIntValue()._value;'); 937 push('if(mode >= 0) {'); 938 push(' if(a >= b) { this.pc = '+pos+'; continue; }'); 939 push('} else {'); 940 push(' if(a <= b) { this.pc = '+pos+'; continue; }'); 941 push('}'); 942 break; 943 case Instruction.Code.EXGOTO_OPT2: 944 var pos = insn.opts[1].pos; 945 push('var a = this.scanArg(variables['+insn.opts[0]+'].at(0), "i").toIntValue()._value;'); 946 push('var b = this.scanArg(stack.pop(), "n").toIntValue()._value;'); 947 push('if(a >= b) { this.pc = '+pos+'; continue; }'); 948 break; 949 case Instruction.Code.EXGOTO_OPT3: 950 var pos = insn.opts[1].pos; 951 push('var a = this.scanArg(variables['+insn.opts[0]+'].at(0), "i").toIntValue()._value;'); 952 push('var b = this.scanArg(stack.pop(), "n").toIntValue()._value;'); 953 push('if(a <= b) { this.pc = '+pos+'; continue; }'); 767 var paramInfos = insn.opts[0]; 768 // TODO 954 769 break; 955 770 case Instruction.Code.ON: 956 var argc= insn.opts[0];771 var indexParamInfo = insn.opts[0]; 957 772 var isGosub = insn.opts[1]; 958 push('var len = stack.length;'); 959 for(var i = 0; i < argc; i ++) { 960 push('this.scanArg(stack[len - '+(argc - i)+'], "l");'); 961 } 962 push('var n = this.scanArg(stack[len - '+(argc + 1)+'], "n").toIntValue()._value;'); 963 push('if(0 <= n && n < '+argc+') {'); indent ++; 964 push('var pos = stack[len - '+argc+' + n].toValue().pos;'); 965 push('stack.length -= '+(argc + 1)+';'); 966 if(isGosub) { 967 pushJumpingSubroutineCode('pos'); 968 push('continue;'); 969 } else { 970 push('this.pc = pos;'); 971 push('continue;'); 972 } 973 indent --; push('}'); 773 var labelParamInfos = insn.opts[2]; 774 // TODO 974 775 break; 975 776 default: … … 1004 805 fileRead: function fileRead(path, success, error) { 1005 806 throw new FileReadException(path, success, error); 1006 },1007 getArg: function getArg(argNum) {1008 var args = this.args;1009 if(!args) {1010 throw new HSPError(ErrorCode.INVALID_PARAMETER);1011 }1012 return args[argNum];1013 807 }, 1014 808 getThismod: function getThismod() { … … 1213 1007 HSPonJS.Frame = Frame; 1214 1008 HSPonJS.Event = Event; 1009 HSPonJS.throwHSPError = throwHSPError; 1215 1010 } 1216 1011 -
lang/javascript/hsp-on-js/branches/param-info/src/param-info.js
r27866 r28040 16 16 Utils.objectExtend(Node.prototype, { 17 17 isVarNode: function () { return false; }, 18 isArgNode: function () { return false; }, 18 19 isLiteralNode: function () { return false; }, 19 20 isDefaultNode: function () { return false; }, … … 27 28 var NodeType = { 28 29 VAR: 1, 29 LITERAL: 2, 30 DEFAULT: 3, 31 OPERATE: 4, 32 USERDEF_FUNCALL: 5, 33 BUILTIN_FUNCALL: 6, 34 GET_STACK: 7 30 ARG: 2, 31 LITERAL: 3, 32 DEFAULT: 4, 33 OPERATE: 5, 34 USERDEF_FUNCALL: 6, 35 BUILTIN_FUNCALL: 7, 36 GET_STACK: 8 35 37 }; 36 38 … … 49 51 (!this.onlyValue?',var':'')+ 50 52 (this.ignoreIndices?'ignore idicies':'')+'>'; 53 }, 54 getValueType: function getValueType() { 55 return 0; 56 } 57 }); 58 59 function ArgNode(id) { 60 this.id = id; 61 } 62 ArgNode.prototype = new Node; 63 Utils.objectExtend(ArgNode.prototype, { 64 nodeType: NodeType.ARG, 65 isArgNode: function () { return true; }, 66 toString: function toString() { 67 return '<ArgNode:'+this.id+'>'; 51 68 }, 52 69 getValueType: function getValueType() { … … 97 114 }, 98 115 getValueType: function getValueType() { 99 if( 8 <= this.calcCode && this.calcCode <= 13) {116 if(isCompareCalcCode(this.calcCode)) { 100 117 return VarType.INT; 101 118 } 102 return lhsNode.getValueType();119 return this.lhsNode.getValueType(); 103 120 } 104 121 }); … … 169 186 HSPonJS.NodeType = NodeType; 170 187 HSPonJS.VarNode = VarNode; 188 HSPonJS.ArgNode = ArgNode; 171 189 HSPonJS.LiteralNode = LiteralNode; 172 190 HSPonJS.DefaultNode = DefaultNode; -
lang/javascript/hsp-on-js/branches/param-info/src/run-in-shell
r27936 r28040 80 80 variable-agent.js 81 81 param-info.js 82 calc-code.js 82 83 compiler.js 83 84 evaluator.js
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)