/// <summary> /// r,adr[,x] あるいは r1,r2 のオペランドを解釈します。 /// </summary> /// <param name="lexer">オペランドの字句を解析する <see cref="OperandLexer"/> のオブジェクトです。</param> /// <param name="opcodeRAdrX">オペランドが r,adr[,x] の場合のオペコードの値です。</param> /// <param name="opcodeR1R2">オペランドが r1,r2 の場合のオペコードの値です。</param> /// <returns> /// 解釈した結果として生成した <see cref="MachineInstructionOperand"/> オブジェクトを返します。 /// </returns> internal static MachineInstructionOperand Parse( OperandLexer lexer, UInt16 opcodeRAdrX, UInt16 opcodeR1R2) { // r,adr[,x] と r1,r2 の両方とも最初は "r," なので、そこまで解釈する。 RegisterOperand rOrR1 = RegisterOperand.Parse(lexer); lexer.SkipComma(); // lexer の状態を保存する。 OperandLexerState savedLexerState = lexer.GetState(); // adr[,x] を解釈してみる。 RAdrXOperand rAdrX; if (RAdrXOperand.TryParseAdrX(lexer, opcodeRAdrX, rOrR1, out rAdrX)) { return(rAdrX); } // adr[,x] でなければ、lexer の状態を元に戻して r2 を解釈してみる。 lexer.SetState(savedLexerState); R1R2Operand r1R2; if (R1R2Operand.TryParseR2(lexer, opcodeR1R2, rOrR1, out r1R2)) { return(r1R2); } // r,adr[,x] でも r1,r2 でもない。 throw new Casl2SimulatorException(Resources.MSG_OperandNeitherRAdrXNorR1R2); }
/// <summary> /// r1,r2 のオペランドを解釈します。 /// </summary> /// <param name="lexer">オペランドの字句を解析する <see cref="OperandLexer"/> のオブジェクトです。</param> /// <param name="opcode">このオペラントの命令の第 1 語のオペコードの値です。</param> /// <returns> /// 解釈した結果として生成した <see cref="R1R2Operand"/> オブジェクトを返します。 /// </returns> internal static R1R2Operand Parse(OperandLexer lexer, UInt16 opcode) { RegisterOperand r1 = RegisterOperand.Parse(lexer); lexer.SkipComma(); RegisterOperand r2 = RegisterOperand.Parse(lexer); return(new R1R2Operand(opcode, r1, r2)); }
/// <summary> /// r,adr[,x] のオペランドを解釈します。 /// </summary> /// <param name="lexer">オペランドの字句を解析する <see cref="OperandLexer"/> のオブジェクトです。</param> /// <param name="opcode">このオペラントの命令の第 1 語のオペコードの値です。</param> /// <returns> /// 解釈した結果として生成した <see cref="RAdrXOperand"/> オブジェクトを返します。 /// </returns> internal static RAdrXOperand Parse(OperandLexer lexer, UInt16 opcode) { RegisterOperand r = RegisterOperand.Parse(lexer); lexer.SkipComma(); AdrXOperand adrX = AdrXOperand.Parse(lexer); return(new RAdrXOperand(opcode, r, adrX)); }
// 指標レジスタとして指定できる GR は GR1 ~ 7。 private static RegisterOperand ParseIndexRegister(OperandLexer lexer) { RegisterOperand x = RegisterOperand.Parse(lexer); if (!CanIndex(x)) { String message = String.Format(Resources.MSG_CanNotBeIndexRegister, x.Name, MinIndexReg, MaxIndexReg); throw new Casl2SimulatorException(message); } return(x); }
/// <summary> /// オペランドが r の機械語命令を作成します。 /// </summary> /// <param name="mnemonic">命令のニーモニックを表わす文字列です。</param> /// <param name="opcode">この命令のオペコードの値です。</param> /// <returns></returns> internal static MachineInstruction MakeR(String mnemonic, UInt16 opcode) { return(new MachineInstruction( mnemonic, Resources.SYN_R, (lexer) => RegisterOperand.Parse(lexer, opcode))); }