mirror of
https://github.com/creeperlv/SVM.git
synced 2026-01-11 12:59:54 +00:00
Working on the assembler and linker.
This commit is contained in:
@@ -6,6 +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 class Assembler
|
public class Assembler
|
||||||
{
|
{
|
||||||
public const string LexDefinition =
|
public const string LexDefinition =
|
||||||
@@ -54,6 +55,7 @@ LabelData InternalLbl
|
|||||||
LabelConstant InternalLbl
|
LabelConstant InternalLbl
|
||||||
";
|
";
|
||||||
LexerDefinition? definition;
|
LexerDefinition? definition;
|
||||||
|
public Dictionary<string, AssemblerFunction> assemblerFunctions = new Dictionary<string, AssemblerFunction>();
|
||||||
public Assembler()
|
public Assembler()
|
||||||
{
|
{
|
||||||
if (LexerDefinition.TryParse(LexDefinition, out definition))
|
if (LexerDefinition.TryParse(LexDefinition, out definition))
|
||||||
@@ -61,17 +63,73 @@ LabelConstant InternalLbl
|
|||||||
definition.Substitute();
|
definition.Substitute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public OperationResult<IntermediateObject> Assemble(string input, string ID = "main.asm")
|
public OperationResult<LexSegment?> Lex(ILexer lexer)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var r = lexer.Lex();
|
||||||
|
if (r.HasError()) return r;
|
||||||
|
if (r.Result == null) return r;
|
||||||
|
if (r.Result.LexSegmentId != null && r.Result.LexMatchedItemId != null)
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public OperationResult<(string, string)?> ParseKVPair(ILexer lexer, LexSegment currentSeg)
|
||||||
|
{
|
||||||
|
OperationResult<(string, string)?> operationResult = new OperationResult<(string, string)?>(null);
|
||||||
|
var r = Lex(lexer);
|
||||||
|
if (operationResult.CheckAndInheritErrorAndWarnings(r)) { return operationResult; }
|
||||||
|
if (currentSeg.Content == null) return operationResult;
|
||||||
|
if (r.Result == null) return operationResult;
|
||||||
|
if (r.Result.Content == null) return operationResult;
|
||||||
|
return (currentSeg.Content, r.Result.Content);
|
||||||
|
}
|
||||||
|
private OperationResult<IntermediateInstruction?> ParseInstruction(StringLexer lexer, LexSegment CurrentSeg, LexSegment? Label)
|
||||||
|
{
|
||||||
|
OperationResult<IntermediateInstruction?> operationResult = new OperationResult<IntermediateInstruction?>(null);
|
||||||
|
IntermediateInstruction intermediateInstruction = new IntermediateInstruction();
|
||||||
|
intermediateInstruction.Label = Label;
|
||||||
|
LexSegment LexDef;
|
||||||
|
if (Label is null)
|
||||||
|
{
|
||||||
|
LexDef = CurrentSeg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var next = Lex(lexer);
|
||||||
|
if (operationResult.CheckAndInheritErrorAndWarnings(next))
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
if (next.Result is null)
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
LexDef = next.Result;
|
||||||
|
}
|
||||||
|
if (LexDef.LexMatchedItemId == null)
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
if (!assemblerFunctions.TryGetValue(LexDef.LexMatchedItemId, out var assemblerFunction))
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
return assemblerFunction(lexer, intermediateInstruction, LexDef);
|
||||||
|
}
|
||||||
|
public OperationResult<IntermediateObject> AssembleIntermediateObject(string input, string ID = "main.asm")
|
||||||
{
|
{
|
||||||
StringLexer lexer = new StringLexer();
|
StringLexer lexer = new StringLexer();
|
||||||
lexer.SetDefinition(definition);
|
lexer.SetDefinition(definition);
|
||||||
lexer.Content = input;
|
lexer.Content = input;
|
||||||
lexer.SourceID = ID;
|
lexer.SourceID = ID;
|
||||||
OperationResult<IntermediateObject> operationResult = new OperationResult<IntermediateObject>();
|
OperationResult<IntermediateObject> operationResult = new OperationResult<IntermediateObject>(new IntermediateObject());
|
||||||
InternalLabel CurrentLabel = InternalLabel.Code;
|
InternalLabel CurrentLabel = InternalLabel.Code;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var lexResult = lexer.Lex();
|
var lexResult = Lex(lexer);
|
||||||
if (lexResult.Result == null) break;
|
if (lexResult.Result == null) break;
|
||||||
var r = lexResult.Result;
|
var r = lexResult.Result;
|
||||||
switch (r.LexSegmentId)
|
switch (r.LexSegmentId)
|
||||||
@@ -96,17 +154,47 @@ LabelConstant InternalLbl
|
|||||||
switch (CurrentLabel)
|
switch (CurrentLabel)
|
||||||
{
|
{
|
||||||
case InternalLabel.Code:
|
case InternalLabel.Code:
|
||||||
switch (r.LexSegmentId)
|
|
||||||
{
|
{
|
||||||
case "GenericLabel":
|
OperationResult<IntermediateInstruction?> instR = r.LexSegmentId switch
|
||||||
break;
|
{
|
||||||
default:
|
"GenericLabel" => ParseInstruction(lexer, r, r),
|
||||||
break;
|
_ => ParseInstruction(lexer, r, null),
|
||||||
|
};
|
||||||
|
if (operationResult.CheckAndInheritErrorAndWarnings(instR))
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
if (instR.Result is null) return operationResult;
|
||||||
|
operationResult.Result.instructions.Add(instR.Result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InternalLabel.Data:
|
case InternalLabel.Data:
|
||||||
|
{
|
||||||
|
var KV = ParseKVPair(lexer, r);
|
||||||
|
if (operationResult.CheckAndInheritErrorAndWarnings(KV))
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
if (KV.Result == null)
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
operationResult.Result.data.Add(KV.Result.Value.Item1, KV.Result.Value.Item2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case InternalLabel.Const:
|
case InternalLabel.Const:
|
||||||
|
{
|
||||||
|
var KV = ParseKVPair(lexer, r);
|
||||||
|
if (operationResult.CheckAndInheritErrorAndWarnings(KV))
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
if (KV.Result == null)
|
||||||
|
{
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
operationResult.Result.consts.Add(KV.Result.Value.Item1, KV.Result.Value.Item2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -132,7 +220,7 @@ LabelConstant InternalLbl
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
public class IntermediateInstruction
|
public class IntermediateInstruction
|
||||||
{
|
{
|
||||||
public string? Label = null;
|
public LexSegment? Label = null;
|
||||||
public PrimaryInstruction inst;
|
public PrimaryInstruction inst;
|
||||||
public List<LexSegment> Parameters = new List<LexSegment>();
|
public List<LexSegment> Parameters = new List<LexSegment>();
|
||||||
}
|
}
|
||||||
|
|||||||
43
src/SVM.Assembler.Core/Linker.cs
Normal file
43
src/SVM.Assembler.Core/Linker.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using LibCLCC.NET.Operations;
|
||||||
|
using SVM.Core;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SVM.Assembler.Core
|
||||||
|
{
|
||||||
|
public class Linker
|
||||||
|
{
|
||||||
|
public static OperationResult<IntermediateObject?> Link(List<IntermediateObject> objs)
|
||||||
|
{
|
||||||
|
OperationResult<IntermediateObject?> operationResult = new OperationResult<IntermediateObject?>(null);
|
||||||
|
IntermediateObject intermediateObject = new IntermediateObject();
|
||||||
|
foreach (var item in objs)
|
||||||
|
{
|
||||||
|
foreach (var inst in item.instructions)
|
||||||
|
{
|
||||||
|
intermediateObject.instructions.Add(inst);
|
||||||
|
}
|
||||||
|
foreach (var data in item.data)
|
||||||
|
{
|
||||||
|
if (!intermediateObject.data.TryAdd(data.Key, data.Value))
|
||||||
|
{
|
||||||
|
intermediateObject.data[data.Key] = data.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var kv in item.consts)
|
||||||
|
{
|
||||||
|
if (!intermediateObject.consts.TryAdd(kv.Key, kv.Value))
|
||||||
|
{
|
||||||
|
intermediateObject.consts[kv.Key] = kv.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
public static OperationResult<ManagedSVMProgram?> Freeze(List<IntermediateObject> objs)
|
||||||
|
{
|
||||||
|
OperationResult<ManagedSVMProgram?> operationResult = new OperationResult<ManagedSVMProgram?>(null);
|
||||||
|
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
using SVM.Core.Utils;
|
using SVM.Core.Utils;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using static SVM.Core.stdc.stdlib;
|
using static SVM.Core.stdc.stdlib;
|
||||||
namespace SVM.Core
|
namespace SVM.Core
|
||||||
{
|
{
|
||||||
|
public unsafe class ManagedSVMProgram
|
||||||
|
{
|
||||||
|
public List<SVMInstruction> instructions = new List<SVMInstruction>();
|
||||||
|
public List<byte> Datas = new List<byte>();
|
||||||
|
}
|
||||||
public unsafe struct SVMProgram : IDisposable
|
public unsafe struct SVMProgram : IDisposable
|
||||||
{
|
{
|
||||||
public UInt64 InstructionCount;
|
public UInt64 InstructionCount;
|
||||||
|
|||||||
Reference in New Issue
Block a user