Example #1
0
        private void GridRAM_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            edtMessages.Clear();
            errors = new SortedDictionary <byte, string>();
            labels = new Dictionary <string, byte>();
            for (byte addr = 0; addr < 100; addr++)
            {
                string line = (string)GridRAM[1, addr].Value;
                if (line == null)
                {
                    continue;
                }
                line = line.Trim().ToUpper();

                //Make sure the labels are accounted for
                if (line[0] == ':')
                {
                    string[] parts = line.Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                    //validation: what can a label be called?
                    parts[0] = parts[0].Substring(1); //remove the :
                    int dummy;                        //not ever used
                    if (parts[0] == "" || new string[] { "ADD", "SUB", "LDA", "STO", "BR", "BRP", "BRZ", "HLT", "IN", "OUT", "DAT" }.Contains(parts[0]) || int.TryParse(parts[0], out dummy))
                    {
                        AddError(addr, "Label '" + parts[0] + "' is invalid!");
                        continue;
                    }
                    //update the label dictionary
                    if (labels.ContainsKey(parts[0]))
                    {
                        labels[parts[0]] = addr;
                    }
                    else
                    {
                        labels.Add(parts[0], addr);
                    }
                }
            }

            for (byte addr = 0; addr < 100; addr++)
            {
                string line = (string)GridRAM[1, addr].Value;
                if (line == null)
                {
                    continue;
                }
                line = line.Trim().ToUpper();

                if (line[0] == ':')
                {
                    string[] parts = line.Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                    try
                    {
                        line = parts[1];//remove the label
                    }
                    catch (IndexOutOfRangeException) { continue; }
                }
                //now translate this into opcode
                try
                {
                    string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    //translate labels
                    for (int i = 0; i < parts.Length; i++)
                    {
                        if (labels.ContainsKey(parts[i]))
                        {
                            parts[i] = labels[parts[i]].ToString();
                        }
                    }

                    line = "";
                    foreach (string part in parts)
                    {
                        line += part + " ";
                    }

                    ushort opcode = Mnemonic.ToByteCode(line);
                    LMC.RAM[addr] = opcode;
                }
                catch (Exception except)
                {
                    AddError(addr, except.Message);
                }
            }
        }
Example #2
0
        static public ushort ToByteCode(string instruction)
        {
            instruction = instruction.ToUpper();
            string[] parts = instruction.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length == 0)
            {
                throw new Exception("An empty string is not valid syntax");
            }

            //check for numbers
            ushort potentialNumber;

            if (ushort.TryParse(parts[0], out potentialNumber))
            {
                return(potentialNumber);
            }
            else if (parts[0] == "DAT")
            {
                return(Mnemonic.ToByteCode(parts[1]));//DAT is followed either by an instruction or a number
            }
            else if (parts[0] == "IN")
            {
                if (parts.Length > 1)
                {
                    throw new Exception("Unexpected arguments for IN instruction");
                }
                else
                {
                    return(901);
                }
            }
            else if (parts[0] == "OUT")
            {
                if (parts.Length > 1)
                {
                    throw new Exception("Unexpected arguments for OUT instruction");
                }
                else
                {
                    return(902);
                }
            }
            else if (parts[0] == "HLT")
            {
                if (parts.Length > 1)
                {
                    throw new Exception("Unexpected arguments for HLT instruction");
                }
                else
                {
                    return(0);
                }
            }
            else
            {
                if (parts.Length < 2)
                {
                    throw new Exception("Argument expected for " + parts[0] + " instruction");
                }
                if (parts.Length > 2)
                {
                    throw new Exception("Unexpected second argument for " + parts[0] + " instruction");
                }

                ushort address;
                try { address = ushort.Parse(parts[1]); }
                catch (Exception) { throw new Exception("Argument is invalid"); }

                if (address > 99)
                {
                    throw new Exception("Argument is out of bounds!");
                }

                //otherwise we should be ready to parse an instruction with a parameter
                switch (parts[0])
                {
                case "ADD": return((ushort)(100 + address));

                case "SUB": return((ushort)(200 + address));

                case "STO": return((ushort)(300 + address));

                case "LDA": return((ushort)(500 + address));

                case "BR": return((ushort)(600 + address));

                case "BRZ": return((ushort)(700 + address));

                case "BRP": return((ushort)(800 + address));

                default: throw new Exception("Invalid opcode " + parts[0]);
                }
            }
        }