public override void EnterInstruction([NotNull] CasmParser.InstructionContext context) { var instructionName = context?.NAME()?.GetText(); if (instructionName == null) { throw new InvalidOperationException("Could not find the opcode for the instruction."); } var operandTypes = new List <OperandType>(); var operands = new List <Operand>(); foreach (var expression in context.expressionList().expression()) { if (expression.register() != null) { operandTypes.Add(OperandType.Register); operands.Add(context.ExtractRegister(operands.Count)); } else if (expression.registerReference() != null) { operandTypes.Add(OperandType.RegisterReference); operands.Add(context.ExtractRegisterReference(operands.Count)); } else if (expression.NUMBER() != null) { operandTypes.Add(OperandType.Immediate); operands.Add(context.ExtractImmediate(operands.Count)); } else if (expression.NAME() != null) { operandTypes.Add(OperandType.Label); operands.Add(new ImmediateOperand(expression.NAME().GetText())); } } if (InstructionMap.InstructionDefinitions.TryGetValue(new InstructionKey(instructionName, operandTypes.ToArray()), out var instructionDefinitions)) { foreach (var instructionDefinition in instructionDefinitions) { _tree.AddNodes(new Instruction(_currentBytePosition, instructionDefinition, operands.ToArray())); _currentBytePosition += 4; } return; } }
public static ImmediateOperand ExtractImmediate(this CasmParser.InstructionContext context, int operandPosition) { var immediateText = context.expressionList().expression(operandPosition).NUMBER().GetText().Replace("_", ""); uint value; if (immediateText.Contains("0x") || immediateText.Contains("0X")) { value = Convert.ToUInt32(immediateText, 16); } else if (immediateText.Contains("0b") || immediateText.Contains("0B")) { value = Convert.ToUInt32(immediateText, 2); } else { value = uint.Parse(immediateText); } return(new ImmediateOperand(value)); }
public static RegisterOperand ExtractRegisterReference(this CasmParser.InstructionContext context, int operandPosition) { var registerText = context.expressionList().expression(operandPosition).registerReference().REGISTERREFERENCE().GetText(); return(new RegisterOperand(uint.Parse(RegisterReferenceRegex.Match(registerText).Groups[1].Value))); }
public static RegisterOperand ExtractRegister(this CasmParser.InstructionContext context, int operandPosition) { var registerText = context.expressionList().expression(operandPosition).register().GetText(); return(new RegisterOperand(uint.Parse(registerText.Substring(1)))); }