Example #1
0
        public ParsedInstruction(SourceLine sourceLine, string[] arguments, OpCodeInfo opCodeInfo)
        {
            if(sourceLine == null)
                throw new ArgumentNullException("sourceLine");

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

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

            this.SourceLine = sourceLine;
            this.Arguments = arguments;
            this.OpCodeInfo = opCodeInfo;
        }
Example #2
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());
        }