/// <summary> /// Constructs a new instance of the preprocessor class. /// </summary> /// <param name="opt">The <see cref="ProcessorOptions"/>.</param> public Preprocessor(ProcessorOptions opt) { _includedFiles = new HashSet <string>(); _index = 0; _options = opt; _macros = new Dictionary <string, Macro>(_options.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase); _preprocessors = new ReservedWords(_options.CaseSensitive ? StringViewComparer.Ordinal : StringViewComparer.IgnoreCase); _preprocessors.DefineType("Macros", ".macro", ".endmacro"); _preprocessors.DefineType("Includes", ".binclude", ".include"); _preprocessors.DefineType("End", ".end"); }
/// <summary> /// Constructs a new instance of an <see cref="AssemblyController"/>, which controls /// the assembly process. /// </summary> /// <param name="args">The commandline arguments.</param> /// <param name="cpuSetHandler">The <see cref="CpuAssembler"/> selection handler.</param> /// <param name="formatSelector">The format selector.</param> /// <exception cref="ArgumentNullException"></exception> public AssemblyController(IEnumerable <string> args, Func <string, AssemblyServices, CpuAssembler> cpuSetHandler, Func <string, string, IBinaryFormatProvider> formatSelector) { if (args == null || cpuSetHandler == null || formatSelector == null) { throw new ArgumentNullException(); } _services = new AssemblyServices(Options.FromArgs(args)); _services.PassChanged += (s, a) => _services.Output.Reset(); _services.PassChanged += (s, a) => _services.SymbolManager.Reset(); _services.FormatSelector = formatSelector; _processorOptions = new ProcessorOptions { CaseSensitive = _services.Options.CaseSensitive, Log = _services.Log, IncludePath = _services.Options.IncludePath, IgnoreCommentColons = _services.Options.IgnoreColons, WarnOnLabelLeft = _services.Options.WarnLeft, InstructionLookup = symbol => _services.InstructionLookupRules.Any(ilr => ilr(symbol)) }; CpuAssembler cpuAssembler = null; var cpu = _services.Options.CPU; if (!string.IsNullOrEmpty(cpu)) { cpuAssembler = cpuSetHandler(cpu, _services); } if (_services.Options.InputFiles.Count > 0) { var src = new Preprocessor(_processorOptions).ProcessToFirstDirective(_services.Options.InputFiles[0]); if (src != null && src.Instruction != null && src.Instruction.Name.Equals(".cpu", _services.StringViewComparer)) { if (src.Operands.Count != 1 || !src.Operands[0].IsDoubleQuote()) { _services.Log.LogEntry(src.Filename, src.LineNumber, src.Instruction.Position, "Invalid expression for directive \".cpu\"."); } else { cpu = src.Operands[0].Name.ToString().TrimOnce('"'); } } } _services.CPU = cpu; if (!string.IsNullOrEmpty(cpu) && cpuAssembler != null && !cpuAssembler.IsCpuValid(cpu)) { _services.Log.LogEntrySimple($"Invalid CPU \"{cpu}\" specified."); } else { if (cpuAssembler == null) { cpuAssembler = cpuSetHandler(cpu, _services); } _assemblers = new List <AssemblerBase> { new AssignmentAssembler(_services), new BlockAssembler(_services), new EncodingAssembler(_services), new PseudoAssembler(_services), new MiscAssembler(_services), cpuAssembler }; _processorOptions.IsMacroNameValid = symbol => !_assemblers.Any(asm => asm.Assembles(symbol)); _processorOptions.LineTerminates = _services.LineTerminates; } }