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); }
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); }