Changeset 29704

Show
Ignore:
Timestamp:
02/08/09 20:20:16 (4 years ago)
Author:
fujidig
Message:

コンパイル中に命令列をリンクトリストで作ってから配列に変換するように

Location:
lang/javascript/hsp-on-js/trunk/src
Files:
8 modified
1 moved

Legend:

Unmodified
Added
Removed
  • lang/javascript/hsp-on-js/trunk/src/compiler.js

    r28714 r29704  
    6767Compiler.prototype = { 
    6868        compile: function() { 
    69                 var sequence = []; 
     69                var sequence = new ISeq; 
    7070                while(this.tokensPos < this.ax.tokens.length) { 
    7171                        var token = this.ax.tokens[this.tokensPos]; 
     
    7373                                throw this.error(); 
    7474                        } 
    75                         var labelIDs = this.ax.labelsMap[token.pos]; 
    76                         if(labelIDs) { 
    77                                 for(var i = 0; i < labelIDs.length; i ++) { 
    78                                         var labelID = labelIDs[i]; 
    79                                         this.labels[labelID].pos = sequence.length; 
    80                                 } 
    81                         } 
    82                         var labels = this.ifLabels[token.pos]; 
    83                         if(labels) { 
    84                                 for(var i = 0; i < labels.length; i ++) { 
    85                                         labels[i].pos = sequence.length; 
    86                                 } 
    87                         } 
    88                         switch(token.type) { 
    89                         case Token.Type.VAR: 
    90                         case Token.Type.STRUCT: 
    91                                 this.compileAssignment(sequence); 
    92                                 break; 
    93                         case Token.Type.CMPCMD: 
    94                                 this.compileBranchCommand(sequence); 
    95                                 break; 
    96                         case Token.Type.PROGCMD: 
    97                                 this.compileProgramCommand(sequence); 
    98                                 break; 
    99                         case Token.Type.MODCMD: 
    100                                 this.compileUserDefCommand(sequence); 
    101                                 break; 
    102                         case Token.Type.INTCMD: 
    103                                 this.compileBasicCommand(sequence); 
    104                                 break; 
    105                         case Token.Type.EXTCMD: 
    106                                 this.compileGuiCommand(sequence); 
    107                                 break; 
    108                         case Token.Type.DLLFUNC: 
    109                         case Token.Type.DLLCTRL: 
    110                                 this.compileCommand(sequence); 
    111                                 break; 
    112                         default: 
    113                                 throw this.error("命令コード " + token.type + " は解釈できません。"); 
    114                         } 
    115                 } 
    116                 return sequence; 
     75                        this.pushLabels(sequence, token.pos); 
     76                        this.compileStatement(sequence); 
     77                } 
     78                this.defineInsnIndex(sequence); 
     79                this.defineLabelPos(sequence); 
     80                var result = this.sequenceToArray(sequence); 
     81                this.deleteLink(sequence); 
     82                return result; 
     83        }, 
     84        pushLabels: function(sequence, pos) { 
     85                var labelIDs = this.ax.labelsMap[pos]; 
     86                if(labelIDs) { 
     87                        for(var i = 0; i < labelIDs.length; i ++) { 
     88                                var labelID = labelIDs[i]; 
     89                                sequence.push(this.labels[labelID]); 
     90                        } 
     91                } 
     92                var labels = this.ifLabels[pos]; 
     93                if(labels) { 
     94                        for(var i = 0; i < labels.length; i ++) { 
     95                                sequence.push(labels[i]); 
     96                        } 
     97                } 
     98                delete this.ifLabels[pos]; 
     99        }, 
     100        defineInsnIndex: function(sequence) { 
     101                var index = 0; 
     102                sequence.forEachOnlyInsn(function(insn) { 
     103                        insn.index = index++; 
     104                }); 
     105        }, 
     106        defineLabelPos: function(sequence) { 
     107                sequence.forEach(function(elem) { 
     108                        if(elem.type != ISeqElem.Type.LABEL) return; 
     109                        elem.definePos(); 
     110                }); 
     111        }, 
     112        sequenceToArray: function(sequence) { 
     113                var result = []; 
     114                sequence.forEachOnlyInsn(function(insn) { 
     115                        result.push(insn); 
     116                }); 
     117                return result; 
     118        }, 
     119        deleteLink: function(sequence) { 
     120                var elem = sequence.first(); 
     121                while(elem) { 
     122                        var next = elem.next; 
     123                        elem.next = elem.prev = null; 
     124                        elem = next; 
     125                } 
     126                ISeq.link(sequence.firstGuard, sequence.lastGuard); 
    117127        }, 
    118128        pushNewInsn: function(sequence, code, opts, token) { 
    119                 token || (token = this.ax.tokens[this.tokensPos]); 
    120                 sequence.push(new Instruction(code, opts, token.fileName, token.lineNo)); 
     129                if(!token) token = this.ax.tokens[this.tokensPos]; 
     130                sequence.push(new Insn(code, opts, token.fileName, token.lineNo)); 
    121131        }, 
    122132        getFinfoIdByMinfoId: function(minfoId) { 
     
    131141        }, 
    132142        error: function(message, token) { 
    133                 token || (token = this.ax.tokens[this.tokensPos]); 
     143                if(!token) token = this.ax.tokens[this.tokensPos]; 
    134144                return new CompileError(message, token.fileName, token.lineNo); 
     145        }, 
     146        compileStatement: function(sequence) { 
     147                var token = this.ax.tokens[this.tokensPos]; 
     148                switch(token.type) { 
     149                case Token.Type.VAR: 
     150                case Token.Type.STRUCT: 
     151                        this.compileAssignment(sequence); 
     152                        break; 
     153                case Token.Type.CMPCMD: 
     154                        this.compileBranchCommand(sequence); 
     155                        break; 
     156                case Token.Type.PROGCMD: 
     157                        this.compileProgramCommand(sequence); 
     158                        break; 
     159                case Token.Type.MODCMD: 
     160                        this.compileUserDefCommand(sequence); 
     161                        break; 
     162                case Token.Type.INTCMD: 
     163                        this.compileBasicCommand(sequence); 
     164                        break; 
     165                case Token.Type.EXTCMD: 
     166                        this.compileGuiCommand(sequence); 
     167                        break; 
     168                case Token.Type.DLLFUNC: 
     169                case Token.Type.DLLCTRL: 
     170                        this.compileCommand(sequence); 
     171                        break; 
     172                default: 
     173                        throw this.error("命令コード " + token.type + " は解釈できません。"); 
     174                } 
    135175        }, 
    136176        compileAssignment: function(sequence) { 
     
    146186                        // インクリメント / デクリメント 
    147187                        var indexParamInfos = this.compileNodes(sequence, indexNodes); 
    148                         this.pushNewInsn(sequence, Instruction.Code.INC + token.val, [varData, indexParamInfos], token); 
     188                        this.pushNewInsn(sequence, Insn.Code.INC + token.val, [varData, indexParamInfos], token); 
    149189                        return; 
    150190                } 
     
    156196                                throw this.error("複合代入のパラメータの数が間違っています。", token); 
    157197                        } 
    158                         this.pushNewInsn(sequence, Instruction.Code.COMPOUND_ASSIGN, [token.val, varData, indexParamInfos, rhsParamInfos[0]], token); 
     198                        this.pushNewInsn(sequence, Insn.Code.COMPOUND_ASSIGN, [token.val, varData, indexParamInfos, rhsParamInfos[0]], token); 
    159199                        return; 
    160200                } 
     
    162202                        throw this.error("代入のパラメータの数が間違っています。", token); 
    163203                } 
    164                 this.pushNewInsn(sequence, Instruction.Code.ASSIGN, [varData, indexParamInfos, rhsParamInfos], token); 
     204                this.pushNewInsn(sequence, Insn.Code.ASSIGN, [varData, indexParamInfos, rhsParamInfos], token); 
    165205        }, 
    166206        compileProgramCommand: function(sequence) { 
     
    170210                        var labelToken = this.ax.tokens[this.tokensPos + 1]; 
    171211                        if(labelToken && labelToken.type == Token.Type.LABEL && !labelToken.ex2 && (!this.ax.tokens[this.tokensPos + 2] || this.ax.tokens[this.tokensPos + 2].ex1)) { 
    172                                 this.pushNewInsn(sequence, Instruction.Code.GOTO, 
     212                                this.pushNewInsn(sequence, Insn.Code.GOTO, 
    173213                                                 [this.labels[labelToken.code]]); 
    174214                                this.tokensPos += 2; 
     
    177217                                var paramInfos = this.compileParameters(sequence); 
    178218                                if(paramInfos.length != 1) throw this.error('goto の引数の数が違います', token); 
    179                                 this.pushNewInsn(sequence, Instruction.Code.GOTO_EXPR, [paramInfos[0]], token); 
     219                                this.pushNewInsn(sequence, Insn.Code.GOTO_EXPR, [paramInfos[0]], token); 
    180220                        } 
    181221                        break; 
     
    183223                        var labelToken = this.ax.tokens[this.tokensPos + 1]; 
    184224                        if(labelToken && labelToken.type == Token.Type.LABEL && !labelToken.ex2 && (!this.ax.tokens[this.tokensPos + 2] || this.ax.tokens[this.tokensPos + 2].ex1)) { 
    185                                 this.pushNewInsn(sequence, Instruction.Code.GOSUB, 
     225                                this.pushNewInsn(sequence, Insn.Code.GOSUB, 
    186226                                                 [this.labels[labelToken.code]]); 
    187227                                this.tokensPos += 2; 
     
    190230                                var paramInfos = this.compileParameters(sequence); 
    191231                                if(paramInfos.length != 1) throw this.error('gosub の引数の数が違います', token); 
    192                                 this.pushNewInsn(sequence, Instruction.Code.GOSUB_EXPR, [paramInfos[0]], token); 
     232                                this.pushNewInsn(sequence, Insn.Code.GOSUB_EXPR, [paramInfos[0]], token); 
    193233                        } 
    194234                        break; 
     
    202242                                if(this.getParametersNodesSub().length > 0) throw this.error('return の引数が多すぎます', token); 
    203243                        } 
    204                         this.pushNewInsn(sequence, Instruction.Code.RETURN, [paramInfo], token); 
     244                        this.pushNewInsn(sequence, Insn.Code.RETURN, [paramInfo], token); 
    205245                        break; 
    206246                case 0x03: // break 
     
    211251                        } 
    212252                        if(this.getParametersNodes().length > 0) throw this.error('break の引数が多すぎます', token); 
    213                         this.pushNewInsn(sequence, Instruction.Code.BREAK, 
     253                        this.pushNewInsn(sequence, Insn.Code.BREAK, 
    214254                                         [this.labels[labelToken.code]], token); 
    215255                        break; 
     
    222262                        var paramInfos = this.compileParameters(sequence, false, false, paramInfos); 
    223263                        if(paramInfos.length > 2) throw this.error('repeat の引数が多すぎます', token); 
    224                         this.pushNewInsn(sequence, Instruction.Code.REPEAT, 
     264                        this.pushNewInsn(sequence, Insn.Code.REPEAT, 
    225265                                         [this.labels[labelToken.code], paramInfos], token); 
    226266                        break; 
     
    228268                        this.tokensPos ++; 
    229269                        if(this.getParametersNodes().length > 0) throw this.error('loop の引数が多すぎます', token); 
    230                         this.pushNewInsn(sequence, Instruction.Code.LOOP, [], token); 
     270                        this.pushNewInsn(sequence, Insn.Code.LOOP, [], token); 
    231271                        break; 
    232272                case 0x06: // continue 
     
    238278                        var paramInfos = this.compileParameters(sequence); 
    239279                        if(paramInfos.length > 1) throw this.error('continue の引数が多すぎます', token); 
    240                         this.pushNewInsn(sequence, Instruction.Code.CONTINUE, 
     280                        this.pushNewInsn(sequence, Insn.Code.CONTINUE, 
    241281                                         [this.labels[labelToken.code], paramInfos[0]], token); 
    242282                        break; 
     
    248288                        } 
    249289                        if(this.getParametersNodes().length > 0) throw this.error(); 
    250                         this.pushNewInsn(sequence, Instruction.Code.FOREACH, 
     290                        this.pushNewInsn(sequence, Insn.Code.FOREACH, 
    251291                                         [this.labels[labelToken.code]], token); 
    252292                        break; 
     
    259299                        var paramInfos = this.compileParameters(sequence); 
    260300                        if(paramInfos.length != 1) throw this.error('foreach の引数の数が違います', token); 
    261                         this.pushNewInsn(sequence, Instruction.Code.EACHCHK, 
     301                        this.pushNewInsn(sequence, Insn.Code.EACHCHK, 
    262302                                         [this.labels[labelToken.code], paramInfos[0]], token); 
    263303                        break; 
     
    282322                                argc = this.getParametersNodesSub().length; 
    283323                        } 
    284                         this.pushNewInsn(sequence, Instruction.Code.NEWMOD, 
     324                        this.pushNewInsn(sequence, Insn.Code.NEWMOD, 
    285325                                             [this.compileNode(sequence, varNode), module, paramInfos, argc], token); 
    286326                        break; 
     
    289329                        var paramInfos = this.compileParameters(sequence, false, true); 
    290330                        if(paramInfos.length != 4) throw this.error('exgoto の引数の数が違います', token); 
    291                         this.pushNewInsn(sequence, Instruction.Code.EXGOTO, [paramInfos], token); 
     331                        this.pushNewInsn(sequence, Insn.Code.EXGOTO, [paramInfos], token); 
    292332                        break; 
    293333                case 0x19: // on 
     
    305345                        this.tokensPos ++; 
    306346                        var labelParamInfos = this.compileParametersSub(sequence); 
    307                         this.pushNewInsn(sequence, Instruction.Code.ON, [isGosub, labelParamInfos, indexParamInfo], token); 
     347                        this.pushNewInsn(sequence, Insn.Code.ON, [isGosub, labelParamInfos, indexParamInfo], token); 
    308348                        break; 
    309349                default: 
     
    322362                        var paramInfos = [this.compileOptionalJumpType(sequence)]; 
    323363                        this.compileParameters(sequence, false, false, paramInfos); 
    324                         this.pushNewInsn(sequence, Instruction.Code.CALL_BUILTIN_CMD, 
     364                        this.pushNewInsn(sequence, Insn.Code.CALL_BUILTIN_CMD, 
    325365                                         [token.type, token.code, paramInfos], token); 
    326366                        break; 
     
    336376                        var paramInfos = [this.compileOptionalJumpType(sequence)]; 
    337377                        this.compileParameters(sequence, false, false, paramInfos); 
    338                         this.pushNewInsn(sequence, Instruction.Code.CALL_BUILTIN_CMD, 
     378                        this.pushNewInsn(sequence, Insn.Code.CALL_BUILTIN_CMD, 
    339379                                         [token.type, token.code, paramInfos], token); 
    340380                        break; 
     
    346386                var token = this.ax.tokens[this.tokensPos++]; 
    347387                var paramInfos = this.compileParameters(sequence); 
    348                 this.pushNewInsn(sequence, Instruction.Code.CALL_BUILTIN_CMD, 
     388                this.pushNewInsn(sequence, Insn.Code.CALL_BUILTIN_CMD, 
    349389                                 [token.type, token.code, paramInfos], token); 
    350390        }, 
     
    367407                           (node.val.getType() == VarType.INT || node.val.getType() == VarType.DOUBLE)) { 
    368408                                if(!node.val._value) { 
    369                                         this.pushNewInsn(sequence, Instruction.Code.GOTO, [label], token); 
     409                                        this.pushNewInsn(sequence, Insn.Code.GOTO, [label], token); 
    370410                                } 
    371411                                return; 
    372412                        } 
    373                         this.pushNewInsn(sequence, Instruction.Code.IFEQ, [label, paramInfo], token); 
     413                        this.pushNewInsn(sequence, Insn.Code.IFEQ, [label, paramInfo], token); 
    374414                } else { 
    375415                        if(nodes.length != 0) throw this.error("else の引数の数が間違っています。", token); 
    376                         this.pushNewInsn(sequence, Instruction.Code.GOTO, [label], token); 
     416                        this.pushNewInsn(sequence, Insn.Code.GOTO, [label], token); 
    377417                } 
    378418        }, 
     
    415455                                        stackSize ++; 
    416456                                        self.pushNewInsn(sequence, 
    417                                                          node.onlyValue ? Instruction.Code.GET_VAR : Instruction.Code.PUSH_VAR, 
     457                                                         node.onlyValue ? Insn.Code.GET_VAR : Insn.Code.PUSH_VAR, 
    418458                                                         [node.varData, self.compileNodes(sequence, node.indexNodes)], 
    419459                                                         node.token); 
     
    423463                                break; 
    424464                        case NodeType.LITERAL: 
     465                                break; 
     466                        case NodeType.LABEL: 
    425467                                break; 
    426468                        case NodeType.DEFAULT: 
     
    435477                                var paramInfos = self.compileNodes(sequence, node.paramNodes); 
    436478                                self.pushNewInsn(sequence, 
    437                                                  Instruction.Code.CALL_USERDEF_FUNC, 
     479                                                 Insn.Code.CALL_USERDEF_FUNC, 
    438480                                                 [node.userDefFunc, paramInfos], 
    439481                                                 node.token); 
     
    444486                                var paramInfos = self.compileNodes(sequence, node.paramNodes); 
    445487                                if(node.groupId == Token.Type.SYSVAR && node.subId == 0x04) { 
    446                                         self.pushNewInsn(sequence, Instruction.Code.CNT, [], node.token); 
     488                                        self.pushNewInsn(sequence, Insn.Code.CNT, [], node.token); 
    447489                                        break; 
    448490                                } 
    449491                                self.pushNewInsn(sequence, 
    450                                                  Instruction.Code.CALL_BUILTIN_FUNC, 
     492                                                 Insn.Code.CALL_BUILTIN_FUNC, 
    451493                                                 [node.groupId, node.subId, paramInfos], 
    452494                                                 node.token); 
     
    530572                                break; 
    531573                        case Token.Type.LABEL: 
    532                                 stack.push(new LiteralNode(this.labels[token.code])); 
     574                                stack.push(new LabelNode(this.labels[token.code])); 
    533575                                this.tokensPos ++; 
    534576                                break; 
     
    698740                var userDefFunc = this.getUserDefFunc(token.code); 
    699741                var paramInfos = this.compileNodes(sequence, this.getUserDefFuncallParamNodes(userDefFunc, false, true)); 
    700                 this.pushNewInsn(sequence, Instruction.Code.CALL_USERDEF_CMD, 
     742                this.pushNewInsn(sequence, Insn.Code.CALL_USERDEF_CMD, 
    701743                                 [userDefFunc, paramInfos], token); 
    702744        }, 
  • lang/javascript/hsp-on-js/trunk/src/create-package

    r28263 r29704  
    2626vartype.js 
    2727value.js 
    28 label.js 
     28label-value.js 
    2929str-value.js 
    3030double-value.js 
  • lang/javascript/hsp-on-js/trunk/src/evaluator.js

    r29399 r29704  
    396396                        push('this.frameStack.push(new Frame('+(pc + 1)+', userDefFuncs['+userDefFunc.id+'], args, this.args));'); 
    397397                        push('this.args = args;'); 
    398                         push('this.pc = '+userDefFunc.label.pos+';'); 
     398                        push('this.pc = '+userDefFunc.label.getPos()+';'); 
    399399                } 
    400400                function pushCallingUserdefFuncCode0(mptypes, paramInfos, constructorThismodExpr) { 
     
    547547                        case NodeType.LITERAL: 
    548548                                return getLiteralExpr(node.val); 
     549                        case NodeType.LABEL: 
     550                                return getLiteralExpr(new LabelValue(node.getLabelPos())); 
    549551                        case NodeType.DEFAULT: 
    550552                                return 'throwHSPError('+ErrorCode.NO_DEFAULT+')'; 
     
    637639                function getLabelParamNativeValueExpr(paramInfo) { 
    638640                        var node = paramInfo.node; 
    639                         if(node.isLiteralNode() && node.val.getType() == VarType.LABEL) { 
    640                                 return '' + node.val.pos; 
     641                        if(node.isLabelNode()) { 
     642                                return '' + node.getLabelPos(); 
    641643                        } 
    642644                        return 'this.scanArg('+getParamExpr(paramInfo)+', "l").toValue().pos'; 
     
    660662                } 
    661663                var insn2func = []; 
    662                 insn2func[Instruction.Code.NOP] = function(insn, pc) { 
    663                 }; 
    664                 insn2func[Instruction.Code.PUSH_VAR] = function(insn, pc) { 
     664                insn2func[Insn.Code.NOP] = function(insn, pc) { 
     665                }; 
     666                insn2func[Insn.Code.PUSH_VAR] = function(insn, pc) { 
    665667                        var varData = insn.opts[0]; 
    666668                        var indexParamInfos = insn.opts[1]; 
    667669                        pushGettingVariableCode(varData, indexParamInfos); 
    668670                }; 
    669                 insn2func[Instruction.Code.GET_VAR] = function(insn, pc) { 
     671                insn2func[Insn.Code.GET_VAR] = function(insn, pc) { 
    670672                        var varData = insn.opts[0]; 
    671673                        var indexParamInfos = insn.opts[1]; 
    672674                        pushGettingArrayValueCode(varData, indexParamInfos); 
    673675                }; 
    674                 insn2func[Instruction.Code.POP] = function(insn, pc) { 
     676                insn2func[Insn.Code.POP] = function(insn, pc) { 
    675677                        push('stack.pop();'); 
    676678                }; 
    677                 insn2func[Instruction.Code.POP_N] = function(insn, pc) { 
     679                insn2func[Insn.Code.POP_N] = function(insn, pc) { 
    678680                        pushStackPopCode(insn.opts[0]); 
    679681                }; 
    680                 insn2func[Instruction.Code.DUP] = function(insn, pc) { 
     682                insn2func[Insn.Code.DUP] = function(insn, pc) { 
    681683                        push('stack.push(stack[stack.length-1]);'); 
    682684                }; 
    683                 insn2func[Instruction.Code.GOTO] = function(insn, pc) { 
    684                         push('this.pc = '+insn.opts[0].pos+';'); 
     685                insn2func[Insn.Code.GOTO] = function(insn, pc) { 
     686                        push('this.pc = '+insn.opts[0].getPos()+';'); 
    685687                        push('continue;'); 
    686688                }; 
    687                 insn2func[Instruction.Code.IFNE] = 
    688                 insn2func[Instruction.Code.IFEQ] = function(insn, pc) { 
     689                insn2func[Insn.Code.IFNE] = 
     690                insn2func[Insn.Code.IFEQ] = function(insn, pc) { 
    689691                        var label = insn.opts[0]; 
    690692                        var paramInfo = insn.opts[1]; 
    691693                        var expr = getParamExpr(paramInfo)+'.toIntValue()._value'; 
    692                         if(insn.code == Instruction.Code.IFEQ) { 
     694                        if(insn.code == Insn.Code.IFEQ) { 
    693695                                expr = '!' + expr; 
    694696                        } 
    695697                        push('if('+expr+') {'); 
    696                         push('    this.pc = '+insn.opts[0].pos+';'); 
     698                        push('    this.pc = '+insn.opts[0].getPos()+';'); 
    697699                        push('    continue;'); 
    698700                        push('}'); 
    699701                }; 
    700                 insn2func[Instruction.Code.ASSIGN] = function(insn, pc) { 
     702                insn2func[Insn.Code.ASSIGN] = function(insn, pc) { 
    701703                        var varData = insn.opts[0]; 
    702704                        var indexParamInfos = insn.opts[1]; 
     
    704706                        pushAssignCode(varData, indexParamInfos, rhsParamInfos); 
    705707                }; 
    706                 insn2func[Instruction.Code.COMPOUND_ASSIGN] = function(insn, pc) { 
     708                insn2func[Insn.Code.COMPOUND_ASSIGN] = function(insn, pc) { 
    707709                        var calcCode = insn.opts[0]; 
    708710                        var varData = insn.opts[1]; 
     
    711713                        pushCompoundAssignCode(calcCode, varData, indexParamInfos, rhsParamInfo); 
    712714                }; 
    713                 insn2func[Instruction.Code.INC] = function(insn, pc) { 
     715                insn2func[Insn.Code.INC] = function(insn, pc) { 
    714716                        var varData = insn.opts[0]; 
    715717                        var indexParamInfos = insn.opts[1]; 
    716718                        pushIncCode(varData, indexParamInfos); 
    717719                }; 
    718                 insn2func[Instruction.Code.DEC] = function(insn, pc) { 
     720                insn2func[Insn.Code.DEC] = function(insn, pc) { 
    719721                        var varData = insn.opts[0]; 
    720722                        var indexParamInfos = insn.opts[1]; 
    721723                        pushDecCode(varData, indexParamInfos); 
    722724                }; 
    723                 insn2func[Instruction.Code.CALL_BUILTIN_CMD] = 
    724                 insn2func[Instruction.Code.CALL_BUILTIN_FUNC] = function(insn, pc) { 
     725                insn2func[Insn.Code.CALL_BUILTIN_CMD] = 
     726                insn2func[Insn.Code.CALL_BUILTIN_FUNC] = function(insn, pc) { 
    725727                        var type = insn.opts[0]; 
    726728                        var subid = insn.opts[1]; 
     
    740742                                } 
    741743                        } 
    742                         if(insn.code == Instruction.Code.CALL_BUILTIN_FUNC) { 
     744                        if(insn.code == Insn.Code.CALL_BUILTIN_FUNC) { 
    743745                                push('stack.push(func.apply(this, args));'); 
    744746                        } else { 
     
    746748                        } 
    747749                }; 
    748                 insn2func[Instruction.Code.CALL_USERDEF_CMD] = 
    749                 insn2func[Instruction.Code.CALL_USERDEF_FUNC] = function(insn, pc) { 
     750                insn2func[Insn.Code.CALL_USERDEF_CMD] = 
     751                insn2func[Insn.Code.CALL_USERDEF_FUNC] = function(insn, pc) { 
    750752                        var userDefFunc = insn.opts[0]; 
    751753                        var paramInfos = insn.opts[1]; 
     
    753755                        push('continue;'); 
    754756                }; 
    755                 insn2func[Instruction.Code.NEWMOD] = function(insn, pc) { 
     757                insn2func[Insn.Code.NEWMOD] = function(insn, pc) { 
    756758                        var varParamInfo = insn.opts[0]; 
    757759                        var module = insn.opts[1]; 
     
    780782                        } 
    781783                }; 
    782                 insn2func[Instruction.Code.RETURN] = function(insn, pc) { 
     784                insn2func[Insn.Code.RETURN] = function(insn, pc) { 
    783785                        var paramInfo = insn.opts[0]; 
    784786                        push('if(this.frameStack.length == 0) {'); 
     
    816818                        push('continue;'); 
    817819                }; 
    818                 insn2func[Instruction.Code.REPEAT] = function(insn, pc) { 
    819                         var pos = insn.opts[0].pos; 
     820                insn2func[Insn.Code.REPEAT] = function(insn, pc) { 
     821                        var pos = insn.opts[0].getPos(); 
    820822                        var paramInfos = insn.opts[1]; 
    821823                        push('if(this.loopStack.length >= 31) {'); 
     
    840842                        push('this.loopStack.push(new LoopData(begin, end, '+(pc + 1)+'));'); 
    841843                }; 
    842                 insn2func[Instruction.Code.LOOP] = function(insn, pc) { 
     844                insn2func[Insn.Code.LOOP] = function(insn, pc) { 
    843845                        push('if(this.loopStack.length == 0) {'); 
    844846                        push('    throw new HSPError(ErrorCode.LOOP_WITHOUT_REPEAT);'); 
     
    852854                        push('this.loopStack.pop();'); 
    853855                }; 
    854                 insn2func[Instruction.Code.CNT] = function(insn, pc) { 
     856                insn2func[Insn.Code.CNT] = function(insn, pc) { 
    855857                        push('if(this.loopStack.length == 0) {'); 
    856858                        push('    stack.push(new IntValue(0));'); 
     
    859861                        push('}'); 
    860862                }; 
    861                 insn2func[Instruction.Code.CONTINUE] = function(insn, pc) { 
    862                         var pos = insn.opts[0].pos; 
     863                insn2func[Insn.Code.CONTINUE] = function(insn, pc) { 
     864                        var pos = insn.opts[0].getPos(); 
    863865                        var paramInfo = insn.opts[1]; 
    864866                        push('if(this.loopStack.length == 0) {'); 
     
    880882                        push('continue;'); 
    881883                }; 
    882                 insn2func[Instruction.Code.BREAK] = function(insn, pc) { 
     884                insn2func[Insn.Code.BREAK] = function(insn, pc) { 
    883885                        var label = insn.opts[0]; 
    884886                        push('if(this.loopStack.length == 0) {'); 
     
    886888                        push('}'); 
    887889                        push('this.loopStack.pop();'); 
    888                         push('this.pc = '+label.pos+';'); 
     890                        push('this.pc = '+label.getPos()+';'); 
    889891                        push('continue;'); 
    890892                }; 
    891                 insn2func[Instruction.Code.FOREACH] = function(insn, pc) { 
     893                insn2func[Insn.Code.FOREACH] = function(insn, pc) { 
    892894                        push('if(this.loopStack.length >= 31) {'); 
    893895                        push('    throw new HSPError(ErrorCode.TOO_MANY_NEST);'); 
     
    895897                        push('this.loopStack.push(new LoopData(0, Infinity, '+(pc + 1)+'));'); 
    896898                }; 
    897                 insn2func[Instruction.Code.EACHCHK] = function(insn, pc) { 
     899                insn2func[Insn.Code.EACHCHK] = function(insn, pc) { 
    898900                        push('if(this.loopStack.length == 0) {'); 
    899901                        push('    throw new HSPError(ErrorCode.LOOP_WITHOUT_REPEAT);') 
    900902                        push('}') 
    901                         var pos = insn.opts[0].pos; 
     903                        var pos = insn.opts[0].getPos(); 
    902904                        var paramInfo = insn.opts[1]; 
    903905                        push('var array = '+getNoSubscriptVariableExpr(paramInfo)+'.value;'); 
     
    919921                        push('}'); 
    920922                }; 
    921                 insn2func[Instruction.Code.GOSUB] = function(insn, pc) { 
     923                insn2func[Insn.Code.GOSUB] = function(insn, pc) { 
    922924                        pushJumpingSubroutineCode(pc); 
    923                         push('this.pc = '+insn.opts[0].pos+';'); 
     925                        push('this.pc = '+insn.opts[0].getPos()+';'); 
    924926                        push('continue;'); 
    925927                }; 
    926                 insn2func[Instruction.Code.GOTO_EXPR] = 
    927                 insn2func[Instruction.Code.GOSUB_EXPR] = function(insn, pc) { 
     928                insn2func[Insn.Code.GOTO_EXPR] = 
     929                insn2func[Insn.Code.GOSUB_EXPR] = function(insn, pc) { 
    928930                        var paramInfo = insn.opts[0]; 
    929                         if(insn.code == Instruction.Code.GOSUB_EXPR) { 
     931                        if(insn.code == Insn.Code.GOSUB_EXPR) { 
    930932                                pushJumpingSubroutineCode(pc); 
    931933                        } 
     
    933935                        push('continue;'); 
    934936                }; 
    935                 insn2func[Instruction.Code.EXGOTO] = function(insn, pc) { 
     937                insn2func[Insn.Code.EXGOTO] = function(insn, pc) { 
    936938                        var paramInfos = insn.opts[0]; 
    937939                        var counterParamInfo = paramInfos[0]; 
     
    968970                        push('}'); 
    969971                }; 
    970                 insn2func[Instruction.Code.ON] = function(insn, pc) { 
     972                insn2func[Insn.Code.ON] = function(insn, pc) { 
    971973                        var isGosub = insn.opts[0]; 
    972974                        var labelParamInfos = insn.opts[1]; 
     
    976978                        for(var i = 0; i < labelParamInfos.length; i ++) { 
    977979                                var paramInfo = labelParamInfos[i]; 
    978                                 if(paramInfo.node.isLiteralNode() && paramInfo.node.val.getType() == VarType.LABEL) { 
    979                                         labelExprs[i] = '' + paramInfo.node.val.pos; 
     980                                if(paramInfo.node.isLabelNode()) { 
     981                                        labelExprs[i] = '' + paramInfo.node.getLabelPos(); 
    980982                                } else { 
    981983                                        if(labelsIndex == null) { 
     
    11191121        }, 
    11201122        getBuiltinFuncName: function(insn) { 
    1121                 if(insn.code != Instruction.Code.CALL_BUILTIN_CMD && 
    1122                    insn.code != Instruction.Code.CALL_BUILTIN_FUNC) { 
     1123                if(insn.code != Insn.Code.CALL_BUILTIN_CMD && 
     1124                   insn.code != Insn.Code.CALL_BUILTIN_FUNC) { 
    11231125                        return undefined; 
    11241126                } 
  • lang/javascript/hsp-on-js/trunk/src/instruction.js

    r28714 r29704  
    1 function Instruction(code, opts, fileName, lineNo) { 
     1var ISeq; 
     2var ISeqElem; 
     3var Label; 
     4var Insn; 
     5var getInsnCodeName; 
     6 
     7(function() { 
     8 
     9ISeq = function() { 
     10        this.firstGuard = new ISeqElem; 
     11        this.lastGuard = new ISeqElem; 
     12        link(this.firstGuard, this.lastGuard); 
     13} 
     14 
     15function link() { 
     16        for(var i = 0; i < arguments.length - 1; i ++) { 
     17                var a = arguments[i]; 
     18                var b = arguments[i+1]; 
     19                if(a) a.next = b; 
     20                if(b) b.prev = a; 
     21        } 
     22} 
     23 
     24ISeq.link = link; 
     25 
     26ISeq.prototype = { 
     27        first: function() { 
     28                return this.firstGuard.next; 
     29        }, 
     30        last: function() { 
     31                return this.lastGuard.prev; 
     32        }, 
     33        push: function(elem) { 
     34                link(this.last(), elem, this.lastGuard); 
     35                return this; 
     36        }, 
     37        pop: function() { 
     38                return this.last().remove(); 
     39        }, 
     40        shift: function() { 
     41                return this.first().remove(); 
     42        }, 
     43        unshift: function(elem) { 
     44                return this.first().insertBefore(elem); 
     45        }, 
     46        forEach: function(callback) { 
     47                var elem = this.first(); 
     48                var end = this.lastGuard; 
     49                while(elem != end) { 
     50                        callback(elem); 
     51                        elem = elem.next; 
     52                } 
     53        }, 
     54        forEachOnlyInsn: function(callback) { 
     55                var elem = this.first(); 
     56                while(elem) { 
     57                        if(elem.type == ISeqElem.Type.INSN) { 
     58                                callback(elem); 
     59                        } 
     60                        elem = elem.next; 
     61                } 
     62        }, 
     63        getLength: function() { 
     64                var length = 0; 
     65                this.forEach(function() { length ++; }); 
     66                return length; 
     67        }, 
     68        toString: function() { 
     69                return '<ISeq:len='+this.getLength()+'>'; 
     70        } 
     71}; 
     72 
     73ISeqElem = function() { 
     74        this.prev = null; 
     75        this.next = null; 
     76}; 
     77 
     78ISeqElem.Type = { 
     79        NONE:  0, 
     80        INSN:  1, 
     81        LABEL: 2 
     82}; 
     83 
     84ISeqElem.prototype = { 
     85        type: ISeqElem.Type.NONE, 
     86        remove: function() { 
     87                link(this.prev, this.next); 
     88                link(null, this, null); 
     89                return this; 
     90        }, 
     91        replace: function(insn) { 
     92                link(this.prev, insn, this.next); 
     93                link(null, this, null); 
     94        }, 
     95        insertAfter: function() { 
     96                var args = [this]; 
     97                args.push.apply(args, arguments); 
     98                args.push(this.next); 
     99                link.apply(null, args); 
     100        }, 
     101        insertBefore: function(insn) { 
     102                var args = [this.prev]; 
     103                args.push.apply(args, arguments); 
     104                args.push(this); 
     105                link.apply(null, args); 
     106        }, 
     107        getNextInsn: function() { 
     108                var elem = this.next; 
     109                while(elem) { 
     110                        if(elem.type == ISeqElem.Type.INSN) { 
     111                                return elem; 
     112                        } 
     113                        elem = elem.next; 
     114                } 
     115                return null; 
     116        }, 
     117        getPrevInsn: function() { 
     118                var elem = this.prev; 
     119                while(elem) { 
     120                        if(elem.type == ISeqElem.Type.INSN) { 
     121                                return elem; 
     122                        } 
     123                        elem = elem.prev; 
     124                } 
     125                return null; 
     126        }, 
     127        getNextElem: function() { 
     128                var elem = this.next; 
     129                while(elem) { 
     130                        if(elem.type == ISeqElem.Type.INSN || elem.type == ISeqElem.Type.NONE) { 
     131                                return elem; 
     132                        } 
     133                        elem = elem.next; 
     134                } 
     135                return null; 
     136        }, 
     137        getPrevElem: function() { 
     138                var elem = this.prev; 
     139                while(elem) { 
     140                        if(elem.type == ISeqElem.Type.INSN || elem.type == ISeqElem.Type.NONE) { 
     141                                return elem; 
     142                        } 
     143                        elem = elem.prev; 
     144                } 
     145                return null; 
     146        } 
     147}; 
     148 
     149Label = function() { 
     150        ISeqElem.call(this); 
     151        this.pos_ = -1; 
     152}; 
     153 
     154Label.prototype = new ISeqElem; 
     155 
     156Utils.objectExtend(Label.prototype, { 
     157        toString: function() { 
     158                return '<Label:'+this.pos_+'>'; 
     159        }, 
     160        getInsn: function() { 
     161                return this.getNextInsn(); 
     162        }, 
     163        getPos: function() { 
     164                return this.pos_; 
     165        }, 
     166        definePos: function() { 
     167                this.pos_ = this.getInsn().index; 
     168        }, 
     169        type: ISeqElem.Type.LABEL 
     170}); 
     171 
     172Insn = function(code, opts, fileName, lineNo) { 
     173        ISeqElem.call(this); 
    2174        this.code = code; 
    3175        this.opts = opts; 
    4176        this.fileName = fileName; 
    5177        this.lineNo = lineNo; 
    6 } 
    7  
    8 Instruction.prototype.toString = function() { 
    9         return this.fileName + '#' + this.lineNo + ': ' + Instruction.CodeNames[this.code] + ' <' + this.opts.join(', ') + '>'; 
    10 }; 
    11  
    12 Instruction.CodeNames = [ 
     178        this.index = -1; 
     179}; 
     180 
     181Insn.prototype = new ISeqElem; 
     182 
     183Utils.objectExtend(Insn.prototype, { 
     184        toString: function() { 
     185                return '<Insn:'+getInsnCodeName(this.code)+' <' + this.opts.join(', ') + '> ('+this.fileName + ':' + this.lineNo+')>'; 
     186        }, 
     187        clone: function() { 
     188                return new Insn(this.code, this.opts, this.fileName, this.lineNo); 
     189        }, 
     190        type: ISeqElem.Type.INSN 
     191}); 
     192 
     193var codeNames = [ 
    13194        'NOP', 
    14195        'PUSH_VAR', 
     
    45226]; 
    46227 
    47 Instruction.Code = {}; 
    48 (function(){ 
    49         for(var i = 0; i < Instruction.CodeNames.length; i ++) { 
    50                 var name = Instruction.CodeNames[i]; 
    51                 Instruction.Code[name] = i; 
     228getInsnCodeName = function(insnCode) { 
     229        return codeNames[insnCode]; 
     230} 
     231 
     232Insn.Code = {}; 
     233(function() { 
     234        for(var i = 0; i < codeNames.length; i ++) { 
     235                var name = codeNames[i]; 
     236                Insn.Code[name] = i; 
    52237        } 
    53238})(); 
    54239 
     240})(); 
     241 
    55242if(typeof HSPonJS != 'undefined') { 
    56         HSPonJS.Instruction = Instruction; 
    57 } 
    58  
     243        HSPonJS.ISeq = ISeq; 
     244        HSPonJS.ISeqElem = ISeqElem; 
     245        HSPonJS.Label = Label; 
     246        HSPonJS.Insn = Insn; 
     247        HSPonJS.getInsnCodeName = getInsnCodeName; 
     248} 
     249 
  • lang/javascript/hsp-on-js/trunk/src/label-array.js

    r28714 r29704  
    11function LabelArray() { 
    22        HSPArray.call(this); 
    3         this.values = [Label.EMPTY]; 
     3        this.values = [LabelValue.EMPTY]; 
    44} 
    55 
     
    1111                if(isExpanded) { 
    1212                        var newLen = this.allLength(); 
    13                         var empty = Label.EMPTY; 
     13                        var empty = LabelValue.EMPTY; 
    1414                        for(var i = this.values.length; i < newLen; i ++) { 
    1515                                this.values[i] = empty; 
     
    2222                if(isExpanded) { 
    2323                        var newLen = this.l0; 
    24                         var empty = Label.EMPTY; 
     24                        var empty = LabelValue.EMPTY; 
    2525                        for(var i = this.values.length; i < newLen; i ++) { 
    2626                                this.values[i] = empty; 
  • lang/javascript/hsp-on-js/trunk/src/label-value.js

    r29399 r29704  
    1 function Label() { 
    2         this.pos = -1; 
     1function LabelValue(pos) { 
     2        if(pos != undefined) { 
     3                this.pos = pos; 
     4        } else { 
     5                this.pos = -1; 
     6        } 
    37} 
    48 
    5 Label.prototype = new Value; 
     9LabelValue.prototype = new Value; 
    610 
    7 Utils.objectExtend(Label.prototype, { 
     11Utils.objectExtend(LabelValue.prototype, { 
    812        toString: function() { 
    9                 return '<Label:'+this.pos+'>'; 
     13                return '<LabelValue:'+this.pos+'>'; 
    1014        }, 
    1115        getType: function() { 
     
    1317        }, 
    1418        isUsing: function() { 
    15                 return this != Label.EMPTY; 
     19                return true; 
    1620        } 
    1721}); 
    1822 
    19 Label.EMPTY = new Label; 
     23LabelValue.EMPTY = new LabelValue; 
     24LabelValue.EMPTY.isUsing = function() { return false; }; 
    2025 
    2126if(typeof HSPonJS != 'undefined') { 
    22         HSPonJS.Label = Label; 
     27        HSPonJS.LabelValue = LabelValue; 
    2328} 
    2429 
  • lang/javascript/hsp-on-js/trunk/src/param-info.js

    r28714 r29704  
    2121        isArgNode:     function() { return false; }, 
    2222        isLiteralNode: function() { return false; }, 
     23        isLabelNode:   function() { return false; }, 
    2324        isDefaultNode: function() { return false; }, 
    2425        isOperateNode: function() { return false; }, 
     
    3435        ARG:     2, 
    3536        LITERAL: 3, 
    36         DEFAULT: 4, 
    37         OPERATE: 5, 
    38         USERDEF_FUNCALL: 6, 
    39         BUILTIN_FUNCALL: 7, 
    40         GET_STACK: 8 
     37        LABEL:   4, 
     38        DEFAULT: 5, 
     39        OPERATE: 6, 
     40        USERDEF_FUNCALL: 7, 
     41        BUILTIN_FUNCALL: 8, 
     42        GET_STACK: 9 
    4143}; 
    4244 
     
    8890        getValueType: function() { 
    8991                return this.val.getType(); 
     92        } 
     93}); 
     94 
     95function LabelNode(lobj) { 
     96        this.lobj = lobj; 
     97} 
     98LabelNode.prototype = new Node; 
     99Utils.objectExtend(LabelNode.prototype, { 
     100        nodeType: NodeType.LABEL, 
     101        isLabelNode: function() { return true; }, 
     102        toString: function() { 
     103                return '<LabelNode:'+this.lobj+'>'; 
     104        }, 
     105        getValueType: function() { 
     106                return VarType.LABEL; 
     107        }, 
     108        getLabelPos: function() { 
     109                return this.lobj.getPos(); 
    90110        } 
    91111}); 
  • lang/javascript/hsp-on-js/trunk/src/run-in-shell

    r28263 r29704  
    6262    vartype.js 
    6363    value.js 
    64     label.js 
     64    label-value.js 
    6565    str-value.js 
    6666    double-value.js 
  • lang/javascript/hsp-on-js/trunk/src/run-in-shell.js

    r28714 r29704  
    2525                var fileName, lineNo; 
    2626                sequence.forEach(function(insn, i) { 
    27                         var out = Formatter.sprintfForJS('%5d %-20s %-30s ', i, Instruction.CodeNames[insn.code], insn.opts.map(String).join(', ')); 
     27                        var out = Formatter.sprintfForJS('%5d %-20s %-30s ', i, getInsnCodeName(insn.code), insn.opts.map(String).join(', ')); 
    2828                        if(fileName != insn.fileName) { 
    2929                                fileName = insn.fileName;