예제 #1
0
        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))));
        }