private static void findLabels(Parser parser, SymbolTable symbols) { int ROM = 0; string symbol; while (parser.hasMoreCommands()) { try { parser.advance(); } catch (EndOfStreamException) { break; } switch (parser.commandType()) { case Parser.L_COMMAND: symbol = parser.symbol(); if (symbols.contains(symbol)) { throw new InvalidOperationException("Cannot redefine label: " + symbol); } symbols.addEntry(symbol, ROM); break; case Parser.A_COMMAND: case Parser.C_COMMAND: ROM++; break; } } parser.reset(); }
private static void assemble(Parser parser, SymbolTable symbols, StreamWriter output) { Code translator = new Code(); int RAM = 16; while (parser.hasMoreCommands()) { int value = 0; try { parser.advance(); } catch (EndOfStreamException) { break; } switch (parser.commandType()) { case Parser.A_COMMAND: int address; string symbol = parser.symbol(); bool isNumber = int.TryParse(symbol, out address); if (!isNumber) { if (!symbols.contains(symbol)) { symbols.addEntry(symbol, RAM++); } address = symbols.getAddress(symbol); } value = address; break; case Parser.C_COMMAND: value |= 7 << 13; // 1110000000000000 == 57344 value |= translator.comp(parser.comp()); value |= translator.dest(parser.dest()); value |= translator.jump(parser.jump()); break; case Parser.L_COMMAND: continue; } string instruction = Convert.ToString(value, 2).PadLeft(16, '0'); output.WriteLine(instruction); } parser.reset(); }
static void Main(string[] args) { String inputpath = Path.GetFullPath(args[0]); String outputpath = Path.GetFileNameWithoutExtension(inputpath) + ".hack"; StreamWriter outputwriter = new StreamWriter(outputpath);//, Encoding.UTF8); Parser prs = new Parser(inputpath); int romAddress = 0; while (prs.hasMoreCommands()) { switch (prs.commandtype) { case Parser.commandtypes.A_COMMAND: case Parser.commandtypes.C_COMMAND: romAddress++; break; case Parser.commandtypes.L_COMMAND: SymbolTable.addEntry(prs.symbol, romAddress); break; default: break; } } prs.rewind(); int ramAddress = 16; while (prs.hasMoreCommands()) { String line = ""; switch (prs.commandtype) { case Parser.commandtypes.A_COMMAND: Int16 number; //直値の時。string -> int16 -> 2進数 -> 15桁にパディング の流れ if (Int16.TryParse(prs.symbol, out number)) { line = "0" + Convert.ToString(number, 2).PadLeft(15, '0'); } //ラベルシンボルの時。symbolDictは10進intなので2進数stringに変換 else if (SymbolTable.symbolDict.ContainsKey(prs.symbol)) { line = "0" + (Convert.ToString(SymbolTable.symbolDict[prs.symbol], 2)).PadLeft(15, '0'); } //変数の時 else { SymbolTable.addEntry(prs.symbol, ramAddress); line = "0" + (Convert.ToString(ramAddress, 2)).PadLeft(15, '0'); ramAddress++; } outputwriter.WriteLine(line); break; case Parser.commandtypes.C_COMMAND: line = "111" + Code.compDict[prs.comp] + Code.destDict[prs.dest] + Code.jumpDict[prs.jump]; outputwriter.WriteLine(line); break; case Parser.commandtypes.L_COMMAND: break; default: break; } } outputwriter.Close(); prs.close(); }
static void Main() { string title = "Pong"; //Name of source file string title2 = "pong"; //Name for file path string outfile = "/Applications/nand2tetris/projects/06/" + title2 + "/" + title + ".hack"; bool hasMoreCommands = true; string type; int nextMem = 16; int counter = 0; Parser p1 = new Parser("/Applications/nand2tetris/projects/06/" + title2 + "/" + title + ".asm"); SymbolTable st = new SymbolTable(); while (hasMoreCommands == true) //First { p1.advance(); type = p1.commandType(); if (type == "L_COMMAND") { st.addEntry(p1.symbol(), counter); } else { counter += 1; hasMoreCommands = p1.hasMoreCommands(); } } hasMoreCommands = true; Parser p = new Parser("/Applications/nand2tetris/projects/06/" + title2 + "/" + title + ".asm"); Code c = new Code(); while (hasMoreCommands == true) //Second { p.advance(); type = p.commandType(); if (type == "A_COMMAND") { string varOrNum = p.symbol(); char von = varOrNum[0]; if (char.IsDigit(von) == true) { int prexxx = Convert.ToInt32(p.symbol()); string xxx = Convert.ToString(prexxx, 2).PadLeft(16, '0'); using (StreamWriter sw = new StreamWriter(outfile, true)) { sw.WriteLine(xxx); } } else //if(char.IsDigit(von)==false), which means xxx is variable. { bool cont = st.contains(varOrNum); if (cont == false) { st.addEntry(varOrNum, nextMem); string xxx = Convert.ToString(nextMem, 2).PadLeft(16, '0'); using (StreamWriter sw = new StreamWriter(outfile, true)) { sw.WriteLine(xxx); } nextMem += 1; } else { string xxx = Convert.ToString(st.getAddress(varOrNum), 2).PadLeft(16, '0'); using (StreamWriter sw = new StreamWriter(outfile, true)) { sw.WriteLine(xxx); } } } } else if (type == "C_COMMAND") { string destmne = p.dest(); string dest = c.dest(destmne); string compmne = p.comp(); string comp = c.comp(compmne); string jumpmne = p.jump(); string jump = c.jump(jumpmne); string c_command = "111" + comp + dest + jump; using (StreamWriter sw = new StreamWriter(outfile, true)) { sw.WriteLine(c_command); } } else //if (type=="L_COMMAND") { } hasMoreCommands = p.hasMoreCommands(); } }