Example #1
0
        public MIXWord WordValue()
        {
            MIXWord result = 0;
            MIXWord e      = Expression();
            int     f      = (int)Field(); if (f == -1)
            {
                f = 5;
            }
            byte w = (byte)(f % 8 - f / 8);

            result[(byte)(f / 8), (byte)(f % 8)] = e[(byte)(5 - w), 5];

            while (tokStream.ToArray().Length > 0 && tokStream.First().Type == TokenType.COMMA)
            {
                tokStream = tokStream.Skip(1);
                e         = Expression();
                f         = (int)Field(); if (f == -1)
                {
                    f = 5;
                }
                w = (byte)(f % 8 - f / 8);

                result[(byte)(f / 8), (byte)(f % 8)] = e[(byte)(5 - w), 5];
            }

            return(result);
        }
Example #2
0
        private void MakeFutureRefs()
        {
            foreach (var fr in futureRefs)
            {
                if (!symbolTable.ContainsKey(fr.Symbol))
                {
                    if (fr.Symbol.StartsWith("=", StringComparison.InvariantCultureIgnoreCase))
                    {
                        int litVal = int.Parse(fr.Symbol.Substring(1, fr.Symbol.Length - 2));
                        assembly.Add(new MemoryCell {
                            Location = insertionPoint, SourceLocation = 0, Contents = new MIXWord(litVal)
                        });
                    }
                    else
                    {
                        assembly.Add(new MemoryCell {
                            Location = insertionPoint, SourceLocation = 0, Contents = new MIXWord()
                        });
                    }

                    symbolTable.Add(fr.Symbol, new MIXWord(insertionPoint));
                    insertionPoint++;
                }

                MIXWord word = new MIXWord();
                word[0, 2] = symbolTable[fr.Symbol];
                word[3]    = fr.Index;
                word[4]    = fr.Field;
                word[5]    = fr.OpCode;

                assembly.Add(new MemoryCell {
                    Location = fr.Location, SourceLocation = fr.SourceLocation, Contents = word
                });
            }
        }
Example #3
0
        public string FormatInstruction(int location, MIXWord instruction, int lineNo, string line)
        {
            string strLine = string.Format("{0:0000}&\\mixinst${1}$.{2}.{3}.{4}.{5}.&{6}&|{7}|\\cr",
                                           location, instruction[0] == 1 ? "-" : "+", instruction[1, 2], instruction[3], instruction[4], instruction[5],
                                           lineNo, line);

            return(strLine);
        }
Example #4
0
        public string FormatInstruction(int location, MIXWord instruction, int lineNo, string line)
        {
            string strLine   = lineNo.ToString().PadLeft(4) + " " + line;
            string firstPart = string.Format("{0:0000}: {1} ", location, instruction.ToInstructionString());

            strLine = firstPart += strLine;

            return(strLine);
        }
Example #5
0
        public MIXWord Index()
        {
            MIXWord result = new MIXWord();

            if (tokStream.ToArray().Length > 0 && tokStream.First().Type == TokenType.COMMA)
            {
                tokStream = tokStream.Skip(1);
                result    = Expression();
            }

            return(result);
        }
Example #6
0
        public Parser(TextReader reader)
        {
            locCounter  = insertionPoint = 0;
            symbolTable = new Dictionary <string, MIXWord>();

            assembly    = new List <MemoryCell>();
            errors      = new List <ErrorInfo>();
            warnings    = new List <ErrorInfo>();
            futureRefs  = new List <FutureReference>();
            localSymbs  = new Dictionary <byte, int>();
            LineNumber  = 1;
            StartLoc    = null;
            this.reader = reader;
        }
Example #7
0
        static void Main(string[] args)
        {
            Dictionary <string, string> aliases = new Dictionary <string, string>();

            aliases.Add("-d", "--deck");
            aliases.Add("-b", "--binary");
            aliases.Add("-?", "--help");
            aliases.Add("-h", "--help");

            Dictionary <string, string> cmdLine = CommandLineHelper.SplitCommandLine(Environment.CommandLine, aliases, true);

            if (cmdLine.Count == 0)
            {
                Console.WriteLine("This is MIX v0.1, (c) 2009 George Tryfonas\nAn mplementation of the machine described by Don Knuth.\n\nType '?' or 'help' at the prompt for instructions.\n");
                MIXController c = new MIXController();
                c.Interface();
            }
            else
            {
                Stream stream;

                MIXMachine machine = new MIXMachine();
                string     inFile  = GetInputFile(cmdLine);
                if (string.IsNullOrEmpty(inFile))
                {
                    stream = Console.OpenStandardInput();
                }
                else
                {
                    stream = new FileStream(inFile, FileMode.Open);
                }

                if (cmdLine.ContainsKey("--deck"))
                {
                    machine.RedirectDevice(MIXMachine.CARD_READER, stream);
                    machine.LoadDeck();
                }
                else if (cmdLine.ContainsKey("--binary"))
                {
                    IFormatter        formatter = new BinaryFormatter();
                    MIXWord           startLoc  = (MIXWord)formatter.Deserialize(stream);
                    List <MemoryCell> data      = (List <MemoryCell>)formatter.Deserialize(stream);

                    machine.LoadImage(data);
                    machine.PC = startLoc;
                    machine.Run();
                }
            }
        }
Example #8
0
        private int LoadImage(string dump)
        {
            IFormatter        formatter = new BinaryFormatter();
            Stream            stream    = new FileStream(dump, FileMode.Open, FileAccess.Read, FileShare.Read);
            MIXWord           startLoc  = (MIXWord)formatter.Deserialize(stream);
            List <MemoryCell> data      = (List <MemoryCell>)formatter.Deserialize(stream);

            symbolTable = (Dictionary <string, MIXWord>)formatter.Deserialize(stream);
            stream.Close();

            machine.LoadImage(data);
            machine.PC = startLoc;

            return(data.Count);
        }
Example #9
0
 private void ShowMemory(int start, int end, bool dasm)
 {
     Console.WriteLine(string.Format("MEMORY CONTENTS ({0:0000} TO {1:0000})", start, end));
     Console.WriteLine();
     for (int i = start; i <= end; i++)
     {
         MIXWord w = machine.Memory[i];
         if (!dasm)
         {
             Console.WriteLine(string.Format("@{0:0000}: {1} = {2} = '{3}'", i, w, Convert.ToString(w.Value).PadLeft(10), MIXWordToString(w)));
         }
         else
         {
             Console.WriteLine(string.Format("@{0:0000}: {1} = {2} = '{3}'\t{4}", i, w, Convert.ToString(w.Value).PadLeft(10), MIXWordToString(w), GetDisassembly(w)));
         }
     }
 }
Example #10
0
        private string MIXWordToString(MIXWord w)
        {
            string result = "";

            for (byte i = 1; i < 6; i++)
            {
                var ch = from c in MIXMachine.CHAR_TABLE
                         where w[i] == c.Value
                         select c.Key;
                if (ch.Count() > 0)
                {
                    result += ch.ElementAt(0).ToString();
                }
                else
                {
                    result += "█";
                }
            }

            return(result);
        }
Example #11
0
        private string GetDisassembly(MIXWord w)
        {
            string          disassembly = "";
            InstructionInfo info        = machine.Disassemble(w);

            if (info == null)
            {
                disassembly = "???";
            }
            else
            {
                disassembly  = machine.Disassemble(w).Name + " " + w[0, 2];
                disassembly += w[3] != 0 ? "," + w[3] : "";
                if (w[4] != machine.Disassemble(w).DefaultField)
                {
                    disassembly += "(" + (w[4] / 8) + ":" + (w[4] % 8) + ")";
                }
            }

            return(disassembly);
        }
Example #12
0
        public MIXWord Field()
        {
            MIXWord result = new MIXWord(-1);

            if (tokStream.ToArray().Length > 0 && tokStream.First().Type == TokenType.LPAREN)
            {
                tokStream = tokStream.Skip(1);
                result    = Expression();
                if (tokStream.First().Type != TokenType.RPAREN)
                {
                    errors.Add(new ErrorInfo
                    {
                        Column = tokStream.First().ColumnNumber,
                        Line   = LineNumber,
                        Text   = string.Format("FIELD: Unexpected input: '{0}', Expected: ')'", tokStream.First().Text)
                    });
                }
                tokStream = tokStream.Skip(1);
            }

            return(result);
        }
Example #13
0
        private void Show(string[] what)
        {
            switch (what[0])
            {
            case "time":
                Console.WriteLine(string.Format("Execution time: {0}u", machine.ExecutionTime));
                break;

            case "bp":
            case "breakpoint":
                if (what.Length == 1)
                {
                    for (int i = 0; i < machine.BreakpointCount; i++)
                    {
                        Console.WriteLine(string.Format("{0} @ {1}", i, machine.GetBreakpoint(i)));
                    }
                }
                else
                {
                    int bp = int.Parse(what[1]);
                    Console.WriteLine(string.Format("{0} @ {1}", bp, machine.GetBreakpoint(bp)));
                }
                break;

            case "mem":
            case "memory":
                int start = 0, end = 3999;
                if (what.Length > 1)
                {
                    if (symbolTable.ContainsKey(what[1].ToUpper()))
                    {
                        start = symbolTable[what[1].ToUpper()].Value;
                    }
                    else
                    {
                        start = int.Parse(what[1]);
                    }
                    if (what.Length > 2)
                    {
                        if (symbolTable.ContainsKey(what[2].ToUpper()))
                        {
                            end = symbolTable[what[2].ToUpper()].Value;
                        }
                        else
                        {
                            end = int.Parse(what[2]);
                        }
                    }
                }

                bool dasm = false;
                if (what.Length > 4 && what[3] == "with" && (what[4] == "disassembly" || what[4] == "dasm"))
                {
                    dasm = true;
                }

                ShowMemory(start, end, dasm);
                break;

            case "state":
                ShowAllState();
                break;

            case "ra":
                ShowRegister(7);
                break;

            case "rx":
                ShowRegister(8);
                break;

            case "rj":
                ShowRegister(9);
                break;

            case "ri1":
                ShowRegister(1);
                break;

            case "ri2":
                ShowRegister(2);
                break;

            case "ri3":
                ShowRegister(3);
                break;

            case "ri4":
                ShowRegister(4);
                break;

            case "ri5":
                ShowRegister(5);
                break;

            case "ri6":
                ShowRegister(6);
                break;

            case "overflow":
            case "of":
                ShowRegister(10);
                break;

            case "ci":
                ShowRegister(11);
                break;

            case "pc":
                ShowRegister(12);
                break;

            case "verbose":
                Console.WriteLine(string.Format("Verbose mode: {0}", verbose));
                break;

            case "devices":
                ShowAllDevices();
                break;

            case "device":
                if (what.Length > 1)
                {
                    ShowDevice(int.Parse(what[1]));
                }
                else
                {
                    ShowAllDevices();
                }
                break;

            case "symbols":
                foreach (var s in symbolTable)
                {
                    Console.WriteLine(string.Format("{0} = {1} = {2} = '{3}'", s.Key, s.Value, s.Value.Value, MIXWordToString(s.Value)));
                }
                break;

            case "symbol":
                if (symbolTable.ContainsKey(what[1].ToUpper()))
                {
                    MIXWord w = symbolTable[what[1].ToUpper()];
                    Console.WriteLine(string.Format("{0} = {1} = {2} = '{3}'", what[1].ToUpper(), w, w.Value, MIXWordToString(w)));
                }
                else
                {
                    Console.Error.WriteLine(string.Format("Symbol '{0}' not found.", what[1].ToUpper()));
                }
                break;

            default:
                Console.Error.WriteLine(string.Format("Unknown parameter: '{0}'", what));
                break;
            }
        }
Example #14
0
 public string FormatSymbol(string name, MIXWord value)
 => name + "\t" + value + " = " + value.Value;
Example #15
0
 public string FormatSymbol(string name, MIXWord value)
 => string.Format("{0}&\\mixword${1}$.{2}.{3}.{4}.{5}.{6}.&=&{7}\\cr", name.Replace("|", @"\|"),
                  value[0] == 1 ? "-" : "+", value[1], value[2], value[3], value[4], value[5], value.Value);
Example #16
0
        private MIXWord Expression()
        {
            MIXWord         result    = new MIXWord();
            Set <TokenType> firstTerm = new Set <TokenType>();

            firstTerm.Add(TokenType.PLUS); firstTerm.Add(TokenType.MINUS);
            firstTerm.Add(TokenType.STAR); firstTerm.Add(TokenType.SLASH);
            firstTerm.Add(TokenType.SLASHSLASH); firstTerm.Add(TokenType.COLON);

            if (tokStream.First().Type == TokenType.PLUS)
            {
                tokStream = tokStream.Skip(1);
                result    = Atom();
            }
            else if (tokStream.First().Type == TokenType.MINUS)
            {
                tokStream = tokStream.Skip(1);
                result    = -Atom();
            }
            else
            {
                result = Atom();
            }

            while (tokStream.ToArray().Length > 0 && firstTerm.Contains(tokStream.First().Type))
            {
                var oper = tokStream.First().Type;
                tokStream = tokStream.Skip(1);

                var term = Atom();

                switch (oper)
                {
                case TokenType.PLUS:
                    result += term;
                    break;

                case TokenType.MINUS:
                    result -= term;
                    break;

                case TokenType.STAR:
                    result *= term;
                    break;

                case TokenType.SLASH:
                    result /= term;
                    break;

                case TokenType.SLASHSLASH:
                    string wordZero = "";
                    for (int i = 0; i < 30; i++)
                    {
                        wordZero += "0";
                    }
                    long n = Convert.ToInt64(Convert.ToString(result.Value, 2) + wordZero, 2);
                    n     /= (long)term.Value;
                    result = new MIXWord((int)n);
                    break;

                case TokenType.COLON:
                    result = new MIXWord(8 * result + term);
                    break;
                }
            }

            return(result);
        }
Example #17
0
        public MIXWord Address()
        {
            MIXWord result = new MIXWord();

            if (tokStream.ToArray().Length > 0)
            {
                var first = tokStream.First();

                if (first.Type == TokenType.SYMBOL)
                {
                    var symbName = first.Text;
                    if (symbName.Length == 2 && char.IsDigit(symbName[0]) && symbName[1] == 'F')
                    {
                        var n = byte.Parse(symbName[0].ToString());
                        if (!localSymbs.ContainsKey(n))
                        {
                            symbName = "|" + n + "-1|";
                        }
                        else
                        {
                            symbName = "|" + n + "-" + (localSymbs[n] + 1) + "|";
                        }
                    }

                    if (!IsLocal(symbName) && !symbolTable.ContainsKey(symbName))
                    {
                        FRefSymb  = symbName;
                        tokStream = tokStream.Skip(1);
                        return(null);
                    }
                    else
                    {
                        result = Expression();
                    }
                }
                else if (first.Type == TokenType.EQUALS)
                {
                    tokStream = tokStream.Skip(1);
                    MIXWord litVal = WordValue();
                    if (first.Type != TokenType.EQUALS)
                    {
                        errors.Add(new ErrorInfo
                        {
                            Column = first.ColumnNumber,
                            Line   = LineNumber,
                            Text   = "ADDRESS: Expected: '='"
                        });
                    }
                    tokStream = tokStream.Skip(1);

                    FRefSymb = "=" + litVal.Value + "=";
                    return(null);
                }
                else
                {
                    result = Expression();
                }
            }

            return(result);
        }
Example #18
0
        private void ParseLine(Scanner s)
        {
            tokStream = s.Tokens;
            var lblText = string.Empty;

            if (tokStream.First().Type == TokenType.LABEL)
            {
                lblText = tokStream.First().Text;
                if (lblText.Length == 2 && char.IsDigit(lblText[0]) && lblText[1] == 'H')
                // This is a local symbol
                {
                    var n = byte.Parse(lblText[0].ToString());
                    if (localSymbs.ContainsKey(n))
                    {
                        localSymbs[n] = localSymbs[n] + 1;
                    }
                    else
                    {
                        localSymbs.Add(n, 1);
                    }
                    lblText = "|" + n + "-" + localSymbs[n] + "|";
                }
                if (tokStream.Skip(1).ToArray().Length > 0)
                {
                    symbolTable.Add(lblText, new MIXWord(locCounter));
                    tokStream = tokStream.Skip(1);
                }
                else
                {
                    errors.Add(new ErrorInfo
                    {
                        Column = tokStream.First().ColumnNumber,
                        Line   = LineNumber,
                        Text   = "LINE: Unexpected end of line, expected: KEYWORD or PSEUDO"
                    });
                }
            }

            // Parse the rest of the sentence
            switch (tokStream.First().Type)
            {
            case TokenType.KEYWORD:
                var instrList = from i in MIXMachine.INSTRUCTION_LIST
                                where i.Name == tokStream.First().Text
                                select i;
                InstructionInfo instr = instrList.First();
                tokStream = tokStream.Skip(1);
                MIXWord a = Address(); MIXWord index = Index(); MIXWord f = Field(); if (f == -1)
                {
                    f = instr.DefaultField;
                }
                MIXWord word = new MIXWord();
                if (a != null)
                {
                    word[0, 2] = a; word[3] = index; word[4] = f; word[5] = instr.OpCode;
                    assembly.Add(new MemoryCell {
                        SourceLocation = LineNumber, Location = locCounter, Contents = word
                    });
                }
                else
                {
                    futureRefs.Add(new FutureReference {
                        Symbol = FRefSymb, Field = f, Index = index, Location = locCounter, OpCode = instr.OpCode, SourceLocation = LineNumber
                    });
                }

                locCounter++;
                break;

            case TokenType.ORIG:
                tokStream  = tokStream.Skip(1);
                locCounter = WordValue();
                break;

            case TokenType.CON:
                tokStream = tokStream.Skip(1);
                assembly.Add(new MemoryCell {
                    SourceLocation = LineNumber, Location = locCounter, Contents = WordValue()
                });
                locCounter++;
                break;

            case TokenType.EQU:
                tokStream = tokStream.Skip(1);
                var val = WordValue();
                if (!string.IsNullOrEmpty(lblText))
                {
                    symbolTable[lblText] = val;
                }
                break;

            case TokenType.ALF:
                tokStream = tokStream.Skip(1);
                if (tokStream.First().Type != TokenType.STRING)
                {
                    errors.Add(new ErrorInfo
                    {
                        Line   = LineNumber,
                        Column = tokStream.First().ColumnNumber,
                        Text   = "LINE: Expected: STRING CONSTANT."
                    });
                }
                else
                {
                    string sc = tokStream.First().Text;

                    MIXWord w = new MIXWord();
                    for (byte i = 0; i < 5; i++)
                    {
                        w[(byte)(i + 1)] = MIXMachine.CHAR_TABLE[sc[i]];
                    }

                    assembly.Add(new MemoryCell {
                        SourceLocation = LineNumber, Location = locCounter, Contents = w
                    });
                    locCounter++;

                    tokStream = tokStream.Skip(1);
                }
                break;

            case TokenType.END:
                if (null != StartLoc)
                {
                    warnings.Add(new ErrorInfo
                    {
                        Line   = LineNumber,
                        Column = tokStream.First().ColumnNumber,
                        Text   = "LINE: Multiple appearances of the END directive."
                    });
                }
                tokStream      = tokStream.Skip(1);
                StartLoc       = WordValue();
                insertionPoint = locCounter;
                break;

            default:
                errors.Add(new ErrorInfo
                {
                    Line   = LineNumber,
                    Column = tokStream.First().ColumnNumber,
                    Text   = string.Format("LINE: Parser panic! Don't know what to do with token {0}['{1}']",
                                           tokStream.First().Type, tokStream.First().Text)
                });
                break;
            }
        }