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; } }
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()); }
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); }