コード例 #1
0
        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();
                }
            }
        }
コード例 #2
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();
                }
            }
        }