示例#1
0
        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;
            }
        }
示例#2
0
        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);
        }