/// <summary> /// Converts a file to a SourceLine list. /// </summary> /// <param name="file">The filename.</param> /// <returns>A <see cref="T:System.Collections.Generic.IEnumerable<DotNetAsm.SourceLine>"/> d.</returns> public IEnumerable <SourceLine> ConvertToSource(string file) { if (FileRegistry.Add(file) == false) { throw new Exception(string.Format(ErrorStrings.FilePreviouslyIncluded, file)); } if (File.Exists(file)) { Console.WriteLine("Processing input file " + file + "..."); int currentline = 1; var sourcelines = new List <SourceLine>(); using (StreamReader reader = new StreamReader(File.Open(file, FileMode.Open))) { while (reader.EndOfStream == false) { var unprocessedline = reader.ReadLine(); try { var line = new SourceLine(file, currentline, unprocessedline); line.Parse( delegate(string token) { return(Controller.IsInstruction(token) || Reserved.IsReserved(token) || (token.StartsWith(".") && Macro.IsValidMacroName(token.Substring(1))) || token == "="); }); sourcelines.Add(line); } catch (Exception ex) { Controller.Log.LogEntry(file, currentline, ex.Message); } currentline++; } sourcelines = Preprocess(sourcelines).ToList(); } return(sourcelines); } throw new FileNotFoundException(string.Format("Unable to open source file \"{0}\"", file)); }
public void Process(SourceLine line) { var instruction = line.Instruction.ToLower(); if (!Processes(line.Instruction)) { if (instruction.Equals(_macros.Last().Key)) { Controller.Log.LogEntry(line, ErrorStrings.RecursiveMacro, line.Instruction); } _macroDefinitions.Peek().Add(line); return; } if (instruction.Equals(".macro") || instruction.Equals(".segment")) { _macroDefinitions.Push(new List <SourceLine>()); string name; _definitions.Push(line); if (instruction.Equals(".segment")) { if (!string.IsNullOrEmpty(line.Label)) { Controller.Log.LogEntry(line, ErrorStrings.None); return; } name = line.Operand; } else { name = line.Label; } if (!Macro.IsValidMacroName(name) || _instructionFcn(name)) { Controller.Log.LogEntry(line, ErrorStrings.LabelNotValid, line.Label); return; } if (_macros.ContainsKey("." + name)) { Controller.Log.LogEntry(line, ErrorStrings.MacroRedefinition, line.Label); return; } _macros.Add("." + name, null); } else if (instruction.Equals(".endmacro") || instruction.Equals(".endsegment")) { var def = instruction.Replace("end", string.Empty); var name = "." + _definitions.Peek().Label; if (!_definitions.Peek().Instruction.Equals(def, Controller.Options.StringComparison)) { Controller.Log.LogEntry(line, ErrorStrings.ClosureDoesNotCloseMacro, line.Instruction); return; } if (def.Equals(".segment")) { name = _definitions.Peek().Operand; if (!name.Equals(line.Operand, Controller.Options.StringComparison)) { Controller.Log.LogEntry(line, ErrorStrings.None); return; } name = "." + name; } _macros[name] = Macro.Create(_definitions.Pop(), line, _macroDefinitions.Pop(), Controller.Options.StringComparison, ConstStrings.OPEN_SCOPE, ConstStrings.CLOSE_SCOPE); } else { var macro = _macros[line.Instruction]; if (macro == null) { Controller.Log.LogEntry(line, ErrorStrings.MissingClosureMacro, line.Instruction); return; } if (IsProcessing()) { _macroDefinitions.Peek().Remove(line); _macroDefinitions.Peek().AddRange(macro.Expand(line).ToList()); } else { _expandedSource = macro.Expand(line).ToList(); } } }
public void Process(SourceLine line) { var instruction = line.Instruction.ToLower(); if (!Processes(line.Instruction)) { if (_macroDefinitions.Count > 0) { // We are in a macro definition if (instruction.Equals(_macros.Last().Key)) { Assembler.Log.LogEntry(line, ErrorStrings.RecursiveMacro, line.Instruction); } _macroDefinitions.Peek().Add(line); } else { // We are consuming source after an undefined .dsegment _expandedSource.Add(line); } return; } if (instruction.Equals(".macro") || instruction.Equals(".segment")) { _macroDefinitions.Push(new List <SourceLine>()); string name; _definitions.Push(line); if (instruction.Equals(".segment")) { if (!string.IsNullOrEmpty(line.Label)) { Assembler.Log.LogEntry(line, ErrorStrings.None); return; } name = line.Operand; } else { name = "." + line.Label; } if (!Macro.IsValidMacroName(name) || _instructionFcn(name)) { Assembler.Log.LogEntry(line, ErrorStrings.LabelNotValid, line.Label); return; } if (_macros.ContainsKey(name)) { Assembler.Log.LogEntry(line, ErrorStrings.MacroRedefinition, line.Label); return; } _macros.Add(name, null); } else if (instruction.Equals(".endmacro") || instruction.Equals(".endsegment")) { var def = instruction.Replace("end", string.Empty); var name = "." + _definitions.Peek().Label; if (!_definitions.Peek().Instruction.Equals(def, Assembler.Options.StringComparison)) { Assembler.Log.LogEntry(line, ErrorStrings.ClosureDoesNotCloseMacro, line.Instruction); return; } if (def.Equals(".segment")) { name = _definitions.Peek().Operand; if (!name.Equals(line.Operand, Assembler.Options.StringComparison)) { Assembler.Log.LogEntry(line, ErrorStrings.None); return; } //name = "." + name; } _macros[name] = Macro.Create(_definitions.Pop(), line, _macroDefinitions.Pop(), Assembler.Options.StringComparison, ConstStrings.OPEN_SCOPE, ConstStrings.CLOSE_SCOPE); if (def.Equals(".segment")) { while (_declarations.Any(l => l.Operand.Equals(name, Assembler.Options.StringComparison))) { var dsegment = _declarations.Pop(); var segname = dsegment.Operand; var ix = _expandedSource.IndexOf(dsegment); _expandedSource.RemoveAt(ix); _expandedSource.InsertRange(ix, _macros[segname].Expand(dsegment)); } } } else if (instruction.Equals(".dsegment")) { if (string.IsNullOrEmpty(line.Operand)) { Assembler.Log.LogEntry(line, ErrorStrings.TooFewArguments, line.Instruction); return; } if (_macros.ContainsKey(line.Operand)) { var seg = _macros[line.Operand]; _expandedSource = seg.Expand(line).ToList(); } else { _expandedSource.Add(line); _declarations.Push(line); } } else { var macro = _macros[line.Instruction]; if (macro == null) { Assembler.Log.LogEntry(line, ErrorStrings.MissingClosureMacro, line.Instruction); return; } if (IsProcessing()) { _macroDefinitions.Peek().Remove(line); _macroDefinitions.Peek().AddRange(macro.Expand(line).ToList()); } else { _expandedSource = macro.Expand(line).ToList(); } } }