Working on the assembler and linker.

This commit is contained in:
2025-07-20 03:35:04 +08:00
parent 48bf6bcc0f
commit bfec019c77
3 changed files with 146 additions and 9 deletions

View File

@@ -6,6 +6,7 @@ using System.Collections.Generic;
namespace SVM.Assembler.Core
{
public delegate OperationResult<IntermediateInstruction?> AssemblerFunction(ILexer lexer, IntermediateInstruction instruction, LexSegment leadingSegment);
public class Assembler
{
public const string LexDefinition =
@@ -54,6 +55,7 @@ LabelData InternalLbl
LabelConstant InternalLbl
";
LexerDefinition? definition;
public Dictionary<string, AssemblerFunction> assemblerFunctions = new Dictionary<string, AssemblerFunction>();
public Assembler()
{
if (LexerDefinition.TryParse(LexDefinition, out definition))
@@ -61,17 +63,73 @@ LabelConstant InternalLbl
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();
lexer.SetDefinition(definition);
lexer.Content = input;
lexer.SourceID = ID;
OperationResult<IntermediateObject> operationResult = new OperationResult<IntermediateObject>();
OperationResult<IntermediateObject> operationResult = new OperationResult<IntermediateObject>(new IntermediateObject());
InternalLabel CurrentLabel = InternalLabel.Code;
while (true)
{
var lexResult = lexer.Lex();
var lexResult = Lex(lexer);
if (lexResult.Result == null) break;
var r = lexResult.Result;
switch (r.LexSegmentId)
@@ -96,17 +154,47 @@ LabelConstant InternalLbl
switch (CurrentLabel)
{
case InternalLabel.Code:
switch (r.LexSegmentId)
{
case "GenericLabel":
break;
default:
break;
OperationResult<IntermediateInstruction?> instR = r.LexSegmentId switch
{
"GenericLabel" => ParseInstruction(lexer, r, r),
_ => ParseInstruction(lexer, r, null),
};
if (operationResult.CheckAndInheritErrorAndWarnings(instR))
{
return operationResult;
}
if (instR.Result is null) return operationResult;
operationResult.Result.instructions.Add(instR.Result);
}
break;
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;
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;
default:
break;
@@ -132,7 +220,7 @@ LabelConstant InternalLbl
[Serializable]
public class IntermediateInstruction
{
public string? Label = null;
public LexSegment? Label = null;
public PrimaryInstruction inst;
public List<LexSegment> Parameters = new List<LexSegment>();
}

View 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;
}
}
}

View File

@@ -1,9 +1,15 @@
using SVM.Core.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using static SVM.Core.stdc.stdlib;
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 UInt64 InstructionCount;