Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,4 @@ $RECYCLE.BIN/
*.swp

coveragereport/
*.csproj.lscache
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ The format is based on Keep a Changelog.

## [Unreleased]

## [2.0.1] - 2026-06-02

### Fix

- **Esolang.Interpreter.Abstractions** / **Esolang.Processor.Abstractions** / **Esolang.Processor.Extensions.IO** :
- add AOT compatibility settings for net10.0 target framework

## [2.0.0] - 2026-06-02

### Added
Expand All @@ -17,13 +24,16 @@ The format is based on Keep a Changelog.
- **Esolang.Generator.Abstractions**:
- Added comprehensive abstractions for method signature binding and type resolution.
- Introduced `MethodSignatureBinder` for mapping esolang source to C# partial methods.
- Added `KnownTypes` for standardized Roslyn type resolution.
- Added `BindingError` record hierarchy for type-safe diagnostic reporting.
- Added `MethodInputKind`, `MethodOutputKind`, and `MethodReturnKind` for signature classification.
- **Esolang.Interpreter.Abstractions**:
- Added new project for common interpreter utilities.
- Introduced `RunToConsoleAsync` extension method for running processors with standard console I/O.
- **Esolang.Processor.Extensions.IO**:
- Extracted and standardized I/O extension methods into a dedicated project.
- Added support for `TextReader`/`TextWriter`, `string`/`StringBuilder`, and `System.IO.Pipelines` (`PipeReader`/`PipeWriter`).
- Added `RunToEndAsync` overloads for `TextReader`/`TextWriter`, `string`/`StringBuilder`, and `PipeReader`/`PipeWriter`.
- Added `RunToStringAsync` for capturing output as a string.
- Enhanced testing infrastructure across all abstraction projects, significantly improving code coverage.

### Changed
Expand All @@ -45,6 +55,7 @@ The format is based on Keep a Changelog.
- Both text and pipe processors return exit codes (`int`) from execution.
- Support for optional `CancellationToken` on all execution methods.

[Unreleased]: https://github.com/Esolang-NET/Abstractions/compare/v2.0.0...HEAD
[Unreleased]: https://github.com/Esolang-NET/Abstractions/compare/v2.0.1...HEAD
[2.0.1]: https://github.com/Esolang-NET/Abstractions/tree/v2.0.1
[2.0.0]: https://github.com/Esolang-NET/Abstractions/tree/v2.0.0
[1.0.0]: https://github.com/Esolang-NET/Abstractions/tree/v1.0.0
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>14</LangVersion>
<AssemblyVersion>2.0.0.2</AssemblyVersion>
<FileVersion>2.0.0.2</FileVersion>
<Version>2.0.0</Version>
<FileVersion>2.0.1.2</FileVersion>
<Version>2.0.1</Version>
<PackageProjectUrl>https://github.com/Esolang-NET/Abstractions/</PackageProjectUrl>
<RepositoryUrl>https://github.com/Esolang-NET/Abstractions.git</RepositoryUrl>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand Down
8 changes: 8 additions & 0 deletions Generator.Abstractions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ This package provides common interfaces, types, and binder utilities for impleme

The `MethodSignatureBinder` is a core utility that facilitates mapping esolang source code to C# partial method signatures. It handles the identification of input, output, and return patterns to generate appropriate boilerplate.

### KnownTypes

The `KnownTypes` struct provides a standardized way to resolve and compare common esolang types (like `PipeReader`, `TextWriter`, etc.) within a Roslyn `Compilation`.

### Binding Kinds

To support diverse esolang execution models, several "Kind" enums are provided to classify method signatures:

- **MethodInputKind**: Classifies how the esolang receives input (e.g., `TextReader`, `PipeReader`, `byte[]`, or none).
- **MethodOutputKind**: Classifies how the esolang sends output (e.g., `TextWriter`, `PipeWriter`, `StringBuilder`, or none).
- **MethodReturnKind**: Determines the method's return pattern (e.g., `void`, `string`, `int`, `Task`, `IEnumerable`, `IAsyncEnumerable`).

### Diagnostic Handling

- **BindingError**: A type-safe record hierarchy representing diagnostic errors encountered during the binding process (e.g., `UnsupportedReturnType`, `DuplicateInput`, `ReturnOutputConflict`).
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageTags>esolang;interpreter;abstractions;interface;execution;runtime</PackageTags>
<RootNamespace>Esolang.Interpreter</RootNamespace>
<IsAotCompatible>true</IsAotCompatible>
<VerifyReferenceAotCompatibility>true</VerifyReferenceAotCompatibility>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 5 additions & 1 deletion Processor.Abstractions/Esolang.Processor.Abstractions.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1;net10.0</TargetFrameworks>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Description>Core interfaces and unified abstractions for esolang execution models, providing event-driven I/O processing standards.</Description>
Expand All @@ -10,6 +10,10 @@
<PackageTags>esolang;processor;abstractions;interface;execution;event-driven;io</PackageTags>
<RootNamespace>Esolang.Processor</RootNamespace>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'=='net10.0'">
<IsAotCompatible>true</IsAotCompatible>
<VerifyReferenceAotCompatibility>true</VerifyReferenceAotCompatibility>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Buffers" Version="4.6.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1;net10.0</TargetFrameworks>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Description>Comprehensive I/O extension methods for IEventProcessor, supporting TextReader/Writer, System.IO.Pipelines, and string-based execution.</Description>
Expand All @@ -11,6 +11,11 @@
<RootNamespace>Esolang.Processor.Extensions.IO</RootNamespace>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)'=='net10.0'">
<IsAotCompatible>true</IsAotCompatible>
<VerifyReferenceAotCompatibility>true</VerifyReferenceAotCompatibility>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Processor.Abstractions\Esolang.Processor.Abstractions.csproj" />
</ItemGroup>
Expand Down
42 changes: 40 additions & 2 deletions Processor.Extensions.IO/TextProcessorExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static async ValueTask<int> RunToEndAsync(
int read;
do
{
#if NETSTANDARD2_1_OR_GREATER
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
read = await input.ReadAsync(buffer.AsMemory(0, 1), cancellationToken).ConfigureAwait(false);
#else
read = await input.ReadAsync(buffer, 0, 1).ConfigureAwait(false);
Expand All @@ -57,7 +57,11 @@ public static async ValueTask<int> RunToEndAsync(
if (input is null)
throw new ArgumentNullException(nameof(input));
{
var inputString = await input.ReadLineAsync();
#if NET7_0_OR_GREATER
var inputString = await input.ReadLineAsync(cancellationToken).ConfigureAwait(false);
#else
var inputString = await input.ReadLineAsync().ConfigureAwait(false);
#endif
if (int.TryParse(inputString, out var i))
{
intInput.Write(i);
Expand All @@ -68,16 +72,50 @@ public static async ValueTask<int> RunToEndAsync(
if (output is null)
throw new ArgumentNullException(nameof(output));
{
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
var buffer =ArrayPool<char>.Shared.Rent(1);
buffer.AsSpan(0, 1)[0] = charOutput.Output;
try {
await output.WriteAsync(buffer.AsMemory(0, 1), cancellationToken).ConfigureAwait(false);
} finally
{
ArrayPool<char>.Shared.Return(buffer);
}
#else
await output.WriteAsync(charOutput.Output).ConfigureAwait(false);
#endif
#if NET8_0_OR_GREATER
await output.FlushAsync(cancellationToken).ConfigureAwait(false);
#else
await output.FlushAsync().ConfigureAwait(false);
#endif

}
break;
case OutputIntEvent intOutput:
if (output is null)
throw new ArgumentNullException(nameof(output));
{
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
var outputString = intOutput.Output.ToString();
var span = intOutput.Output.ToString().AsSpan();
var buffer =ArrayPool<char>.Shared.Rent(span.Length);
var memory = buffer.AsMemory(0, span.Length);
span.CopyTo(memory.Span);
try {
await output.WriteAsync(memory, cancellationToken).ConfigureAwait(false);
} finally
{
ArrayPool<char>.Shared.Return(buffer);
}
#else
await output.WriteAsync(intOutput.Output.ToString()).ConfigureAwait(false);
#endif
#if NET8_0_OR_GREATER
await output.FlushAsync(cancellationToken).ConfigureAwait(false);
#else
await output.FlushAsync().ConfigureAwait(false);
#endif
}
break;
case EndEvent endEvent:
Expand Down
Loading