Skip to content

Commit

Permalink
Draft: Выделение поддоменов (#72)
Browse files Browse the repository at this point in the history
* #31 - IAbstractSyntaxTreeNode.cs

* #31 - tree internal

* #31 - separate ast from backend

* #31 - segment

* #31 - separate ast from backend 2

* #31 - value dto converter

* #31 - удалил Type из TypeValue

* #31 - fix test

* #31 - symbol contracts

* #31 - tuple -> dto

* #31 - End is property

* mv

* #31 - backend mv

* #31 - backend subdomain

* #31 - scope dto for ast

* #31 - rename

* #31 - rename

* #31 - ISymbolTable -> Scope

* #31 - SymbolTableStorage.cs

* #31 - fix bug

* #31 - remove IR from codegen
  • Loading branch information
Stepami authored Jul 27, 2024
1 parent ca57c69 commit 396bf92
Show file tree
Hide file tree
Showing 138 changed files with 1,203 additions and 982 deletions.
21 changes: 10 additions & 11 deletions src/HydraScript.Lib/BackEnd/AddressedInstructions.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
using System.Collections;
using HydraScript.Lib.BackEnd.Addresses;
using HydraScript.Lib.BackEnd.Instructions;
using HydraScript.Lib.BackEnd.Impl.Addresses;

namespace HydraScript.Lib.BackEnd;

public class AddressedInstructions : IEnumerable<Instruction>
public class AddressedInstructions : IEnumerable<IExecutableInstruction>
{
private readonly LinkedList<IAddress> _addresses = new();
private readonly Dictionary<IAddress, LinkedListNode<IAddress>> _addressToNode = new();
private readonly Dictionary<LinkedListNode<IAddress>, Instruction> _instructions = new();
private readonly Dictionary<LinkedListNode<IAddress>, IExecutableInstruction> _instructions = new();

public Instruction this[IAddress address]
public IExecutableInstruction this[IAddress address]
{
get => _instructions[_addressToNode[address]];
private set => _instructions[_addressToNode[address]] = value;
Expand All @@ -22,7 +21,7 @@ public Instruction this[IAddress address]
public IAddress End =>
_addresses.Last?.Value!;

public void Add(Instruction instruction, string? label = null)
public void Add(IExecutableInstruction instruction, string? label = null)
{
IAddress newAddress = label is null
? new HashAddress(seed: instruction.GetHashCode())
Expand All @@ -32,15 +31,15 @@ public void Add(Instruction instruction, string? label = null)
AddWithAddress(instruction, newAddress);
}

public void Replace(Instruction old, Instruction @new)
public void Replace(IExecutableInstruction old, IExecutableInstruction @new)
{
var address = old.Address;
@new.Address = address;

this[address] = @new;
}

private void AddWithAddress(Instruction instruction, IAddress newAddress)
private void AddWithAddress(IExecutableInstruction instruction, IAddress newAddress)
{
var last = _addresses.Last;
if (last is not null)
Expand All @@ -52,13 +51,13 @@ private void AddWithAddress(Instruction instruction, IAddress newAddress)
_instructions.Add(newNode, instruction);
}

public void AddRange(IEnumerable<Instruction> instructions)
public void AddRange(IEnumerable<IExecutableInstruction> instructions)
{
foreach (var instruction in instructions)
AddWithAddress(instruction, instruction.Address);
}

public void Remove(Instruction instruction)
public void Remove(IExecutableInstruction instruction)
{
var address = instruction.Address;
var nodeToRemove = _addressToNode[address];
Expand All @@ -74,7 +73,7 @@ public void Remove(Instruction instruction)
_addresses.Remove(nodeToRemove);
}

public IEnumerator<Instruction> GetEnumerator() =>
public IEnumerator<IExecutableInstruction> GetEnumerator() =>
_addresses.Select(address => this[address])
.GetEnumerator();

Expand Down
20 changes: 20 additions & 0 deletions src/HydraScript.Lib/BackEnd/Call.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using HydraScript.Lib.BackEnd.Impl.Addresses;

namespace HydraScript.Lib.BackEnd;

public record Call(
IAddress From,
FunctionInfo To,
string? Where = null)
{
public override string ToString() =>
$"{From}: {Where} => {To.Start}: {To.Id}";
}

public record FunctionInfo(string Id)
{
public Label Start => new($"Start_{this}");
public Label End => new($"End_{this}");

public override string ToString() => Id;
}
16 changes: 16 additions & 0 deletions src/HydraScript.Lib/BackEnd/Frame.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace HydraScript.Lib.BackEnd;

public class Frame(IAddress returnAddress, Frame? parentFrame = null)
{
private readonly Dictionary<string, object?> _variables = new();

public IAddress ReturnAddress { get; } = returnAddress;

public object? this[string id]
{
get => _variables.TryGetValue(id, out var value)
? value
: parentFrame?[id];
set => _variables[id] = value;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace HydraScript.Lib.BackEnd.Addresses;
namespace HydraScript.Lib.BackEnd;

public interface IAddress : IEquatable<IAddress>
{
Expand Down
8 changes: 8 additions & 0 deletions src/HydraScript.Lib/BackEnd/IExecutableInstruction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace HydraScript.Lib.BackEnd;

public interface IExecutableInstruction
{
public IAddress Address { get; set; }
public IAddress Execute(IExecuteParams executeParams);
public bool End { get; }
}
9 changes: 9 additions & 0 deletions src/HydraScript.Lib/BackEnd/IExecuteParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace HydraScript.Lib.BackEnd;

public interface IExecuteParams
{
public Stack<Call> CallStack { get; }
public Stack<Frame> Frames { get; }
public Queue<object?> Arguments { get; }
public TextWriter Writer { get; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace HydraScript.Lib.BackEnd.Values;
namespace HydraScript.Lib.BackEnd;

public interface IValue : IEquatable<IValue>
{
Expand Down
7 changes: 7 additions & 0 deletions src/HydraScript.Lib/BackEnd/IVirtualMachine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace HydraScript.Lib.BackEnd;

public interface IVirtualMachine
{
public IExecuteParams ExecuteParams { get; }
public void Run(AddressedInstructions instructions);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace HydraScript.Lib.BackEnd.Addresses;
namespace HydraScript.Lib.BackEnd.Impl.Addresses;

public class HashAddress(int seed) : IAddress
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace HydraScript.Lib.BackEnd.Addresses;
namespace HydraScript.Lib.BackEnd.Impl.Addresses;

public class Label(string name) : IAddress
{
Expand Down
9 changes: 9 additions & 0 deletions src/HydraScript.Lib/BackEnd/Impl/ExecuteParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace HydraScript.Lib.BackEnd.Impl;

public class ExecuteParams(TextWriter textWriter) : IExecuteParams
{
public Stack<Call> CallStack { get; } = new();
public Stack<Frame> Frames { get; } = new();
public Queue<object?> Arguments { get; } = new();
public TextWriter Writer { get; } = textWriter;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using HydraScript.Lib.BackEnd.Addresses;

namespace HydraScript.Lib.BackEnd.Instructions;
namespace HydraScript.Lib.BackEnd.Impl.Instructions;

public abstract class BlockLabel : Instruction
{
Expand All @@ -15,7 +13,7 @@ protected BlockLabel(BlockPosition blockPosition, BlockType blockType, string bl
_blockId = blockId;
}

public override IAddress Execute(VirtualMachine vm) =>
public override IAddress Execute(IExecuteParams executeParams) =>
Address.Next;

protected override string ToStringInternal() =>
Expand Down
16 changes: 16 additions & 0 deletions src/HydraScript.Lib/BackEnd/Impl/Instructions/Halt.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using HydraScript.Lib.BackEnd.Impl.Addresses;

namespace HydraScript.Lib.BackEnd.Impl.Instructions;

public class Halt : Instruction
{
public override bool End => true;

public override IAddress Execute(IExecuteParams executeParams)
{
executeParams.Frames.Pop();
return new HashAddress(seed: 0);
}

protected override string ToStringInternal() => "End";
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using HydraScript.Lib.BackEnd.Addresses;
namespace HydraScript.Lib.BackEnd.Impl.Instructions;

namespace HydraScript.Lib.BackEnd.Instructions;

public abstract class Instruction
public abstract class Instruction : IExecutableInstruction
{
private IAddress _address = default!;

Expand All @@ -18,9 +16,9 @@ public IAddress Address

protected virtual void OnSetOfAddress(IAddress address) { }

public abstract IAddress Execute(VirtualMachine vm);
public abstract IAddress Execute(IExecuteParams executeParams);

public virtual bool End() => false;
public virtual bool End => false;

protected abstract string ToStringInternal();

Expand Down
14 changes: 14 additions & 0 deletions src/HydraScript.Lib/BackEnd/Impl/Instructions/PopParameter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace HydraScript.Lib.BackEnd.Impl.Instructions;

public class PopParameter(string parameter) : Instruction
{
public override IAddress Execute(IExecuteParams executeParams)
{
var argument = executeParams.Arguments.Dequeue();
executeParams.Frames.Peek()[parameter] = argument;
return Address.Next;
}

protected override string ToStringInternal() =>
$"PopParameter {parameter}";
}
13 changes: 13 additions & 0 deletions src/HydraScript.Lib/BackEnd/Impl/Instructions/Print.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace HydraScript.Lib.BackEnd.Impl.Instructions;

public class Print(IValue value) : Instruction
{
public override IAddress Execute(IExecuteParams executeParams)
{
executeParams.Writer.WriteLine(value.Get(executeParams.Frames.Peek()));
return Address.Next;
}

protected override string ToStringInternal() =>
$"Print {value}";
}
14 changes: 14 additions & 0 deletions src/HydraScript.Lib/BackEnd/Impl/Instructions/PushParameter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace HydraScript.Lib.BackEnd.Impl.Instructions;

public class PushParameter(IValue value) : Instruction
{
public override IAddress Execute(IExecuteParams executeParams)
{
executeParams.Arguments.Enqueue(
value.Get(executeParams.Frames.Peek()));
return Address.Next;
}

protected override string ToStringInternal() =>
$"PushParameter {value}";
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
using HydraScript.Lib.BackEnd.Addresses;
using HydraScript.Lib.BackEnd.Values;

namespace HydraScript.Lib.BackEnd.Instructions;
namespace HydraScript.Lib.BackEnd.Impl.Instructions;

public class RemoveFromArray(string id, IValue index) : Instruction
{
public override IAddress Execute(VirtualMachine vm)
public override IAddress Execute(IExecuteParams executeParams)
{
var frame = vm.Frames.Peek();
var frame = executeParams.Frames.Peek();
if (frame[id] is List<object> list)
{
list.RemoveAt(Convert.ToInt32(index.Get(frame)));
Expand Down
19 changes: 19 additions & 0 deletions src/HydraScript.Lib/BackEnd/Impl/Instructions/Return.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace HydraScript.Lib.BackEnd.Impl.Instructions;

public class Return(IValue? value = null) : Instruction
{
public override IAddress Execute(IExecuteParams executeParams)
{
var frame = executeParams.Frames.Pop();
var call = executeParams.CallStack.Pop();
if (call.Where != null && value != null)
{
executeParams.Frames.Peek()[call.Where] = value.Get(frame);
}

return frame.ReturnAddress;
}

protected override string ToStringInternal() =>
$"Return{(value != null ? $" {value}" : "")}";
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using HydraScript.Lib.BackEnd.Addresses;
using HydraScript.Lib.BackEnd.Values;

namespace HydraScript.Lib.BackEnd.Instructions.WithAssignment;
namespace HydraScript.Lib.BackEnd.Impl.Instructions.WithAssignment;

public class AsString(IValue value) : Simple(value)
{
public override IAddress Execute(VirtualMachine vm)
public override IAddress Execute(IExecuteParams executeParams)
{
var frame = vm.Frames.Peek();
var frame = executeParams.Frames.Peek();
frame[Left!] = JsonSerializer.Serialize(
Right.right!.Get(frame),
new JsonSerializerOptions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace HydraScript.Lib.BackEnd.Impl.Instructions.WithAssignment;

public class CallFunction(
FunctionInfo function,
bool hasReturnValue) : Simple(null, (null, null), "Call ")
{
protected override void OnSetOfAddress(IAddress address)
{
if (hasReturnValue)
base.OnSetOfAddress(address);
}

public override IAddress Execute(IExecuteParams executeParams)
{
var frame = new Frame(Address.Next, executeParams.Frames.Peek());
executeParams.CallStack.Push(new Call(Address, function, Left));
executeParams.Frames.Push(frame);
return function.Start;
}

protected override string ToStringInternal() => Left == null
? $"Call {function}"
: $"{Left} = Call {function}";
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
using HydraScript.Lib.BackEnd.Addresses;

namespace HydraScript.Lib.BackEnd.Instructions.WithAssignment.ComplexData.Create;
namespace HydraScript.Lib.BackEnd.Impl.Instructions.WithAssignment.ComplexData.Create;

public class CreateArray(string id, int size) : Simple(id)
{
private readonly string _id = id;

public override IAddress Execute(VirtualMachine vm)
public override IAddress Execute(IExecuteParams executeParams)
{
var frame = vm.Frames.Peek();
var frame = executeParams.Frames.Peek();
frame[_id] = new object[size].ToList();
return Address.Next;
}
Expand Down
Loading

0 comments on commit 396bf92

Please sign in to comment.