示例#1
0
        /// <summary>
        /// Converts a file to a SourceLine list.
        /// </summary>
        /// <param name="file">The filename.</param>
        /// <returns>A <see cref="T:System.Collections.Generic.IEnumerable&lt;DotNetAsm.SourceLine&gt;"/> 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();
                }
            }
        }
示例#3
0
        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();
                }
            }
        }