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); }
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 }); } }
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); }
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); }
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); }
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; }
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(); } } }
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); }
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))); } } }
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); }
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); }
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); }
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; } }
public string FormatSymbol(string name, MIXWord value) => name + "\t" + value + " = " + value.Value;
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);
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); }
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); }
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; } }