예제 #1
0
 /// <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");
 }
예제 #2
0
        /// <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;
            }
        }