private static void WriteXmlInstruction(XmlTextWriter xmltw, AbstractInstruction cinst)
        {
            switch (cinst.Name())
            {
            case "call":
            case "execute":
            case "bcall":
                xmltw.WriteStartElement(cinst.Name());
                xmltw.WriteAttributeString("name", cinst.ToString().Split(new char[] { ' ' })[1]);
                xmltw.WriteEndElement();
                break;

            case "fcall":
                FCallInstruction fcinst = (FCallInstruction)cinst;
                xmltw.WriteStartElement(cinst.Name());
                xmltw.WriteAttributeString("assembly", fcinst._assemblyName);
                xmltw.WriteAttributeString("class", fcinst._classType);
                xmltw.WriteAttributeString("method", fcinst._methodName);
                xmltw.WriteAttributeString("predicate", fcinst._predicateName);
                break;

            default:
                WriteXmlInstructionArguments(xmltw, cinst);
                break;
            }
        }
        private string GetInstructionStatement(AbstractInstruction inst)
        {
            string statement = "program.Add(iset.CreateInstruction(";

            if (inst.Name() == "procedure")
            {
                ProcedureInstruction pi = (ProcedureInstruction)inst;
                statement += "\"procedure\", \"" + pi.ProcedureName + "\", \"" + pi.Arity + "\"";
            }
            else
            {
                if (inst._arguments == null || inst._arguments.Length == 0)
                {
                    statement += "\"" + inst.Name() + "\"";
                }
                else
                {
                    statement += "\"" + inst.Name() + "\", ";
                    for (int i = 0; i < inst._arguments.Length; i++)
                    {
                        statement += "\"" + inst._arguments[i] + "\"";
                        if (i != (inst._arguments.Length - 1))
                        {
                            statement += ", ";
                        }
                    }
                }
            }

            statement += "));";

            return(statement);
        }
        private static void WriteXmlInstructionArguments(XmlTextWriter xmltw, AbstractInstruction cinst)
        {
            switch (cinst.NumberOfArguments())
            {
            case 0:
                xmltw.WriteStartElement(cinst.Name());
                xmltw.WriteEndElement();
                break;

            case 1:
                xmltw.WriteStartElement(cinst.Name());
                xmltw.WriteAttributeString("arg1", cinst.ToString().Split(new char[] { ' ' })[1]);
                xmltw.WriteEndElement();
                break;

            case 2:
                xmltw.WriteStartElement(cinst.Name());
                if (cinst.Name() == "put_structure")
                {
                    string args = cinst.ToString().Split(new char[] { ' ' })[1];
                    xmltw.WriteAttributeString("arg1", args.Split(new char[] { ',' })[0]);
                    xmltw.WriteAttributeString("arg2", args.Split(new char[] { ',' })[1]);
                    xmltw.WriteEndElement();
                }
                else
                {
                    if (cinst.ToString().IndexOf('"') != -1)
                    {
                        // put_constant "Hello, World", X0
                        string instStr = cinst.ToString();
                        string arg1    = instStr.Substring(instStr.IndexOf('"'), instStr.LastIndexOf('"') - instStr.IndexOf('"') + 1);
                        string arg2    = instStr.Substring(instStr.LastIndexOf('"') + 2);
                        xmltw.WriteAttributeString("arg1", arg1);
                        xmltw.WriteAttributeString("arg2", arg2);
                        xmltw.WriteEndElement();
                    }
                    else if (cinst.ToString().IndexOf('\'') != -1)
                    {
                        // put_constant 'Hello, World', X0
                        string instStr = cinst.ToString();
                        string arg1    = instStr.Substring(instStr.IndexOf('\''), instStr.LastIndexOf('\'') - instStr.IndexOf('\'') + 1);
                        string arg2    = instStr.Substring(instStr.LastIndexOf('\'') + 2);
                        xmltw.WriteAttributeString("arg1", arg1);
                        xmltw.WriteAttributeString("arg2", arg2);
                        xmltw.WriteEndElement();
                    }
                    else
                    {
                        string args = cinst.ToString().Split(new char[] { ' ' })[1];
                        xmltw.WriteAttributeString("arg1", args.Split(new char[] { ',' })[0]);
                        xmltw.WriteAttributeString("arg2", args.Split(new char[] { ',' })[1]);
                        xmltw.WriteEndElement();
                    }
                }
                break;
            }
        }
Example #4
0
        public void CreateInstruction()
        {
            AMInstructionSet am = new AMInstructionSet();

            foreach (string s in instructions)
            {
                AbstractInstruction i = null;

                if (s == "set_void" || s == "unify_void")
                {
                    i = am.CreateInstruction(s, "1");
                    Assert.AreEqual(s, i.Name());
                }
                else
                {
                    i = am.CreateInstruction(s, "f/1", "1", "X2", "X3");
                    Assert.AreEqual(s, i.Name());
                }
            }
        }
        private static void GenerateXmlFile(string xmlFilename, ArrayList assemblyFiles, ArrayList arrayList)
        {
            XmlTextWriter xmltw = new XmlTextWriter(xmlFilename, null);

            xmltw.Formatting = Formatting.Indented;


            xmltw.WriteStartDocument();

            xmltw.WriteComment(" This file was automatically generated by axiomc ");
            xmltw.WriteComment(" Source: " + xmlFilename.Replace(".xml", ".pro") + ",    Date: " + DateTime.Now + " ");



            xmltw.WriteStartElement("AMProgram");

            /* write namespaces and assembly files here */
            if (assemblyFiles.Count > 0)
            {
                xmltw.WriteStartElement("AssemblyFiles");
                foreach (string asmFile in assemblyFiles)
                {
                    xmltw.WriteStartElement("LoadAssembly");
                    xmltw.WriteString(asmFile);
                    xmltw.WriteEndElement();
                }
                xmltw.WriteEndElement();
            }

            for (int i = 0; i < arrayList.Count; i++)
            {
                AbstractInstruction inst = (AbstractInstruction)arrayList[i];
                if (inst.Name() == "procedure")
                {
                    ProcedureInstruction p = (ProcedureInstruction)inst;
                    xmltw.WriteStartElement("Predicate");
                    xmltw.WriteAttributeString("name", p.ProcedureName + "/" + p.Arity);
                    for (int j = i + 1; j < arrayList.Count; j++)
                    {
                        AbstractInstruction cinst = (AbstractInstruction)arrayList[j];
                        WriteXmlInstruction(xmltw, cinst);
                        if (cinst.Name() == "proceed" || cinst.Name() == "execute")
                        {
                            i = j;
                            break;
                        }
                    }
                    xmltw.WriteEndElement();
                }
                else
                {
                    WriteXmlInstruction(xmltw, inst);
                }
            }


            xmltw.WriteEndElement();
            xmltw.WriteEndDocument();
            xmltw.Flush();
            xmltw.Close();
        }
 private bool CompareInstructions(AbstractInstruction i1, AbstractInstruction i2)
 {
     return(i1.ToString() == i2.ToString());
 }
Example #7
0
        static int Main(string[] args)
        {
            Console.WriteLine("MMIXAL Assembler");
            Console.WriteLine($"Thomas Holmes 2020. {VersionNumber}");

            if (args.Length < 1)
            {
                Console.WriteLine("A source file must be specified");
                return(-1);
            }
            string objectFile = args[0];

            var asmLines  = new List <AsmLine>();
            var operators = ReflectionUtilities.FindExtendingClasses <AbstractInstruction>().ToArray();

            ulong lineNumber     = 1;
            var   assemblerState = new AssemblerState();

            using (var stream = File.OpenRead(objectFile))
                using (var reader = new StreamReader(stream))
                {
                    ulong  virtualProgramCounter = 0;
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (string.IsNullOrWhiteSpace(line))
                        {
                            continue;
                        }

                        AsmLine asmLine;
                        try
                        {
                            asmLine = AsmLine.Parse(line);
                        }
                        catch (Exception ex)
                        {
                            assemblerState.RaiseError(ex.Message);
                            continue;
                        }

                        // hacks to forward read address references.
                        if (asmLine.Op == "LOC" && assemblerState.TryParseConstant(asmLine.Expr, out ulong location))
                        {
                            virtualProgramCounter = location;
                        }
                        if (!string.IsNullOrWhiteSpace(asmLine.Label))
                        {
                            assemblerState.DefineVariable(asmLine.Label, new OctaConstantAssemblerVariable(virtualProgramCounter));
                        }
                        virtualProgramCounter += operators.SingleOrDefault(o => o.SupportsSymbol(asmLine.Op))?.DetermineByteLength(asmLine) ?? 0;

                        asmLines.Add(asmLine);
                        lineNumber++;
                    }
                }

            var outFile = objectFile.Replace(".mms", ".mmo");

            if (!assemblerState.Errors.Any())
            {
                using (var outStream = File.OpenWrite(outFile))
                    using (var streamWriter = new StreamWriter(outStream))
                    {
                        foreach (var asmLine in asmLines)
                        {
                            AbstractInstruction op = operators.SingleOrDefault(o => o.SupportsSymbol(asmLine.Op));
                            if (op is null)
                            {
                                // unknown operation
                                op = new ErroneousInstruction(asmLine.Op);
                            }

                            OperatorOutput output = null;
                            try
                            {
                                output = op.GenerateBinary(assemblerState, asmLine);
                            }
                            catch (Exception ex)
                            {
                                assemblerState.RaiseError(ex.Message);
                            }

                            if (!string.IsNullOrWhiteSpace(output?.Warning))
                            {
                                assemblerState.RaiseWarning(output?.Warning);
                            }
                            if (output.Output != null)
                            {
                                // ensure bytes are multiple of 4
                                var bytes = new List <byte>(output.Output);
                                for (int skip = 0; skip < bytes.Count; skip += 4)
                                {
                                    var byteLine = bytes.Skip(skip).Take(4).ToArray();
                                    streamWriter.WriteLine($"{assemblerState.ProgramCounter:x}: {byteLine.ToHexString()}");
                                    assemblerState.ProgramCounter += 4;
                                }
                            }
                        }
                    }
            }

            Console.WriteLine($"Program assembled with {assemblerState.Warnings.Count} warnings and {assemblerState.Errors.Count} errors");
            foreach (var warning in assemblerState.Warnings)
            {
                Console.WriteLine($"Warning - {warning}");
            }
            foreach (var error in assemblerState.Errors)
            {
                Console.WriteLine($"Error - {error}");
            }

            if (assemblerState.Errors.Any())
            {
                Console.WriteLine("Program not written due to previous errors.");
                File.Delete(outFile);
            }
            else
            {
                Console.WriteLine($"Program written to {outFile}.");
            }

            return(0);
        }