mirror of
https://github.com/creeperlv/SVM.git
synced 2026-01-11 04:49:53 +00:00
Finished basic Assembler and Linker framework.
This commit is contained in:
@@ -6,7 +6,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace SVM.Assembler.Core
|
namespace SVM.Assembler.Core
|
||||||
{
|
{
|
||||||
public delegate OperationResult<IntermediateInstruction?> AssemblerFunction(ILexer lexer, IntermediateInstruction instruction, LexSegment leadingSegment);
|
public delegate OperationResult<SVMInstruction> LinkerFunction(LinkingContext context, IntermediateInstruction instruction);
|
||||||
public class Assembler
|
public class Assembler
|
||||||
{
|
{
|
||||||
public const string LexDefinition =
|
public const string LexDefinition =
|
||||||
@@ -55,13 +55,15 @@ LabelData InternalLbl
|
|||||||
LabelConstant InternalLbl
|
LabelConstant InternalLbl
|
||||||
";
|
";
|
||||||
LexerDefinition? definition;
|
LexerDefinition? definition;
|
||||||
public Dictionary<string, AssemblerFunction> assemblerFunctions = new Dictionary<string, AssemblerFunction>();
|
public ISADefinition ISA;
|
||||||
public Assembler()
|
public Assembler(ISADefinition isaDefinition)
|
||||||
{
|
{
|
||||||
if (LexerDefinition.TryParse(LexDefinition, out definition))
|
if (LexerDefinition.TryParse(LexDefinition, out definition))
|
||||||
{
|
{
|
||||||
definition.Substitute();
|
definition.Substitute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ISA = isaDefinition;
|
||||||
}
|
}
|
||||||
public OperationResult<LexSegment?> Lex(ILexer lexer)
|
public OperationResult<LexSegment?> Lex(ILexer lexer)
|
||||||
{
|
{
|
||||||
@@ -113,11 +115,32 @@ LabelConstant InternalLbl
|
|||||||
{
|
{
|
||||||
return operationResult;
|
return operationResult;
|
||||||
}
|
}
|
||||||
if (!assemblerFunctions.TryGetValue(LexDef.LexMatchedItemId, out var assemblerFunction))
|
if (!ISA.InstructionDefinitions.TryGetValue(LexDef.LexMatchedItemId, out var instructionDef))
|
||||||
{
|
{
|
||||||
return operationResult;
|
return operationResult;
|
||||||
}
|
}
|
||||||
return assemblerFunction(lexer, intermediateInstruction, LexDef);
|
foreach (var item in instructionDef.ParameterPattern)
|
||||||
|
{
|
||||||
|
var next = Lex(lexer);
|
||||||
|
if (operationResult.CheckAndInheritErrorAndWarnings(next))
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
if (next.Result is null)
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
if (next.Result.LexSegmentId is null)
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
if (!item.AllowedTokenIds.Contains(next.Result.LexSegmentId))
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
intermediateInstruction.Parameters.Add(next.Result);
|
||||||
|
}
|
||||||
|
return intermediateInstruction;
|
||||||
}
|
}
|
||||||
public OperationResult<IntermediateObject> AssembleIntermediateObject(string input, string ID = "main.asm")
|
public OperationResult<IntermediateObject> AssembleIntermediateObject(string input, string ID = "main.asm")
|
||||||
{
|
{
|
||||||
|
|||||||
21
src/SVM.Assembler.Core/ISADefinition.cs
Normal file
21
src/SVM.Assembler.Core/ISADefinition.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using SVM.Core;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SVM.Assembler.Core
|
||||||
|
{
|
||||||
|
public class ISADefinition
|
||||||
|
{
|
||||||
|
public Dictionary<string, InstructionDefinition> InstructionDefinitions = new Dictionary<string, InstructionDefinition>();
|
||||||
|
public Dictionary<PrimaryInstruction, LinkerFunction> LinkerFunctions = new Dictionary<PrimaryInstruction, LinkerFunction>();
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
foreach (var item in InstructionDefinitions)
|
||||||
|
{
|
||||||
|
if (!LinkerFunctions.TryAdd(item.Value.PrimaryInstruction, item.Value.linkerFunction))
|
||||||
|
{
|
||||||
|
LinkerFunctions[item.Value.PrimaryInstruction] = item.Value.linkerFunction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/SVM.Assembler.Core/InstructionDefinition.cs
Normal file
21
src/SVM.Assembler.Core/InstructionDefinition.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using SVM.Core;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SVM.Assembler.Core
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class InstructionDefinition
|
||||||
|
{
|
||||||
|
public string MatchID;
|
||||||
|
public PrimaryInstruction PrimaryInstruction;
|
||||||
|
public LinkerFunction linkerFunction;
|
||||||
|
public InstructionDefinition(string matchID, LinkerFunction assemblerFunction)
|
||||||
|
{
|
||||||
|
MatchID = matchID;
|
||||||
|
this.linkerFunction = assemblerFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<InstructionParameter> ParameterPattern = new List<InstructionParameter>();
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/SVM.Assembler.Core/InstructionParameter.cs
Normal file
9
src/SVM.Assembler.Core/InstructionParameter.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SVM.Assembler.Core
|
||||||
|
{
|
||||||
|
public class InstructionParameter
|
||||||
|
{
|
||||||
|
public List<string> AllowedTokenIds = new List<string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
using LibCLCC.NET.Operations;
|
using LibCLCC.NET.Operations;
|
||||||
using SVM.Core;
|
using SVM.Core;
|
||||||
|
using SVM.Core.Utils;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace SVM.Assembler.Core
|
namespace SVM.Assembler.Core
|
||||||
{
|
{
|
||||||
@@ -33,10 +37,46 @@ namespace SVM.Assembler.Core
|
|||||||
}
|
}
|
||||||
return operationResult;
|
return operationResult;
|
||||||
}
|
}
|
||||||
public static OperationResult<ManagedSVMProgram?> Freeze(List<IntermediateObject> objs)
|
public unsafe static OperationResult<ManagedSVMProgram?> Finialize(ISADefinition definition, IntermediateObject Obj)
|
||||||
{
|
{
|
||||||
OperationResult<ManagedSVMProgram?> operationResult = new OperationResult<ManagedSVMProgram?>(null);
|
OperationResult<ManagedSVMProgram?> operationResult = new OperationResult<ManagedSVMProgram?>(null);
|
||||||
|
ManagedSVMProgram program = new ManagedSVMProgram();
|
||||||
|
LinkingContext context = new LinkingContext(program, Obj);
|
||||||
|
List<byte[]> Data = new List<byte[]>();
|
||||||
|
uint offset = 0;
|
||||||
|
foreach (var item in Obj.data)
|
||||||
|
{
|
||||||
|
var data = Encoding.UTF8.GetBytes(item.Value);
|
||||||
|
byte[] data2 = new byte[data.Length + sizeof(int)];
|
||||||
|
fixed (byte* ptr = data2)
|
||||||
|
{
|
||||||
|
int len = data.Length;
|
||||||
|
((IntPtr)ptr).SetData(len);
|
||||||
|
}
|
||||||
|
Buffer.BlockCopy(data, 0, data2, sizeof(int), data.Length);
|
||||||
|
context.DataOffsets.Add(item.Key, offset);
|
||||||
|
offset += (uint)data2.Length;
|
||||||
|
Data.Add(data);
|
||||||
|
}
|
||||||
|
foreach (var item in Obj.instructions)
|
||||||
|
{
|
||||||
|
if (definition.LinkerFunctions.TryGetValue(item.inst, out var func))
|
||||||
|
{
|
||||||
|
var inst = func(context, item);
|
||||||
|
if (operationResult.CheckAndInheritErrorAndWarnings(inst))
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
program.instructions.Add(inst.Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
program.Datas = new byte[offset];
|
||||||
|
int offset2 = 0;
|
||||||
|
foreach (var item in Data)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(item, 0, program.Datas, offset2, item.Length);
|
||||||
|
offset2 += item.Length;
|
||||||
|
}
|
||||||
return operationResult;
|
return operationResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
38
src/SVM.Assembler.Core/LinkingContext.cs
Normal file
38
src/SVM.Assembler.Core/LinkingContext.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using SVM.Core;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SVM.Assembler.Core
|
||||||
|
{
|
||||||
|
public class LinkingContext
|
||||||
|
{
|
||||||
|
public Dictionary<string, uint> DataOffsets = new Dictionary<string, uint>();
|
||||||
|
public ManagedSVMProgram Program;
|
||||||
|
public Dictionary<string, int> label = new Dictionary<string, int>();
|
||||||
|
public IntermediateObject IntermediateObject;
|
||||||
|
public LinkingContext(ManagedSVMProgram program, IntermediateObject intermediateObject)
|
||||||
|
{
|
||||||
|
Program = program;
|
||||||
|
IntermediateObject = intermediateObject;
|
||||||
|
}
|
||||||
|
public bool TryFindLabel(string label, out int offset)
|
||||||
|
{
|
||||||
|
label = label + ":";
|
||||||
|
if (this.label.TryGetValue(label, out offset))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < IntermediateObject.instructions.Count; i++)
|
||||||
|
{
|
||||||
|
IntermediateInstruction? item = IntermediateObject.instructions[i];
|
||||||
|
if (item.Label != null)
|
||||||
|
if (item.Label.Content == label)
|
||||||
|
{
|
||||||
|
this.label.Add(label, i);
|
||||||
|
offset = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace SVM.Core
|
|||||||
public unsafe class ManagedSVMProgram
|
public unsafe class ManagedSVMProgram
|
||||||
{
|
{
|
||||||
public List<SVMInstruction> instructions = new List<SVMInstruction>();
|
public List<SVMInstruction> instructions = new List<SVMInstruction>();
|
||||||
public List<byte> Datas = new List<byte>();
|
public byte[]? Datas;
|
||||||
}
|
}
|
||||||
public unsafe struct SVMProgram : IDisposable
|
public unsafe struct SVMProgram : IDisposable
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,5 +41,10 @@ namespace SVM.Core.Utils
|
|||||||
{
|
{
|
||||||
GetDataWithOffsetInStructCount<T>(ptr, (IntPtr)dest, offset);
|
GetDataWithOffsetInStructCount<T>(ptr, (IntPtr)dest, offset);
|
||||||
}
|
}
|
||||||
|
public static void SetData<T>(this IntPtr ptr, T data) where T : unmanaged
|
||||||
|
{
|
||||||
|
var srcPtr = (byte*)&data;
|
||||||
|
Buffer.MemoryCopy(srcPtr, (byte*)ptr, sizeof(T), sizeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user