Пример #1
0
        public int AddInstrLookup(string Mnemonic, int OpCode, int OpCount)
        {
            var Instr = new InstrLookup();

            Instr.Mnemonic = Mnemonic;
            Instr.OpCode   = OpCode;
            Instr.OpCount  = OpCount;
            InstrTable_.Add(Instr);
            return(InstrTable_.Count - 1);
        }
Пример #2
0
        public bool GetInstrByMnemonic(string Mnemonic, ref InstrLookup Instr)
        {
            for (var Index = 0; Index < InstrTable_.Count; ++Index)
            {
                if (InstrTable_[Index].Mnemonic == Mnemonic)
                {
                    Instr = InstrTable_[Index];
                    return(true);
                }
            }

            return(false);
        }
    public bool GetInstrByMnemonic(string mnemonic, out InstrLookup instrLookup)
    {
        for (int i = 0; i < MAX_INSTR_LOOKUP_COUNT; ++i)
        {
            if (instrTable [i].mnemonic == mnemonic)
            {
                instrLookup = instrTable [i];
                return(true);
            }
        }

        instrLookup = null;
        return(false);
    }
    public static int AddInstrLookup(string mnemonic, OpCode opCode, int opCount)
    {
        if (instrIndex >= MAX_INSTR_LOOKUP_COUNT)
        {
            return(-1);
        }

        var instr = instrTable [instrIndex];

        if (instr == null)
        {
            instr = new InstrLookup();
            instrTable [instrIndex] = instr;
        }

        instr.mnemonic = mnemonic;
        instr.opCode   = opCode;
        instr.opCount  = opCount;
        instr.opList   = new OpFlagType[opCount];

        return(instrIndex++);
    }
    private void SecondParse()
    {
        Token token = null;

        while ((token = lexer.NextToken()).type != TokenType.EOF)
        {
//            Console.WriteLine ( token );

            switch (token.type)
            {
            case TokenType.FUNC:

                isFuncActive      = true;
                currentFunc       = script.funcTable.GetFuncByName(lexer.NextToken().value);
                currentParamIndex = 0;
                break;

            case TokenType.CLOSE_BRACE:

                isFuncActive = false;
                if (currentFunc.name == XASMLexer.Keyworkd_Main)
                {
                    script.instrStream.instrs [instrStreamSize].opCode  = OpCode.Exit;
                    script.instrStream.instrs [instrStreamSize].opCount = 1;
                    script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                        type = OpType.INT, intLiteral = 0
                    });
                }
                else
                {
                    script.instrStream.instrs [instrStreamSize].opCode  = OpCode.Ret;
                    script.instrStream.instrs [instrStreamSize].opCount = 0;
                    script.instrStream.instrs [instrStreamSize].opList  = null;
                }

//					Console.WriteLine ( $"添加 {script.instrStream.instrs [ instrStreamSize ]} {instrStreamSize} {lexer.LexerPosition}" );

                instrStreamSize++;
                break;

            case TokenType.PARAM:

                var paramNameToken = lexer.NextToken();
                int stackIndex     = -(currentFunc.localDataSize + 2 + (currentParamIndex + 1));                       // +2 因为从-2 开始(-1保留) +1 因为参数在返回地址的下面

                if (script.symbolTable.AddSymbol(paramNameToken.value, 1, stackIndex, currentFunc.index) == -1)
                {
                    throw new SyntaxError(
                              string.Format(Messages.ERROR_MSG_FUNC_PARAM_DUPLICATE_DEFINITION,
                                            paramNameToken.value), token.span.Start.Line, token.span.Start.Column);
                }

                currentParamIndex++;
                break;

            case TokenType.INSTR:

                InstrLookup currentInstrLookup = null;
                if (!instrLookupTable.GetInstrByMnemonic(token.value, out currentInstrLookup))
                {
                    throw new SyntaxError(
                              string.Format(Messages.ERROR_MSG_INSTR_NOT_FOUND,
                                            token.value), token.span.Start.Line, token.span.Start.Column);
                }

                script.instrStream.instrs [instrStreamSize].opCode  = currentInstrLookup.opCode;
                script.instrStream.instrs [instrStreamSize].opCount = currentInstrLookup.opCount;

                for (int i = 0; i < currentInstrLookup.opCount; i++)
                {
                    OpFlagType currentOpFlagType = currentInstrLookup.opList [i];

                    Token instrParamToken = lexer.NextToken();
//						Console.WriteLine ( $"指令参数{i}: {instrParamToken}" );
                    switch (instrParamToken.type)
                    {
                    case TokenType.INT:

                        if ((currentOpFlagType & OpFlagType.INT) == OpFlagType.INT)
                        {
                            script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                type = OpType.INT, intLiteral = int.Parse(instrParamToken.value)
                            });
                        }
                        else
                        {
                            throw new SyntaxError(
                                      string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM,
                                                    token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        }
                        break;

                    case TokenType.FLOAT:

                        if ((currentOpFlagType & OpFlagType.FLOAT) == OpFlagType.FLOAT)
                        {
                            script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                type = OpType.FLOAT, floatLiteral = float.Parse(instrParamToken.value)
                            });
                        }
                        else
                        {
                            throw new SyntaxError(
                                      string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM,
                                                    token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        }
                        break;

                    case TokenType.STRING:

                        if ((currentOpFlagType & OpFlagType.STRING) == OpFlagType.STRING)
                        {
                            int stringTableIdx = script.stringTable.AddString(instrParamToken.value);

                            script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                type = OpType.STRING, stringTableIndex = stringTableIdx
                            });
                        }
                        else
                        {
                            throw new SyntaxError(
                                      string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM,
                                                    token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        }
                        break;

                    case TokenType.REG_RETVAL:

                        if ((currentOpFlagType & OpFlagType.REG) == OpFlagType.REG)
                        {
                            script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                type = OpType.REG, reg = 0
                            });
                        }
                        else
                        {
                            throw new SyntaxError(
                                      string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM,
                                                    token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        }
                        break;

                    case TokenType.IDENT:

                        if ((currentOpFlagType & OpFlagType.FUNC_NAME) == OpFlagType.FUNC_NAME)
                        {
                            FuncNode func = script.funcTable.GetFuncByName(instrParamToken.value);

                            if (func != null)
                            {
                                script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                    type = OpType.FUNC_INDEX, funcIndex = func.index
                                });
                            }
                            else
                            {
                                throw new SyntaxError(
                                          string.Format(Messages.ERROR_MSG_FUNC_NOT_FOUND,
                                                        instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                            }
                        }

                        if ((currentOpFlagType & OpFlagType.LINE_LABEL) == OpFlagType.LINE_LABEL)
                        {
                            LabelNode labelNode = script.labelTable.GetLabelByIdent(instrParamToken.value, currentFunc.index);

                            if (labelNode != null)
                            {
                                script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                    type = OpType.INSTR_INDEX, instrIndex = labelNode.targetIndex
                                });
                            }
                            else
                            {
                                throw new SyntaxError(
                                          string.Format(Messages.ERROR_MSG_LABEL_NOT_FOUND,
                                                        instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                            }
                        }

                        if ((currentOpFlagType & OpFlagType.MEM_REF) == OpFlagType.MEM_REF)
                        {
                            SymbolNode symbolNode = script.symbolTable.GetSymbolByIdent(instrParamToken.value, currentFunc.index);

                            // 如果该变量不是函数作用域内定义的,则查找全局变量
                            if (symbolNode == null)
                            {
                                symbolNode = script.symbolTable.GetSymbolByIdent(instrParamToken.value, -1);
                            }
                            if (symbolNode == null)
                            {
                                throw new SyntaxError(
                                          string.Format(Messages.ERROR_MSG_VAR_NOT_FOUND,
                                                        instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                            }

                            int  baseIndex      = symbolNode.stackIndex;
                            char symbolNextChar = lexer.PeekChar(1);

                            if (symbolNextChar != char.MinValue)
                            {
                                // 非数组成员
                                if (symbolNextChar != XASMLexer.Open_Bracket)
                                {
                                    // 验证非数组定义
                                    if (symbolNode.size > 1)
                                    {
                                        throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_START_ERROR, token.span.Start.Line,
                                                              token.span.Start.Column);
                                    }

                                    script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                        type = OpType.ABS_STACK_INDEX, stackIndex = baseIndex
                                    });
                                }
                                else
                                {
                                    // 验证数组定义
                                    if (symbolNode.size <= 1)
                                    {
                                        throw new SyntaxError(
                                                  string.Format(Messages.ERROR_MSG_VAR_TYPE_IS_NOT_A_ARRAY,
                                                                instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                    }

                                    // 左中括号
                                    lexer.NextToken();

                                    // 数组索引参数
                                    Token arrayIndexParamToken = lexer.NextToken();

                                    // 数组索引是常数
                                    if (arrayIndexParamToken.type == TokenType.INT)
                                    {
                                        int offset = int.Parse(arrayIndexParamToken.value);
                                        if (offset >= symbolNode.size)
                                        {
                                            throw new SyntaxError(
                                                      string.Format(Messages.ERROR_MSG_INDEX_OUT_OF_BOUNDS,
                                                                    arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                        }

                                        script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                            type = OpType.ABS_STACK_INDEX, stackIndex = baseIndex >= 0 ? baseIndex + offset : baseIndex - offset
                                        });
                                    }

                                    // 数组索引是变量
                                    else if (arrayIndexParamToken.type == TokenType.IDENT)
                                    {
                                        SymbolNode offsetSymbolNode = script.symbolTable.GetSymbolByIdent(arrayIndexParamToken.value, currentFunc.index);

                                        // 如果该变量不是函数作用域内定义的,则查找全局变量
                                        if (offsetSymbolNode == null)
                                        {
                                            symbolNode = script.symbolTable.GetSymbolByIdent(arrayIndexParamToken.value, -1);
                                        }
                                        if (offsetSymbolNode == null)
                                        {
                                            throw new SyntaxError(
                                                      string.Format(Messages.ERROR_MSG_VAR_NOT_FOUND,
                                                                    arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                        }

                                        // 不支持数组作为数组的索引
                                        if (offsetSymbolNode.size > 1)
                                        {
                                            throw new SyntaxError(
                                                      string.Format(Messages.ERROR_MSG_VAR_ARRAY_INDEX_TYPE_NOT_SUPPORT,
                                                                    arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                        }

                                        script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                            type = OpType.REL_STACK_INDEX, stackIndex = offsetSymbolNode.stackIndex
                                        });

                                        // 右中括号
                                        if (lexer.NextToken().type != TokenType.CLOSE_BRACKET)
                                        {
                                            throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_END_ERROR, token.span.Start.Line,
                                                                  token.span.Start.Column);
                                        }
                                    }
                                    else
                                    {
                                        throw new SyntaxError(
                                                  string.Format(Messages.ERROR_MSG_VAR_ARRAY_INDEX_TYPE_NOT_SUPPORT,
                                                                arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                    }
                                }
                            }
                            else
                            {
                                throw new SyntaxError(Messages.ERROR_MSG_INVALID_TOKEN, token.span.Start.Line,
                                                      token.span.Start.Column);
                            }
                        }

                        break;

                    default:

                        throw new SyntaxError(
                                  string.Format(Messages.ERROR_MSG_INVALID_PARAM_TYPE,
                                                instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        break;
                    }

                    // 指令参数之间的逗号分隔符
                    if (i < currentInstrLookup.opCount - 1)
                    {
                        if (lexer.NextToken().type != TokenType.COMMA)
                        {
                            throw new SyntaxError(Messages.ERROR_MSG_INSTR_PARAM_MISS_COMMA, token.span.Start.Line, token.span.Start.Column);
                        }
                    }
                }

                // 每条指令以换行符结束
                if (lexer.NextToken().type != TokenType.NEWLINE)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_INSTR_END_MISMATCH, token.span.Start.Line, token.span.Start.Column);
                }

//					Console.WriteLine ( $"添加 {script.instrStream.instrs [ instrStreamSize ]} {instrStreamSize} {lexer.LexerPosition}" );

                instrStreamSize++;
                break;    // End Of TokenType.INSTR
            }             // End Of switch ( token.Type )

            // SkipToNextLine???
        }               // End Of While
    }
    private static int instrIndex;                       // 使用一个静态变量来保存表中下一条指令的索引

    public static void InitInstrTable()
    {
        instrIndex = 0;

        instrTable = new InstrLookup[MAX_INSTR_LOOKUP_COUNT];

        for (int i = 0; i < MAX_INSTR_LOOKUP_COUNT; ++i)
        {
            instrTable [i] = new InstrLookup();
        }

        int localInstrIdx = instrIndex;

        /*
         * Mov	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Mov.ToString(), OpCode.Mov, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);


        // ---- Arithmetic

        /*
         * Add	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Add.ToString(), OpCode.Add, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Sub	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Sub.ToString(), OpCode.Sub, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Mul	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Mul.ToString(), OpCode.Mul, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Div	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Div.ToString(), OpCode.Div, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Mod	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Mod.ToString(), OpCode.Mod, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Exp	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Exp.ToString(), OpCode.Exp, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Neg	Destination
         */
        localInstrIdx = AddInstrLookup(OpCode.Neg.ToString(), OpCode.Neg, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Inc	Destination
         */
        localInstrIdx = AddInstrLookup(OpCode.Inc.ToString(), OpCode.Inc, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Dec	Destination
         */
        localInstrIdx = AddInstrLookup(OpCode.Dec.ToString(), OpCode.Dec, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);

        // ---- Bitwise

        /*
         * And	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.And.ToString(), OpCode.And, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Or	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Or.ToString(), OpCode.Or, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * XOr	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.XOr.ToString(), OpCode.XOr, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Not	Destination
         */
        localInstrIdx = AddInstrLookup(OpCode.Not.ToString(), OpCode.Not, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * ShL	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.ShL.ToString(), OpCode.ShL, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * ShR	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.ShR.ToString(), OpCode.ShR, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        // ---- String

        /*
         * Concat	Destination, Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Concat.ToString(), OpCode.Concat, 2);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * GetChar	Destination, Source, Index
         */
        localInstrIdx = AddInstrLookup(OpCode.GetChar.ToString(), OpCode.GetChar, 3);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 2, OpFlagType.INT |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * SetChar	Destination, Source, Index
         */
        localInstrIdx = AddInstrLookup(OpCode.SetChar.ToString(), OpCode.SetChar, 3);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 2, OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        // ---- Conditional Branching

        /*
         * Jmp	Label
         */
        localInstrIdx = AddInstrLookup(OpCode.Jmp.ToString(), OpCode.Jmp, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.LINE_LABEL);

        /*
         * JE	Op0, Op1, Label
         */
        localInstrIdx = AddInstrLookup(OpCode.JE.ToString(), OpCode.JE, 3);
        SetOpType(localInstrIdx, 0, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 2, OpFlagType.LINE_LABEL);

        /*
         * JNE	Op0, Op1, Label
         */
        localInstrIdx = AddInstrLookup(OpCode.JNE.ToString(), OpCode.JNE, 3);
        SetOpType(localInstrIdx, 0, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 2, OpFlagType.LINE_LABEL);

        /*
         * JG	Op0, Op1, Label
         */
        localInstrIdx = AddInstrLookup(OpCode.JG.ToString(), OpCode.JG, 3);
        SetOpType(localInstrIdx, 0, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 2, OpFlagType.LINE_LABEL);

        /*
         * JL	Op0, Op1, Label
         */
        localInstrIdx = AddInstrLookup(OpCode.JL.ToString(), OpCode.JL, 3);
        SetOpType(localInstrIdx, 0, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 2, OpFlagType.LINE_LABEL);

        /*
         * JGE	Op0, Op1, Label
         */
        localInstrIdx = AddInstrLookup(OpCode.JGE.ToString(), OpCode.JGE, 3);
        SetOpType(localInstrIdx, 0, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 2, OpFlagType.LINE_LABEL);

        /*
         * JLE	Op0, Op1, Label
         */
        localInstrIdx = AddInstrLookup(OpCode.JLE.ToString(), OpCode.JLE, 3);
        SetOpType(localInstrIdx, 0, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 1, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
        SetOpType(localInstrIdx, 2, OpFlagType.LINE_LABEL);

        // ---- The Stack Interface

        /*
         * Push	Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Push.ToString(), OpCode.Push, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Pop	Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Pop.ToString(), OpCode.Pop, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.MEM_REF |
                  OpFlagType.REG);

        // ---- The Function Interface

        /*
         * Call	Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Call.ToString(), OpCode.Call, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.FUNC_NAME);

        /*
         * Ret	Source
         */
        localInstrIdx = AddInstrLookup(OpCode.Ret.ToString(), OpCode.Ret, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.FUNC_NAME);

        /*
         * CallHost	Source
         */
        localInstrIdx = AddInstrLookup(OpCode.CallHost.ToString(), OpCode.CallHost, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.HOST_API_CALL);

        // ---- Miscellaneous

        /*
         * Pause	Duration
         */
        localInstrIdx = AddInstrLookup(OpCode.Pause.ToString(), OpCode.Pause, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);

        /*
         * Exit	Code
         */
        localInstrIdx = AddInstrLookup(OpCode.Exit.ToString(), OpCode.Exit, 1);
        SetOpType(localInstrIdx, 0, OpFlagType.INT |
                  OpFlagType.FLOAT |
                  OpFlagType.STRING |
                  OpFlagType.MEM_REF |
                  OpFlagType.REG);
    }