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; }
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()); }