コード例 #1
0
        /// <summary>
        /// Parses a string containing assembler directive.
        /// </summary>
        /// <param name="s">An array beginning with a an assembler directive, possibly including arguments.</param>
        /// <param name="result">If the parse is successful, the Directive represented by the given string. Otherwise, null.</param>
        /// <returns>A Boolean value indicating whether the parse was successful.</returns>
        public static bool TryParse(string[] tokens, out AssemblerDirective result)
        {
            if (tokens.Length < 1)
            {
                result = null;
                return(false);
            }
            Mnemonic dir;

            if (!Enum.TryParse(tokens[0], true, out dir))
            {
                result = null;
                return(false);
            }

            switch (dir)
            {
            // parse arguments properly for each directive.
            case Mnemonic.BYTE:
            case Mnemonic.RESW:
            case Mnemonic.RESB:
            case Mnemonic.EQU:
            case Mnemonic.START:
            case Mnemonic.WORD:
            case Mnemonic.BASE:
                if (tokens.Length < 2)     // These directives require an argument.
                {
                    result = null;
                    return(false);
                }
                result         = new AssemblerDirective(dir);
                result.Value   = tokens[1];
                result.Comment = string.Join(" ", tokens, 2, tokens.Length - 2);
                break;

            case Mnemonic.END:
                result = new AssemblerDirective(dir);
                if (tokens.Length > 1)     // Argument of END is optional.
                {
                    result.Value   = tokens[1];
                    result.Comment = string.Join(" ", tokens, 2, tokens.Length - 2);
                }
                break;

            case Mnemonic.LTORG:
                // LTORG takes no arguments.
                result         = new LTORG();
                result.Comment = string.Join(" ", tokens, 1, tokens.Length - 1);
                break;

            default:
                throw new NotImplementedException($"Assembler directive \"{tokens[0]}\" is not supported!");
            }

            return(true);
        }
コード例 #2
0
ファイル: Line.cs プロジェクト: geoff-m/SICXE
        private static bool TryParseWithoutLabel(string[] tokens, out Line result)
        {
            // Attempt to parse as instruction.
            Instruction inst;

            if (Instruction.TryParse(tokens, out inst))
            {
                result = inst;
                return(true);
            }

            // Attempt to parse as directive.
            AssemblerDirective dir;

            if (AssemblerDirective.TryParse(tokens, out dir))
            {
                result = dir;
                return(true);
            }

            // Attempt to parse as @import.
            ImportDirective id;

            if (ImportDirective.TryParse(tokens, out id))
            {
                result = id;
                return(true);
            }

            // Attempt to parse as @export.
            ExportDirective ed;

            if (ExportDirective.TryParse(tokens, out ed))
            {
                result = ed;
                return(true);
            }

            result = null;
            return(false);
        }
コード例 #3
0
        public Program MakeRandomProgram(int lines)
        {
            t          = new Timer(3000);
            t.Elapsed += TimerElapsed;
            symbols.Clear();
            GenerateSymbols(lines);
            var ret = new Program();

            t.Start();

            ret.Add(new AssemblerDirective(AssemblerDirective.Mnemonic.START)
            {
                //Value = r.Next(0, 1 << 12).ToString()
                Value = "0"
            });

            for (int lineIdx = 0; lineIdx < lines; ++lineIdx)
            {
                Line line;
                // Make a WORD or RESW.
                if (r.NextDouble() < CHANCE_MEMORY)
                {
                    AssemblerDirective dir;
                    if (r.NextDouble() < CHANCE_RESW)
                    {
                        dir = new AssemblerDirective(AssemblerDirective.Mnemonic.WORD);
                    }
                    else
                    {
                        dir = new AssemblerDirective(AssemblerDirective.Mnemonic.RESW);
                    }
                    if (r.NextDouble() < CHANCE_USE_SYMBOL)
                    {
                        // The symbol we put here must not have been defined elsewhere.
                        var sym = GetUndefinedSymbol();
                        dir.Label = sym.Name;
                        sym.Define();
                    }
                    dir.Value = GetSmallishNumber().ToString();
                    line      = dir;
                }
                else
                {
                    // Make an instruction.
                    //Instruction.Mnemonic.
                    Instruction instr = new Instruction(MNEMONICS[r.Next(MNEMONICS.Length)]);

                    for (int operandIdx = 0; operandIdx < instr.Operands.Count; ++operandIdx)
                    {
                        var operand = instr.Operands[operandIdx];
                        switch (instr.Format)
                        {
                        case InstructionFormat.Format2:
                            // Choose register.
                            operand.Value = (int)REGISTERS[r.Next(REGISTERS.Length)];
                            break;

                        case InstructionFormat.Format3:
                        case InstructionFormat.Format4:
                        case InstructionFormat.Format3Or4:
                            // Choose whether a symbol will be referenced.
                            if (r.NextDouble() < CHANCE_USE_SYMBOL)
                            {
                                operand.SymbolName = GetSymbol();
                            }
                            else
                            {
                                // Use immediate instead of symbol.
                                operand.Value = r.Next(-0x7ff, 0x800);
                            }
                            // Choose direct/indirect.
                            if (r.NextDouble() < CHANCE_INDIRECT)
                            {
                                operand.AddressingMode = AddressingMode.Indirect;
                            }
                            // Choose immediate.
                            if (r.NextDouble() < CHANCE_IMMEDIATE)
                            {
                                operand.AddressingMode |= AddressingMode.Immediate;
                            }
                            // Choose extended.
                            if (r.NextDouble() < CHANCE_EXTENDED)
                            {
                                //operand.AddressingMode |= AddressingMode.Extended;
                                instr.Format = InstructionFormat.Format4;
                            }
                            break;
                        }
                    } // For each operand.

                    line = instr;
                } // Choose between making this line a WORD or an instruction.

                ret.Add(line);
                Interlocked.Increment(ref linesProcessed);
            } // For each line in output program.

            // Finally, append any symbols that are still undefined by this point.
            foreach (var s in symbols)
            {
                if (!s.IsDefined)
                {
                    AssemblerDirective dir;
                    if (r.NextDouble() < CHANCE_RESW)
                    {
                        dir = new AssemblerDirective(AssemblerDirective.Mnemonic.WORD);
                    }
                    else
                    {
                        dir = new AssemblerDirective(AssemblerDirective.Mnemonic.RESW);
                    }
                    dir.Label = s.Name;
                    s.Define();
                    dir.Value = GetSmallishNumber().ToString();
                    ret.Add(dir);
                }
            }

            t.Stop();

            Console.Error.WriteLine();
            return(ret);
        }