diff --git a/src/SVM.Assembler.Core/Assembler.cs b/src/SVM.Assembler.Core/Assembler.cs index fb102c0..f39f518 100644 --- a/src/SVM.Assembler.Core/Assembler.cs +++ b/src/SVM.Assembler.Core/Assembler.cs @@ -65,7 +65,7 @@ LabelConstant InternalLbl ISA = isaDefinition; } - public OperationResult Lex(ILexer lexer) + private OperationResult Lex(ILexer lexer) { while (true) { @@ -78,7 +78,7 @@ LabelConstant InternalLbl } } } - public OperationResult<(string, string)?> ParseKVPair(ILexer lexer, LexSegment currentSeg) + private OperationResult<(string, string)?> ParseKVPair(ILexer lexer, LexSegment currentSeg) { OperationResult<(string, string)?> operationResult = new OperationResult<(string, string)?>(null); var r = Lex(lexer); diff --git a/src/SVM.Assembler.Core/ISADefinition.cs b/src/SVM.Assembler.Core/ISADefinition.cs index 2b7a667..3d6ce9a 100644 --- a/src/SVM.Assembler.Core/ISADefinition.cs +++ b/src/SVM.Assembler.Core/ISADefinition.cs @@ -1,6 +1,7 @@ using SVM.Core; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Xml; @@ -34,17 +35,17 @@ namespace SVM.Assembler.Core { for (int i = 0; i < depth; i++) { - Console.Write("\t"); + Trace.Write("\t"); } } static void ShowNode(XmlNode node, int depth = 0) { PrintDepth(depth); - Console.WriteLine($"[+]{node.NodeType}:{node.Name}"); + Trace.WriteLine($"[+]{node.NodeType}:{node.Name}"); foreach (XmlAttribute item in node.Attributes) { PrintDepth(depth + 1); - Console.WriteLine($"[i]{item.NodeType}:{item.Name}={item.InnerText}"); + Trace.WriteLine($"[i]{item.NodeType}:{item.Name}={item.InnerText}"); } foreach (XmlElement item in node.ChildNodes) @@ -56,13 +57,13 @@ namespace SVM.Assembler.Core else { PrintDepth(depth + 1); - Console.Write($"[?]{item.NodeType}:{item.Name}"); + Trace.Write($"[?]{item.NodeType}:{item.Name}"); } } } static bool ParseParameter(XmlNode node, ref InstructionDefinition instruction) { - Console.WriteLine("Parse:Parameter"); + Trace.WriteLine("Parse:Parameter"); InstructionParameter parameter = new InstructionParameter(); foreach (XmlNode subNode in node) { @@ -75,7 +76,7 @@ namespace SVM.Assembler.Core { var result = item.Attributes.GetNamedItem("Id"); if (result == null) return false; - Console.WriteLine($"Item:{result.InnerText}"); + Trace.WriteLine($"Item:{result.InnerText}"); parameter.AllowedTokenIds.Add(result.InnerText); } } @@ -90,12 +91,12 @@ namespace SVM.Assembler.Core if (ConverterAttr == null) return false; if (!Enum.TryParse(TypeAttr.InnerText, out var nType)) { - Console.WriteLine($"ParseSVMNativeTypes:{TypeAttr.InnerText}"); + Trace.WriteLine($"ParseSVMNativeTypes:{TypeAttr.InnerText}"); return false; } if (!int.TryParse(PosAttr.InnerText, out var pos)) { - Console.WriteLine($"ParseInt:{PosAttr.InnerText}"); + Trace.WriteLine($"ParseInt:{PosAttr.InnerText}"); return false; } parameter.ExpectdValue.Type = nType; @@ -111,7 +112,7 @@ namespace SVM.Assembler.Core } static bool ParseDefinition(XmlNode node, ref ISADefinition definition) { - Console.WriteLine($"ParseDefinition:{node.Name}"); + Trace.WriteLine($"ParseDefinition:{node.Name}"); InstructionDefinition instDefinition = new InstructionDefinition(); var PIAttr = node.Attributes.GetNamedItem("PrimaryInstruction"); if (PIAttr == null) return false; @@ -122,13 +123,13 @@ namespace SVM.Assembler.Core instDefinition.PrimaryInstruction = pi; foreach (XmlNode item in node.ChildNodes) { - Console.WriteLine($"{item.Name}"); + Trace.WriteLine($"{item.Name}"); switch (item.Name) { case "Aliases": foreach (XmlNode aliasNode in item.ChildNodes) { - Console.WriteLine($"Aliases->{aliasNode.Name}"); + Trace.WriteLine($"Aliases->{aliasNode.Name}"); if (aliasNode.Name == "Alias") { instDefinition.Aliases.Add(aliasNode.Attributes["Name"].Value); @@ -142,7 +143,7 @@ namespace SVM.Assembler.Core case "Parameters": foreach (XmlNode parameterNode in item.ChildNodes) { - Console.WriteLine($"Parameters->{parameterNode.Name}"); + Trace.WriteLine($"Parameters->{parameterNode.Name}"); if (parameterNode.Name == "InstructionParameter") { if (!ParseParameter(parameterNode, ref instDefinition)) @@ -157,7 +158,7 @@ namespace SVM.Assembler.Core } break; default: - Console.WriteLine($"???{item.Name}"); + Trace.WriteLine($"???{item.Name}"); break; } } @@ -166,12 +167,12 @@ namespace SVM.Assembler.Core } static bool ParseDefinitions(XmlNode node, ref ISADefinition definition) { - Console.WriteLine("Parse:Definitions"); + Trace.WriteLine("Parse:Definitions"); foreach (XmlNode item in node.ChildNodes) { if (item.Name != "InstructionDefinition") { - Console.WriteLine($"Not Matching:{item.Name}"); + Trace.WriteLine($"Not Matching:{item.Name}"); return false; } @@ -279,7 +280,7 @@ namespace SVM.Assembler.Core } break; default: - Console.WriteLine("Unknown Node!"); + Trace.WriteLine("Unknown Node!"); break; } } diff --git a/src/SVM.Assembler.Core/Linker.cs b/src/SVM.Assembler.Core/Linker.cs index 6721b46..6cc78bc 100644 --- a/src/SVM.Assembler.Core/Linker.cs +++ b/src/SVM.Assembler.Core/Linker.cs @@ -36,6 +36,7 @@ namespace SVM.Assembler.Core } } } + operationResult.Result = intermediateObject; return operationResult; } public static bool TryParseRegister(string input, LinkingContext context, out byte registerID) @@ -290,6 +291,7 @@ namespace SVM.Assembler.Core offset += (uint)data2.Length; Data.Add(data); } + Console.WriteLine($"Instruction Count:{Obj.instructions.Count}"); foreach (var item in Obj.instructions) { if (definition.InstructionDefinitions.TryGetValue(item.inst, out var def)) @@ -310,6 +312,7 @@ namespace SVM.Assembler.Core Buffer.BlockCopy(item, 0, program.Datas, offset2, item.Length); offset2 += item.Length; } + operationResult.Result = program; return operationResult; } } diff --git a/src/SVM.Assembler.Core/SVM.Assembler.Core.csproj b/src/SVM.Assembler.Core/SVM.Assembler.Core.csproj index a4a3d1f..17adff0 100644 --- a/src/SVM.Assembler.Core/SVM.Assembler.Core.csproj +++ b/src/SVM.Assembler.Core/SVM.Assembler.Core.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/SVM.Assembler/Program.cs b/src/SVM.Assembler/Program.cs index 65d8716..e205a7b 100644 --- a/src/SVM.Assembler/Program.cs +++ b/src/SVM.Assembler/Program.cs @@ -19,7 +19,70 @@ namespace SVM.Assembler Console.WriteLine("Cannot load ISA definition!"); return; } - Console.WriteLine(JsonConvert.SerializeObject(def, Formatting.Indented)); + List files = new List(); + List objs = new(); + string outputfile = "a.out"; + for (int i = 0; i < args.Length; i++) + { + string? item = args[i]; + switch (item) + { + case "-o": + outputfile = args[i + 1]; + i++; + break; + default: + if (File.Exists(item)) + { + files.Add(item); + continue; + } + break; + } + } + + foreach (var item in files) + { + Console.WriteLine(item); + } + Assembler.Core.Assembler assembler = new Core.Assembler(def); + foreach (var item in files) + { + var result = assembler.AssembleIntermediateObject(File.ReadAllText(item), item); + if (result.HasError()) + { + Console.Error.WriteLine($"Error at assembling {item}. Abort."); + return; + } + objs.Add(result.Result); + } + { + var lResult = Linker.Link(objs); + if (lResult.HasError()) + { + Console.Error.WriteLine("Linking error!"); + return; + } + if (lResult.Result == null) + { + Console.Error.WriteLine("Linker return no data!"); + return; + } + var fResult = Linker.Finialize(def, lResult.Result); + if (fResult.HasError()) + { + Console.Error.WriteLine("Finalizer error!"); + return; + } + if (fResult.Result == null) + { + Console.Error.WriteLine("Linker Finalizer return no data!"); + return; + } + if (File.Exists(outputfile)) File.Delete(outputfile); + using var stream = File.OpenWrite(outputfile); + fResult.Result.WriteToStream(stream); + } } } } diff --git a/src/SVM.Core/SVMProgram.cs b/src/SVM.Core/SVMProgram.cs index 13fe347..e7c6b2e 100644 --- a/src/SVM.Core/SVMProgram.cs +++ b/src/SVM.Core/SVMProgram.cs @@ -9,6 +9,17 @@ namespace SVM.Core { public List instructions = new List(); public byte[]? Datas; + public void WriteToStream(Stream stream) + { + stream.WriteData(Datas?.Length ?? 0); + stream.WriteData(instructions.Count); + if (Datas != null) + stream.Write(Datas); + foreach (SVMInstruction instruction in instructions) + { + stream.WriteData(instruction); + } + } } public unsafe struct SVMProgram : IDisposable { diff --git a/src/SVM.Core/Utils/StreamUtils.cs b/src/SVM.Core/Utils/StreamUtils.cs index 3551274..4bcded3 100644 --- a/src/SVM.Core/Utils/StreamUtils.cs +++ b/src/SVM.Core/Utils/StreamUtils.cs @@ -7,6 +7,12 @@ namespace SVM.Core.Utils { public static class StreamUtils { + public unsafe static void WriteData(this Stream s, T data) where T : unmanaged + { + var ptr=&data; + Span buffer = new(ptr, sizeof(T)); + s.Write(buffer); + } public unsafe static bool TryReadData(this Stream stream, out T data) where T : unmanaged { int len = sizeof(T);