Changeset 28040

Show
Ignore:
Timestamp:
01/06/09 23:53:43 (4 years ago)
Author:
fujidig
Message:

Evaluator を一部対応(exgoto, on, ユーザ定義関数呼び出し, 複合代入は未実装)

Location:
lang/javascript/hsp-on-js/branches/param-info/src
Files:
1 added
6 modified

Legend:

Unmodified
Added
Removed
  • lang/javascript/hsp-on-js/branches/param-info/src/builtin-funcs.js

    r26377 r28040  
    6060                this.scanArgs(arguments, ''); 
    6161                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); 
    6269        }, 
    6370        0x16: function mref(v, id) { 
  • lang/javascript/hsp-on-js/branches/param-info/src/compiler.js

    r27948 r28040  
    136136        compileAssignment: function compileAssignment(sequence) { 
    137137                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()); 
    139141                var token = this.ax.tokens[this.tokensPos++]; 
    140142                if(!(token && token.type == Token.Type.MARK)) { 
     
    143145                if(this.ax.tokens[this.tokensPos].ex1) { 
    144146                        if(token.val == 0) { // インクリメント 
    145                                 this.pushNewInsn(sequence, Instruction.Code.INC, [varParamInfo], token); 
     147                                this.pushNewInsn(sequence, Instruction.Code.INC, [varData, indexParamInfos], token); 
    146148                                return; 
    147149                        } 
    148150                        if(token.val == 1) { // デクリメント 
    149                                 this.pushNewInsn(sequence, Instruction.Code.DEC, [varParamInfo], token); 
     151                                this.pushNewInsn(sequence, Instruction.Code.DEC, [varData, indexParamInfos], token); 
    150152                                return; 
    151153                        } 
     
    153155                if(token.val != 8) { // CALCCODE_EQ 
    154156                        // 複合代入 
    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) { 
    157159                                throw this.error("複合代入のパラメータの数が間違っています。", token); 
    158160                        } 
    159                         this.pushNewInsn(sequence, Instruction.Code.COMPOUND_ASSIGN, [token.val, varParamInfo, paramInfos[0]], token); 
     161                        this.pushNewInsn(sequence, Instruction.Code.COMPOUND_ASSIGN, [token.val, varData, indexParamInfos, rhsParamInfos[0]], token); 
    160162                        return; 
    161163                } 
    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) { 
    164166                        throw this.error("代入のパラメータの数が間違っています。", token); 
    165167                } 
    166                 this.pushNewInsn(sequence, Instruction.Code.ASSIGN, [varParamInfo, paramInfos], token); 
     168                this.pushNewInsn(sequence, Instruction.Code.ASSIGN, [varData, indexParamInfos, rhsParamInfos], token); 
    167169        }, 
    168170        compileProgramCommand: function compileProgramCommand(sequence) { 
     
    222224                                throw this.error(); 
    223225                        } 
    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); 
    231227                        if(paramInfos.length > 2) throw this.error('repeat の引数が多すぎます', token); 
    232228                        this.pushNewInsn(sequence, Instruction.Code.REPEAT, 
     
    292288                        this.pushNewInsn(sequence, Instruction.Code.NEWMOD, 
    293289                                             [varParamInfo, module, paramInfos, argc], token); 
    294                         break; 
    295                 case 0x14: // delmod 
    296                         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); 
    300290                        break; 
    301291                case 0x18: // exgoto 
     
    433423                                } 
    434424                                break; 
     425                        case NodeType.ARG: 
     426                                break; 
    435427                        case NodeType.LITERAL: 
    436428                                break; 
     
    452444                                parent[propname] = new GetStackNode(stackSize++, node); 
    453445                                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                                } 
    454450                                self.pushNewInsn(sequence, 
    455451                                                 Instruction.Code.CALL_BUILTIN_FUNC, 
     
    661657                var varData = this.getVariableData(mustBeVar); 
    662658                ++ this.tokensPos; 
     659                if(varData.proxyVarType == ProxyVarType.ARG_NOTVAR) { 
     660                        return new ArgNode(varData.id); 
     661                } 
    663662                var indexNodes = this.getVariableSubscriptNodes(); 
    664663                return new VarNode(varData, indexNodes, onlyValue, token); 
     
    671670                        return this.compileSysvar(); 
    672671                } 
    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; 
    684672        }, 
    685673        getSysvarCallNode: function getSysvarCallNode() { 
     
    835823                        return ProxyVarType.ARG_VAR; 
    836824                default: 
     825                        if(this.isLeftParenToken(this.ax.tokens[this.tokensPos + 1])) { 
     826                                throw this.error('変数でないエイリアスに添字を指定しています'); 
     827                        } 
    837828                        return ProxyVarType.ARG_NOTVAR; 
    838829                } 
  • lang/javascript/hsp-on-js/branches/param-info/src/create-package

    r27866 r28040  
    4646variable-agent.js 
    4747param-info.js 
     48calc-code.js 
    4849compiler.js 
    4950evaluator.js 
  • lang/javascript/hsp-on-js/branches/param-info/src/evaluator.js

    r27936 r28040  
    5050} 
    5151 
     52function throwHSPError(errorCode) { 
     53        throw new HSPError(errorCode); 
     54} 
     55 
    5256Evaluator.prototype = { 
    5357        evaluate: function evaluate() { 
     
    142146                        lines.push(Utils.strTimes('\t', indent) + line); 
    143147                } 
    144                 function pushJumpingSubroutineCode(posExpr) { 
     148                function pushJumpingSubroutineCode() { 
    145149                        push('if(this.frameStack.length >= 256) {'); 
    146150                        push('    throw new HSPError(ErrorCode.STACK_OVERFLOW);'); 
    147151                        push('}'); 
    148152                        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); 
    160167                        } 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); 
    174187                        } 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();'); 
    191271                        push('if(variable.value.getType() != type) {'); 
    192272                        push('    if(offset == 0) {'); 
     
    197277                        push('}'); 
    198278                        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                        } 
    472312                } 
    473313                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; 
    476319                        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+')'; 
    488327                        default: 
    489328                                throw new Error('must not happen'); 
    490329                        } 
     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]; 
    491370                } 
    492371                function getLiteralExpr(literal) { 
     
    494373                        return 'literals['+(literals.length - 1)+']'; 
    495374                } 
     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; 
    496466                var literals = this.literals; 
    497467                var userDefFuncs = this.userDefFuncs; 
     
    499469                var indent = 0; 
    500470                var sequence = this.sequence; 
    501                 var operateMethodNames = 'add,sub,mul,div,mod,and,or,xor,eq,ne,gt,lt,gteq,lteq,rsh,lsh'.split(','); 
    502471                 
    503472                push('for(;;) {'); indent ++; 
     
    509478                        case Instruction.Code.NOP: 
    510479                                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; 
    517480                        case Instruction.Code.PUSH_VAR: 
    518                                 var varId = insn.opts[0]; 
    519                                 var indicesCount = insn.opts[1]; 
    520                                 pushGettingVariableCode('variables['+varId+']', indicesCount); 
     481                                var varData = insn.opts[0]; 
     482                                var indexParamInfos = insn.opts[1]; 
     483                                pushGettingVariableCode(varData, indexParamInfos); 
    521484                                break; 
    522485                        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); 
    527489                                break; 
    528490                        case Instruction.Code.POP: 
     
    530492                                break; 
    531493                        case Instruction.Code.POP_N: 
    532                                 push('stack.length -= '+insn.opts[0]+';'); 
     494                                pushStackPopCode(insn.opts[0]); 
    533495                                break; 
    534496                        case Instruction.Code.DUP: 
    535497                                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);'); 
    556498                                break; 
    557499                        case Instruction.Code.GOTO: 
     
    560502                                break; 
    561503                        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+') {'); 
    563518                                push('    this.pc = '+insn.opts[0].pos+';'); 
    564519                                push('    continue;'); 
    565520                                push('}'); 
    566521                                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; 
    573522                        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); 
    616527                                break; 
    617528                        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: 
    624529                                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); 
    640534                                break; 
    641535                        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); 
    663539                                break; 
    664540                        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); 
    686544                                break; 
    687545                        case Instruction.Code.CALL_BUILTIN_CMD: 
     
    689547                                var type = insn.opts[0]; 
    690548                                var subid = insn.opts[1]; 
    691                                 var argc = insn.opts[2]; 
     549                                var paramInfos = insn.opts[2]; 
    692550                                push('var func = BuiltinFuncs['+type+']['+subid+'];'); 
    693551                                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); 
    695566                                if(insn.code == Instruction.Code.CALL_BUILTIN_FUNC) { 
    696567                                        push('stack.push(func.apply(this, args));'); 
     
    702573                        case Instruction.Code.CALL_USERDEF_FUNC: 
    703574                                var userDefFunc = insn.opts[0]; 
    704                                 var paramsInfo = insn.opts[1]; 
    705                                 pushCallingUserdefFuncCode(userDefFunc, paramsInfo); 
     575                                var paramInfos = insn.opts[1]; 
     576                                pushCallingUserdefFuncCode(userDefFunc, paramInfos); 
    706577                                push('continue;'); 
    707578                                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; 
    738579                        case Instruction.Code.NEWMOD: 
    739                                 var varData = insn.opts[0]; 
     580                                var varParamInfo = insn.opts[0]; 
    740581                                var module = insn.opts[1]; 
    741                                 var paramsInfo = insn.opts[2]; 
     582                                var paramInfos = insn.opts[2]; 
    742583                                var argc = insn.opts[3]; 
    743584                                if(!userDefFuncs[module.id]) { 
     
    750591                                        break; 
    751592                                } 
    752                                 push('var variable = '+getVariableExpr(varData)+';'); 
     593                                var variableExpr = getNoSubscriptVariableExpr(varParamInfo); 
     594                                if(!variableExpr) break; 
     595                                push('var variable = '+variableExpr+';'); 
    753596                                push('if(variable.getType() != '+VarType.STRUCT+') {'); 
    754597                                push('    variable.value = new StructArray();'); 
     
    757600                                push('var offset = array.newmod('+moduleExpr+');'); 
    758601                                if(constructor) { 
    759                                         pushCallingUserdefFuncCode(constructor, paramsInfo, 'new VariableAgent1D(variable, offset)'); 
     602                                        pushCallingUserdefFuncCode(constructor, paramInfos, 'new VariableAgent1D(variable, offset)'); 
    760603                                        push('continue;'); 
    761604                                } 
    762605                                break; 
    763606                        case Instruction.Code.RETURN: 
    764                                 var existReturnVal = insn.opts[0]; 
    765                                 var usedPushVar = insn.opts[1]; 
     607                                var paramInfo = insn.opts[0]; 
    766608                                push('if(this.frameStack.length == 0) {'); 
    767609                                push('    throw new HSPError(ErrorCode.RETURN_WITHOUT_GOSUB);'); 
     
    769611                                push('var frame = this.frameStack.pop();'); 
    770612                                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); 
    772617                                        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 ++; 
    778620                                        push('switch(val.getType()) {'); 
    779621                                        push('case '+VarType.STR+':'); 
     
    798640                                push('continue;'); 
    799641                                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; 
    807642                        case Instruction.Code.REPEAT: 
    808643                                var pos = insn.opts[0].pos; 
    809                                 var argc = insn.opts[1]; 
     644                                var paramInfos = insn.opts[1]; 
    810645                                push('if(this.loopStack.length >= 31) {'); 
    811646                                push('    throw new HSPError(ErrorCode.TOO_MANY_NEST);'); 
    812647                                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])+';'); 
    820651                                        push('if(end < 0) end = Infinity;'); 
    821652                                } else { 
    822653                                        push('var end = Infinity;'); 
     654                                } 
     655                                if(paramInfos.length == 2) { 
     656                                        push('var begin = '+getIntParamExpr(paramInfos[1])+';'); 
     657                                } else { 
     658                                        push('var begin = 0;'); 
    823659                                } 
    824660                                push('if(end == 0) {'); 
     
    850686                        case Instruction.Code.CONTINUE: 
    851687                                var pos = insn.opts[0].pos; 
    852                                 var argc = insn.opts[1]; 
     688                                var paramInfo = insn.opts[1]; 
    853689                                push('if(this.loopStack.length == 0) {'); 
    854690                                push('    throw new HSPError(ErrorCode.LOOP_WITHOUT_REPEAT);'); 
     
    856692                                push('var data = this.loopStack[this.loopStack.length - 1];'); 
    857693                                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)+')'; 
    860697                                } else { 
    861698                                        newCntExpr = '++data.cnt'; 
     
    867704                                push('    this.pc = data.pc;'); 
    868705                                push('}'); 
     706                                if(paramInfo) { 
     707                                        pushStackPopCode(paramInfo.stackSize); 
     708                                } 
    869709                                push('continue;'); 
    870710                                break; 
     
    889729                                push('}') 
    890730                                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)+';'); 
    892733                                push('var data = this.loopStack[this.loopStack.length - 1];'); 
    893734                                push('if(data.cnt >= v.variable.getL0()) {') 
     
    908749                                break; 
    909750                        case Instruction.Code.GOSUB: 
    910                                 pushJumpingSubroutineCode(insn.opts[0].pos); 
     751                                pushJumpingSubroutineCode(); 
     752                                push('this.pc = '+insn.opts[0].pos+';'); 
    911753                                push('continue;'); 
    912754                                break; 
    913755                        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); 
    915764                                push('continue;'); 
    916765                                break; 
    917                         case Instruction.Code.GOSUB_EXPR: 
    918                                 pushJumpingSubroutineCode('this.scanArg(stack.pop(), "l").toValue().pos'); 
    919                                 push('continue;'); 
    920                                 break; 
    921766                        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 
    954769                                break; 
    955770                        case Instruction.Code.ON: 
    956                                 var argc = insn.opts[0]; 
     771                                var indexParamInfo = insn.opts[0]; 
    957772                                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 
    974775                                break; 
    975776                        default: 
     
    1004805        fileRead: function fileRead(path, success, error) { 
    1005806                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]; 
    1013807        }, 
    1014808        getThismod: function getThismod() { 
     
    12131007        HSPonJS.Frame = Frame; 
    12141008        HSPonJS.Event = Event; 
     1009        HSPonJS.throwHSPError = throwHSPError; 
    12151010} 
    12161011 
  • lang/javascript/hsp-on-js/branches/param-info/src/param-info.js

    r27866 r28040  
    1616Utils.objectExtend(Node.prototype, { 
    1717        isVarNode:     function () { return false; }, 
     18        isArgNode:     function () { return false; }, 
    1819        isLiteralNode: function () { return false; }, 
    1920        isDefaultNode: function () { return false; }, 
     
    2728var NodeType = { 
    2829        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 
    3537}; 
    3638 
     
    4951                       (!this.onlyValue?',var':'')+ 
    5052                       (this.ignoreIndices?'ignore idicies':'')+'>'; 
     53        }, 
     54        getValueType: function getValueType() { 
     55                return 0; 
     56        } 
     57}); 
     58 
     59function ArgNode(id) { 
     60        this.id = id; 
     61} 
     62ArgNode.prototype = new Node; 
     63Utils.objectExtend(ArgNode.prototype, { 
     64        nodeType: NodeType.ARG, 
     65        isArgNode: function () { return true; }, 
     66        toString: function toString() { 
     67                return '<ArgNode:'+this.id+'>'; 
    5168        }, 
    5269        getValueType: function getValueType() { 
     
    97114        }, 
    98115        getValueType: function getValueType() { 
    99                 if(8 <= this.calcCode && this.calcCode <= 13) { 
     116                if(isCompareCalcCode(this.calcCode)) { 
    100117                        return VarType.INT; 
    101118                } 
    102                 return lhsNode.getValueType(); 
     119                return this.lhsNode.getValueType(); 
    103120        } 
    104121}); 
     
    169186        HSPonJS.NodeType = NodeType; 
    170187        HSPonJS.VarNode = VarNode; 
     188        HSPonJS.ArgNode = ArgNode; 
    171189        HSPonJS.LiteralNode = LiteralNode; 
    172190        HSPonJS.DefaultNode = DefaultNode; 
  • lang/javascript/hsp-on-js/branches/param-info/src/run-in-shell

    r27936 r28040  
    8080    variable-agent.js 
    8181    param-info.js 
     82    calc-code.js 
    8283    compiler.js 
    8384    evaluator.js