private void startBtn_Click(object sender, RoutedEventArgs e) { saveBtn_Click(null, null); string text = new TextRange(codeEditor.Document.ContentStart, codeEditor.Document.ContentEnd).Text; errorBox.Text = ""; try { var Instructions = AssemblerSpecs.Assemble(text); output.ItemsSource = Instructions; using (var fs = new FileStream(codeFile.Replace(".asm", ".hack"), FileMode.OpenOrCreate & FileMode.Truncate, FileAccess.Write)) { using (StreamWriter streamWriter = new StreamWriter(fs)) { foreach (var i in Instructions) { streamWriter.WriteLine(i); } streamWriter.Flush(); } } } catch (Exception ex) { errorBox.Text = ex.Message; } }
public static List <string> Assemble(string Text) { var HackCode = new List <string>(); var Instructions = AssemblerSpecs.CleanCode(Text); var SymbolTable = new Dictionary <string, int>(AssemblerSpecs.PreSymbols); for (int i = 0; i < Instructions.Count; i++) { var instruction = Instructions[i].instruction; var instructionLNo = Instructions[i].linenumber; if (instruction.StartsWith("(")) { var label = instruction?.Replace("(", "")?.Replace(")", "")?.Trim(); if (string.IsNullOrEmpty(label)) { throw new Exception("Invalid Label at line " + instructionLNo + 1); } SymbolTable.Add(label, i); Instructions.RemoveAt(i--); } } int lastVar = 16; for (int i = 0; i < Instructions.Count; i++) { var instruction = Instructions[i].instruction; var instructionLNo = Instructions[i].linenumber; if (instruction.StartsWith("@")) { var label = instruction?.Replace("@", "")?.Trim(); if (string.IsNullOrEmpty(label)) { throw new Exception("Invalid address at line " + (instructionLNo + 1)); } int address = 0; if (int.TryParse(label, out address)) { continue; } if (SymbolTable.ContainsKey(label)) { address = SymbolTable[label]; } else { SymbolTable[label] = lastVar++; address = SymbolTable[label]; } } } for (int i = 0; i < Instructions.Count; i++) { var instruction = Instructions[i].instruction; var instructionLNo = Instructions[i].linenumber; try { if (instruction.StartsWith("@")) { var label = instruction?.Replace("@", "")?.Trim(); int address; if (!int.TryParse(label, out address)) { if (SymbolTable.ContainsKey(label)) { address = SymbolTable[label]; } else { throw new Exception("'" + label + "' label not found at line number " + instructionLNo); } } char[] hack = new char[16] { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' }; var stringAddres = Convert.ToString(address, 2); for (int j = 16 - stringAddres.Length; j < 16; j++) { hack[j] = stringAddres[j - (16 - stringAddres.Length)]; } HackCode.Add(new string(hack)); } else { string dest = "null"; string comp = ""; string jump = "null"; if (instruction.Contains(';') && instruction.Contains('=')) { var split_destAndOther = instruction.Split('='); var split_compAndJump = split_destAndOther[1].Split(';'); dest = split_destAndOther[0]; comp = split_compAndJump[0]; jump = split_compAndJump[1]; } else if (instruction.Contains(';')) { var splited = instruction.Split(';'); comp = splited[0]; jump = splited[1]; } else if (instruction.Contains('=')) { var splited = instruction.Split('='); dest = splited[0]; comp = splited[1]; } else { throw new Exception("Invalid instruction line at " + instructionLNo); } var hack = "111" + COMP[comp] + DEST[dest] + JUMP[jump]; HackCode.Add(hack); } } catch (Exception ex) { throw new Exception(ex.Message + " line at " + instructionLNo); } } return(HackCode); }