Ejemplo n.º 1
0
        private byte[] GetInstructionBytes(IList<AssemblerMessage> messages, IDictionary<string, byte> labels, ParsedInstruction parsedInstruction)
        {
            if (parsedInstruction.OpCodeInfo.InstructionSize > 1)
            {
                var generator = parsedInstruction.OpCodeInfo.InstructionGenerator;

                if (generator == null)
                    throw new Exception("The generator was null!!!!");

                var context = new FinalAssembleContext(labels, messages, parsedInstruction);

                var argumentBytes = generator.GenerateInstruction(context);

                if (argumentBytes == null)
                    return null;

                if (argumentBytes.Length != parsedInstruction.OpCodeInfo.InstructionSize - 1)
                {
                    messages.Add(new AssemblerMessage(ErrorLevel.Error, string.Format("The number of bytes produced does not match the instruction size.")));
                    return null;
                }

                return new byte[] { parsedInstruction.OpCodeInfo.OpCode }.Concat(argumentBytes).ToArray();
            }
            else
            {
                return new byte[] {parsedInstruction.OpCodeInfo.OpCode};
            }
        }
Ejemplo n.º 2
0
        public Pass1Result(IDictionary<string, byte> labels, ParsedInstruction[] parsedInstructions)
        {
            if (labels == null)
                throw new ArgumentNullException("labels");

            if (parsedInstructions == null)
                throw new ArgumentNullException("parsedInstructions");

            this.Labels = labels;
            this.ParsedInstructions = parsedInstructions;
        }
Ejemplo n.º 3
0
        public FinalAssembleContext(IDictionary<string, byte> labels, 
            IList<AssemblerMessage> messages,
            ParsedInstruction parsedInstruction)
        {
            if (labels == null)
                throw new ArgumentNullException("labels");

            if (messages == null)
                throw new ArgumentNullException("messages");

            if (parsedInstruction == null)
                throw new ArgumentNullException("parsedInstruction");

            _labels = labels;
            _messages = messages;
            _parsedInstruction = parsedInstruction;
        }
Ejemplo n.º 4
0
        private Pass1Result Pass1(IList<AssemblerMessage> messages, SourceLine[] sourceLines)
        {
            if (messages == null)
                throw new NullReferenceException("messages");

            if (sourceLines == null)
                throw new NullReferenceException("sourceLines");

            byte currentLocation = 0;

            var parsedInstructions = new List<ParsedInstruction>(sourceLines.Length);

            Dictionary<string, byte> labels = new Dictionary<string, byte>();

            foreach (var sourceLine in sourceLines)
            {
                //Ditch the whitespace
                var cleanedLine = sourceLine.Line.RemoveWhitespace();

                if (cleanedLine.StartsWith(":"))
                {
                    //This is a label
                    string labelName = LabelNameGetter.GetLabelName(cleanedLine);

                    if (string.IsNullOrWhiteSpace(labelName))
                    {
                        messages.Add(new AssemblerMessage(ErrorLevel.Error, string.Format("Invalid label  on line {0}", sourceLine.LineNumber), sourceLine.LineNumber));
                    }
                    else
                    {
                        labels.Add(labelName, currentLocation);
                    }
                }
                else
                {
                    //This out to be a bloody instruction
                    var parts = cleanedLine.Split(',');

                    //This is the number of arguments specified
                    var numberOfArgumentsSpecified = parts.Length - 1;

                    //Get the instruction name
                    string instructionName = parts[0];

                    //Attempt to get the op code info
                    var opCodeInfo = OpCodeFactory.GetOpCodeInfo(parts[0]);

                    //Check to see
                    if (opCodeInfo == null)
                    {
                        messages.Add(new AssemblerMessage(ErrorLevel.Error, string.Format("Invalid instruction '{0}' on line {1}", instructionName, sourceLine.LineNumber), sourceLine.LineNumber));
                    }
                    else
                    {
                        if (numberOfArgumentsSpecified != opCodeInfo.NumberOfArguments)
                        {
                            messages.Add(new AssemblerMessage(ErrorLevel.Error, string.Format("The instruction '{0}' takes {1} parameters but {2} were specified.", opCodeInfo.AssemblerKeyword, opCodeInfo.NumberOfArguments, numberOfArgumentsSpecified)));
                        }
                        else
                        {
                            //Get the arguments
                            var arguments = parts.Skip(1).ToArray();

                            //Create the parsed instruction
                            var parsedInstruction = new ParsedInstruction(sourceLine, arguments, opCodeInfo);

                            parsedInstructions.Add(parsedInstruction);

                            //Move the current location so that labels can be correctly set.
                            currentLocation += opCodeInfo.InstructionSize;
                        }
                    }
                }
            }

            return new Pass1Result(labels, parsedInstructions.ToArray());
        }