diff --git a/.gitignore b/.gitignore index e7bd4192..c468fc76 100644 --- a/.gitignore +++ b/.gitignore @@ -398,3 +398,4 @@ FodyWeavers.xsd *.sln.iml .lh/ +/ZSharpTest/test.zs diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f8332ffb..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "python.analysis.extraPaths": [ - "${workspaceFolder}/zsharp-miniz", - "${workspaceFolder}/zsharp-lang", - "${workspaceFolder}/zsharp-runtime", - "${workspaceFolder}/zsharp-text", - "${workspaceFolder}/zsharp-vm", - ], - "python.analysis.exclude": [ - "${workspaceFolder}/miniz", - ] -} \ No newline at end of file diff --git a/CommonZ/CommonZ.csproj b/CommonZ/CommonZ.csproj index 30402ac0..0d2df0d1 100644 --- a/CommonZ/CommonZ.csproj +++ b/CommonZ/CommonZ.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable diff --git a/CommonZ/IResult.cs b/CommonZ/IResult.cs new file mode 100644 index 00000000..b76bb0e6 --- /dev/null +++ b/CommonZ/IResult.cs @@ -0,0 +1,32 @@ +public interface IResult + where TResult : class? + where TError : class +{ + public bool IsOk { get; } + + public bool IsError { get; } + + public TResult Unwrap(); + + public TError UnwrapError(); + + public IResult When(Action action) + { + if (this.Ok(out var result)) + action(result); + + return this; + } + + public IResult When(Func map) where R : class; + + public IResult Else(Action action) + { + if (this.Error(out var error)) + action(error); + + return this; + } + + public IResult Else(Func map) where E : class; +} \ No newline at end of file diff --git a/CommonZ/Result.cs b/CommonZ/Result.cs new file mode 100644 index 00000000..6bbe56ad --- /dev/null +++ b/CommonZ/Result.cs @@ -0,0 +1,47 @@ +using System.Diagnostics.CodeAnalysis; + +namespace CommonZ +{ + public sealed class Result + : IResult + where TResult : class? + where TError : class + { + private readonly TResult? result; + private readonly TError? error; + + [MemberNotNullWhen(true, nameof(result))] + public bool IsOk => result is not null; + + [MemberNotNullWhen(true, nameof(error))] + public bool IsError => error is not null; + + private Result(TResult? result, TError? error) + { + this.result = result; + this.error = error; + } + + public static Result Ok(TResult result) + => new(result, null); + + public static Result Error(TError error) + => new(null, error); + + TResult IResult.Unwrap() + => result ?? throw new InvalidOperationException(error!.ToString()); + + TError IResult.UnwrapError() + => error ?? throw new InvalidOperationException("Result is Ok"); + + IResult IResult.When(Func map) + => IsOk + ? Result.Ok(map(result)) + : Result.Error(error!); + + IResult IResult.Else(Func map) + => IsOk + ? Result.Ok(result) + : Result.Error(map(error!)); + } +} diff --git a/CommonZ/collections/CacheBase.cs b/CommonZ/collections/CacheBase.cs index 30ec9a42..a33ab80a 100644 --- a/CommonZ/collections/CacheBase.cs +++ b/CommonZ/collections/CacheBase.cs @@ -12,10 +12,13 @@ public abstract class CacheBase public Cache? Parent { get; set; } - public T Cache(Key key, T value) + public T Cache(Key key, T value, bool set = false) where T : Value { - _cache.Add(key, value); + if (set) + _cache[key] = value; + else + _cache.Add(key, value); return value; } diff --git a/CommonZ/collections/Mapping.cs b/CommonZ/collections/Mapping.cs index 32c12345..15065108 100644 --- a/CommonZ/collections/Mapping.cs +++ b/CommonZ/collections/Mapping.cs @@ -3,6 +3,12 @@ public class Mapping : Dictionary where Key : notnull { + public Mapping() : base() { } + + public Mapping(IDictionary dictionary) : base(dictionary) { } + + public Mapping(IEnumerable> items) : base(items) { } + public virtual void OnAdd(Key key, Value value) { } public virtual void OnRemove(Key key) { } diff --git a/CommonZ/extensions/IResultExtensions.cs b/CommonZ/extensions/IResultExtensions.cs new file mode 100644 index 00000000..7e829d1a --- /dev/null +++ b/CommonZ/extensions/IResultExtensions.cs @@ -0,0 +1,70 @@ +using CommonZ; +using System.Diagnostics.CodeAnalysis; +using static System.Runtime.InteropServices.JavaScript.JSType; + +public static class IResultExtensions +{ + public static bool Ok( + this IResult result, + [NotNullWhen(true)] out TResult? output + ) + where TResult : class? + where TError : class + => (output = result.IsOk ? result.Unwrap() : null) is not null; + + public static bool Error( + this IResult result, + [NotNullWhen(true)] out TError? error + ) + where TResult : class? + where TError : class + => (error = result.IsError ? result.UnwrapError() : null) is not null; + + public static IResult When( + this IResult result, + out TResult? output + ) + where TResult : class? + where TError : class + { + output = result.IsOk ? result.Unwrap() : null; + return result; + } + + public static IResult Else( + this IResult result, + out TError? error + ) + where TResult : class? + where TError : class + { + error = result.IsError ? result.UnwrapError() : null; + return result; + } + + public static IResult When( + this IResult result, + Func> map + ) + where TResult : class? + where TError : class + where R : class + { + if (result.IsError) return result.When(_ => (null as R)!); + + return map(result.Unwrap()).Else(e => e); + } + + //public static IResult Else( + // this IResult result, + // Action action + //) + // where TResult : class? + // where TError : class + //{ + // if (result.IsError) + // action(result.UnwrapError()); + + // return result; + //} +} \ No newline at end of file diff --git a/Examples/test.zs b/Examples/test.zs new file mode 100644 index 00000000..76652afa --- /dev/null +++ b/Examples/test.zs @@ -0,0 +1,28 @@ +import { print } from "std:io"; +import { Void, Test } from "std:types"; + +print("[CT] Hello, World!"); + +import { Directory } from "std:fs"; + +import { CompilerObject } from "core:compiler"; + +module A { + print("[CT] Inside module A"); + + fun main(): Void { + print(Directory.cwd().toString()); + print(Test(Directory.cwd().toString())); + + print("[RT] Hello, World!"); + return; + } +} + +if (false) { + print("[CT] Condition is true"); +} else { + print("[CT] Condition is false"); +} + +A.main(); diff --git a/README.md b/README.md index b82e3881..34b1a6f6 100644 --- a/README.md +++ b/README.md @@ -1,76 +1,15 @@ # Z# Language -Welcome to the Z# language repository! This repository holds the first released version of Z#. - -Z# is a typesafe, interpreterd language. It is still very much a WIP so don't expect it to work smoothly. - -The current state of the project is: -* [x] Tokenizer -* [x] Parser -* [x] Resolver -* [x] Compiler -* [x] IR Layer -* [x] ZSRuntime -* [ ] Platform Compiler - -## Structure - -The whole compiler is separated to multiple modules, each with a different purpose. +> This README file is out-of-date. I will update this once I have enough time and an acceptable working version. +> If you have any questions regarding this project, you can join the discord server ~~[discord server](https://discord.gg/Uc3GN2bfG9)~~ [discord channel on PLTD](https://discord.gg/jkCSRvpyYA). -To understand the architecture of the compiler, one needs to understand the architecture of the language. -The language is interpreted and it allows using statements in top-level scopes (e.g. document, module, etc..). -Also, it is typesafe. The compiler creates an IR of the code and the interpreter holds a runtime representation of the IR. - -The IR defines a static structure, while the runtime objects can vary during execution. - -## Running - -Simply run the main project (ZSharpTest). - -You can edit the [`test.zs`](ZSharpTest/test.zs) file. +Welcome to the Z# language repository! This repository holds the first released version of Z#. -## ToDo +Z# is a typesafe, interpreterd language. It is still very much a WIP so don't expect it to work smoothly. -* [ ] Add support for type-inference - - [x] Local inference - - [ ] Function return type -* [ ] Implement the overloading protocol (C#) -* [ ] Implement the `compile` protocol (both `IRObject` and `IR Type`) (C#, Z#) -* [ ] Implement better Z# RT VM API (C#) - - [x] Function calls - - [ ] Object construction, instantiation and initialization - - [x] IR loading -* [x] Organize IR loading in Z# RT VM (C#) -* [ ] Implement document-level definitions - - [ ] Functions - - [ ] Globals -* [ ] Implement OOP types - - [ ] Class - - [ ] Interface - - [ ] Typeclass - - [ ] Structure -* [ ] Add support for decorators -* [ ] Add support for custom attributes -* [ ] Implement the CG `Execute`/`Evaluate` command. -* [ ] Implement the `import(string)` CG function (C#) - - [ ] Add support for extensible `StringImporter` -* [ ] Add support for definition templates - - [ ] Functions - - [ ] Classes (which includes methods, properties, fields, etc..) -* [x] Fix module references lookup code (consider the fact that IR have 2 sources: `Read` and `EvaluateType`). - - > The way this works is by analyzing each function code right after the body is compiled. -* [ ] ZSharp.Compiler project - - [ ] IR Generator - - [ ] Generators - - [ ] Document - - [ ] Function Body - - [ ] Module - - [ ] OOP Types - - [ ] Method Body +This repository is undergoing massive rewrites and the architecture is still under development. +Due to that, contributions are currently not accepted. -## ToDo (High Level) -* [ ] C# Interop with Z# (C# Reflection -> IR) -* [ ] Add more language features -* [ ] Fully implement the IR -> CG loader +However, suggestions about everything (syntax, concepts, architecture, etc..) are always welcome. diff --git a/Testing/Program.cs b/Testing/Program.cs new file mode 100644 index 00000000..89ce8628 --- /dev/null +++ b/Testing/Program.cs @@ -0,0 +1,45 @@ +using ZSharp.Importer.ILLoader; +using Objects = ZSharp.Importer.ILLoader.Objects; + +var rtm = ZSharp.IR.RuntimeModule.Standard; +var coc = new ZSharp.Compiler.Compiler(rtm); +var rt = new ZSharp.Platform.Runtime.Runtime(new() +{ + Array = rtm.TypeSystem.Array, + Boolean = rtm.TypeSystem.Boolean, + Char = null!, + Float16 = null!, + Float32 = rtm.TypeSystem.Float32, + Float64 = null!, + Float128 = null!, + Object = rtm.TypeSystem.Object, + Pointer = rtm.TypeSystem.Pointer, + Reference = rtm.TypeSystem.Reference, + SInt8 = null!, + SInt16 = null!, + SInt32 = rtm.TypeSystem.Int32, + SInt64 = null!, + SIntNative = null!, + String = rtm.TypeSystem.String, + UInt8 = null!, + UInt16 = null!, + UInt32 = null!, + UInt64 = null!, + UIntNative = null!, + Void = rtm.TypeSystem.Void +}); + +var ilLoader = new ILLoader(coc, rt); + +coc.TS.SInt32 = ilLoader.TypeSystem.SInt32; + +var code = rt.Expose("Hello, Exposed String!"); +var exposed = rt.Evaluate(code, rtm.TypeSystem.Object); +System.Console.WriteLine(exposed); + +var typedCode = ilLoader.ExposeAsIR(12); +var typedExposed = rt.Evaluate(typedCode, rtm.TypeSystem.Int32); +System.Console.WriteLine(typedExposed); + + +System.Console.WriteLine(string.Empty); diff --git a/Testing/Testing.csproj b/Testing/Testing.csproj new file mode 100644 index 00000000..4f8e16a7 --- /dev/null +++ b/Testing/Testing.csproj @@ -0,0 +1,14 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + diff --git a/ZSharp v1.sln b/ZSharp v1.sln index a58e1513..adb6d31b 100644 --- a/ZSharp v1.sln +++ b/ZSharp v1.sln @@ -9,38 +9,81 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharp.AST", "ZSharp.AST\ZS EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharp.Text", "ZSharp.Text\ZSharp.Text.csproj", "{E81AC1F8-9CED-4E6E-B1F2-A9E66A1EBF63}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharpTest", "ZSharpTest\ZSharpTest.csproj", "{F89D890B-AC10-4CC1-A07D-E54CE0115F54}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharp.IR", "ZSharp.IR\ZSharp.IR.csproj", "{A6987B24-D697-4F9F-9615-9BE8641065A8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharp.Compiler", "ZSharp.Compiler\ZSharp.Compiler.csproj", "{678634DE-CD65-4020-AB16-CCC77E013299}" - ProjectSection(ProjectDependencies) = postProject - {50A7F0CE-AFEE-418E-89E3-96F41D45BF8A} = {50A7F0CE-AFEE-418E-89E3-96F41D45BF8A} - EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharp.Tokenizer", "ZSharp.Tokenizer\ZSharp.Tokenizer.csproj", "{2A7DE2EA-2347-465B-AFC4-62F46B380F30}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharpTokenizerTest", "ZSharpTokenizerTest\ZSharpTokenizerTest.csproj", "{DFE6B315-DF3D-4EE9-990C-068404AB9F83}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharp.Parser", "ZSharp.Parser\ZSharp.Parser.csproj", "{8523CD79-8272-4331-A49F-947B0269A42D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharpParserTest", "ZSharpParserTest\ZSharpParserTest.csproj", "{0DC3D462-5240-4670-A5C2-04FCD7093F2E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Interpreter", "ZSharp.Interpreter\ZSharp.Interpreter.csproj", "{F46A91F5-47BA-468A-81F0-FF6BCEB4112C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharp.CT.StandardLibrary", "ZSharp.CT.StandardLibrary\ZSharp.CT.StandardLibrary.csproj", "{7FCC6EEC-12BC-409C-93A9-0A4AF7B8E83B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Library.Standard.Math", "ZSharp.Library.Standard.Math\ZSharp.Library.Standard.Math.csproj", "{AF9E7F68-2AB3-42F7-AE29-5D7A1CE89DBA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZSharp.ZSSourceCompiler", "ZSharp.ZSSourceCompiler\ZSharp.ZSSourceCompiler.csproj", "{5864E449-5E21-426C-9FA5-39BE15B4A0E0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.Features", "ZSharp.Compiler.Features\ZSharp.Compiler.Features.csproj", "{E3DAA459-48D0-461E-A17E-453816D15090}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Interpreter", "ZSharp.Interpreter\ZSharp.Interpreter.csproj", "{F46A91F5-47BA-468A-81F0-FF6BCEB4112C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testing", "Testing\Testing.csproj", "{8A5EB8BE-EDF3-444E-AC15-A3E9DEF1FC7F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Library.Standard.FileSystem", "ZSharp.Library.Standard.FileSystem\ZSharp.Library.Standard.FileSystem.csproj", "{7E9F2ABB-373C-40BF-8D62-CBDD64DA8E36}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Platform.IL", "ZSharp.Platform.IL\ZSharp.Platform.IL.csproj", "{2222D3B2-0148-4AAC-955C-679E7F20C2FA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Importer.ILLoader", "ZSharp.Importer.ILLoader\ZSharp.Importer.ILLoader.csproj", "{980FAC95-52E8-499D-96A9-943EE4861EA0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Platform.Runtime", "ZSharp.Platform.Runtime\ZSharp.Platform.Runtime.csproj", "{3CD28041-00F7-4A40-BEFD-4F77809BCBF7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.IR", "ZSharp.Compiler.IR\ZSharp.Compiler.IR.csproj", "{B3E3E076-4B77-433F-9466-D0A0D8D9EAFA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.SourceCompiler.Project", "ZSharp.SourceCompiler.Project\ZSharp.SourceCompiler.Project.csproj", "{FBDD6EA4-FA23-47B3-8A41-538AE2EA575E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Importer.ILLoader.Attributes", "ZSharp.Importer.ILLoader.Attributes\ZSharp.Importer.ILLoader.Attributes.csproj", "{42BF3911-0DC7-4831-A989-98D48C17CC74}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.SourceCompiler.Core", "ZSharp.SourceCompiler.Core\ZSharp.SourceCompiler.Core.csproj", "{2DF6ABEC-5B49-435D-A583-4C97C61D1558}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.SourceCompiler.Module", "ZSharp.SourceCompiler.Module\ZSharp.SourceCompiler.Module.csproj", "{5C914B09-68BF-4BCD-BF9E-2F682F03590D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.SourceCompiler.Script", "ZSharp.SourceCompiler.Script\ZSharp.SourceCompiler.Script.csproj", "{51F7D757-1DBC-452B-84FF-45307ADCDF5C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.CLI", "ZSharp.CLI\ZSharp.CLI.csproj", "{4DA26E46-B765-4A8C-BAE1-5E99D6138DAF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.Core", "ZSharp.Compiler.Core\ZSharp.Compiler.Core.csproj", "{F5CCD8B1-98F4-151B-C4FA-6E651CEC6193}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Logging", "ZSharp.Logging\ZSharp.Logging.csproj", "{EF96A6E6-190B-457B-AD9C-1057CD7EDBB2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.TS", "ZSharp.Compiler.TS\ZSharp.Compiler.TS.csproj", "{1864BBD1-5A3D-4FB1-B799-B736C5016191}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.TS.Static", "ZSharp.Compiler.TS.Static\ZSharp.Compiler.TS.Static.csproj", "{C6FC0FBB-6E0B-437B-82B7-294D830109EA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.Context", "ZSharp.Compiler.Context\ZSharp.Compiler.Context.csproj", "{B2DD7DE5-8D23-4BA8-9AC6-808BF8FFF3CA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.SourceCompiler.Common", "ZSharp.SourceCompiler.Common\ZSharp.SourceCompiler.Common.csproj", "{A3DB8E19-9047-4FF6-87E7-69BDC09647D1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Library.Standard.IO", "ZSharp.Library.Standard.IO\ZSharp.Library.Standard.IO.csproj", "{8BD20BCF-DC47-4B94-B40E-1A6B7137265C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.Overloading", "ZSharp.Compiler.Overloading\ZSharp.Compiler.Overloading.csproj", "{51026F8A-3101-41C7-BDD0-9275FE436410}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.CG", "ZSharp.Compiler.CG\ZSharp.Compiler.CG.csproj", "{5653B9BD-331E-C526-0DA7-BD8CB9C9274C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.CG.Direct", "ZSharp.Compiler.CG.Direct\ZSharp.Compiler.CG.Direct.csproj", "{4C08CAB6-8668-5DC7-96F5-0335E6AEF680}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.CG.Proxy", "ZSharp.Compiler.CG.Proxy\ZSharp.Compiler.CG.Proxy.csproj", "{708FB37D-DCFE-2FEB-DADE-F5C80ACDE10F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.CG.Typed", "ZSharp.Compiler.CG.Typed\ZSharp.Compiler.CG.Typed.csproj", "{62E6B22B-2057-8EFC-30D4-B6F497FEF9D8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.Reflection", "ZSharp.Compiler.Reflection\ZSharp.Compiler.Reflection.csproj", "{0B9B763F-D6DA-4D29-B810-7A4CADF152DB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.IR.Static", "ZSharp.Compiler.IR.Static\ZSharp.Compiler.IR.Static.csproj", "{D4B62927-75B2-4147-8B63-1154BA1AB9CE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.IRLoader", "ZSharp.Compiler.IRLoader\ZSharp.Compiler.IRLoader.csproj", "{8E9A7EF0-EE8E-4481-BF60-C6BDBD5C7BB8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.Evaluation", "ZSharp.Compiler.Evaluation\ZSharp.Compiler.Evaluation.csproj", "{C8474D6A-5A65-4D39-AA23-A9EBF8A405AC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.CT.CompilerAPI", "ZSharp.CT.CompilerAPI\ZSharp.CT.CompilerAPI.csproj", "{7A85DEFF-0453-4252-8FFB-C8365AA84615}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Importer.RT", "ZSharp.Importer.RT\ZSharp.Importer.RT.csproj", "{2C743056-A568-443E-B659-5B6731CD9B24}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.CT.RuntimeAPI", "ZSharp.CT.RuntimeAPI\ZSharp.CT.RuntimeAPI.csproj", "{360265D8-8811-4A25-9060-AD9B9D334D8C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Library.Core.Compiler", "ZSharp.Library.Core.Compiler\ZSharp.Library.Core.Compiler.csproj", "{820EF0D4-C0F7-468A-A2A5-70A7EF64FF8A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Runtime.IL", "ZSharp.Runtime.IL\ZSharp.Runtime.IL.csproj", "{A3937E93-8537-4251-AF60-7DB8ECE0D99C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.Evaluation.Direct", "ZSharp.Compiler.Evaluation.Direct\ZSharp.Compiler.Evaluation.Direct.csproj", "{12BA2B1B-FC9D-4C8C-8D0B-265248CE992D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.CT.StandardLibrary.Math", "ZSharp.CT.StandardLibrary.Math\ZSharp.CT.StandardLibrary.Math.csproj", "{AF9E7F68-2AB3-42F7-AE29-5D7A1CE89DBA}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZSharp.Compiler.Evaluation.IR", "ZSharp.Compiler.Evaluation.IR\ZSharp.Compiler.Evaluation.IR.csproj", "{D409F69A-8459-7B08-E513-7235D92D8EA0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -60,10 +103,6 @@ Global {E81AC1F8-9CED-4E6E-B1F2-A9E66A1EBF63}.Debug|Any CPU.Build.0 = Debug|Any CPU {E81AC1F8-9CED-4E6E-B1F2-A9E66A1EBF63}.Release|Any CPU.ActiveCfg = Release|Any CPU {E81AC1F8-9CED-4E6E-B1F2-A9E66A1EBF63}.Release|Any CPU.Build.0 = Release|Any CPU - {F89D890B-AC10-4CC1-A07D-E54CE0115F54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F89D890B-AC10-4CC1-A07D-E54CE0115F54}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F89D890B-AC10-4CC1-A07D-E54CE0115F54}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F89D890B-AC10-4CC1-A07D-E54CE0115F54}.Release|Any CPU.Build.0 = Release|Any CPU {A6987B24-D697-4F9F-9615-9BE8641065A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A6987B24-D697-4F9F-9615-9BE8641065A8}.Debug|Any CPU.Build.0 = Debug|Any CPU {A6987B24-D697-4F9F-9615-9BE8641065A8}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -76,50 +115,146 @@ Global {2A7DE2EA-2347-465B-AFC4-62F46B380F30}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A7DE2EA-2347-465B-AFC4-62F46B380F30}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A7DE2EA-2347-465B-AFC4-62F46B380F30}.Release|Any CPU.Build.0 = Release|Any CPU - {DFE6B315-DF3D-4EE9-990C-068404AB9F83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DFE6B315-DF3D-4EE9-990C-068404AB9F83}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DFE6B315-DF3D-4EE9-990C-068404AB9F83}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DFE6B315-DF3D-4EE9-990C-068404AB9F83}.Release|Any CPU.Build.0 = Release|Any CPU {8523CD79-8272-4331-A49F-947B0269A42D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8523CD79-8272-4331-A49F-947B0269A42D}.Debug|Any CPU.Build.0 = Debug|Any CPU {8523CD79-8272-4331-A49F-947B0269A42D}.Release|Any CPU.ActiveCfg = Release|Any CPU {8523CD79-8272-4331-A49F-947B0269A42D}.Release|Any CPU.Build.0 = Release|Any CPU - {0DC3D462-5240-4670-A5C2-04FCD7093F2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0DC3D462-5240-4670-A5C2-04FCD7093F2E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0DC3D462-5240-4670-A5C2-04FCD7093F2E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0DC3D462-5240-4670-A5C2-04FCD7093F2E}.Release|Any CPU.Build.0 = Release|Any CPU - {7FCC6EEC-12BC-409C-93A9-0A4AF7B8E83B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7FCC6EEC-12BC-409C-93A9-0A4AF7B8E83B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7FCC6EEC-12BC-409C-93A9-0A4AF7B8E83B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7FCC6EEC-12BC-409C-93A9-0A4AF7B8E83B}.Release|Any CPU.Build.0 = Release|Any CPU - {5864E449-5E21-426C-9FA5-39BE15B4A0E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5864E449-5E21-426C-9FA5-39BE15B4A0E0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5864E449-5E21-426C-9FA5-39BE15B4A0E0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5864E449-5E21-426C-9FA5-39BE15B4A0E0}.Release|Any CPU.Build.0 = Release|Any CPU {F46A91F5-47BA-468A-81F0-FF6BCEB4112C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F46A91F5-47BA-468A-81F0-FF6BCEB4112C}.Debug|Any CPU.Build.0 = Debug|Any CPU {F46A91F5-47BA-468A-81F0-FF6BCEB4112C}.Release|Any CPU.ActiveCfg = Release|Any CPU {F46A91F5-47BA-468A-81F0-FF6BCEB4112C}.Release|Any CPU.Build.0 = Release|Any CPU - {8E9A7EF0-EE8E-4481-BF60-C6BDBD5C7BB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8E9A7EF0-EE8E-4481-BF60-C6BDBD5C7BB8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8E9A7EF0-EE8E-4481-BF60-C6BDBD5C7BB8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8E9A7EF0-EE8E-4481-BF60-C6BDBD5C7BB8}.Release|Any CPU.Build.0 = Release|Any CPU - {7A85DEFF-0453-4252-8FFB-C8365AA84615}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7A85DEFF-0453-4252-8FFB-C8365AA84615}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7A85DEFF-0453-4252-8FFB-C8365AA84615}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7A85DEFF-0453-4252-8FFB-C8365AA84615}.Release|Any CPU.Build.0 = Release|Any CPU - {360265D8-8811-4A25-9060-AD9B9D334D8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {360265D8-8811-4A25-9060-AD9B9D334D8C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {360265D8-8811-4A25-9060-AD9B9D334D8C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {360265D8-8811-4A25-9060-AD9B9D334D8C}.Release|Any CPU.Build.0 = Release|Any CPU - {A3937E93-8537-4251-AF60-7DB8ECE0D99C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A3937E93-8537-4251-AF60-7DB8ECE0D99C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A3937E93-8537-4251-AF60-7DB8ECE0D99C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A3937E93-8537-4251-AF60-7DB8ECE0D99C}.Release|Any CPU.Build.0 = Release|Any CPU {AF9E7F68-2AB3-42F7-AE29-5D7A1CE89DBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AF9E7F68-2AB3-42F7-AE29-5D7A1CE89DBA}.Debug|Any CPU.Build.0 = Debug|Any CPU {AF9E7F68-2AB3-42F7-AE29-5D7A1CE89DBA}.Release|Any CPU.ActiveCfg = Release|Any CPU {AF9E7F68-2AB3-42F7-AE29-5D7A1CE89DBA}.Release|Any CPU.Build.0 = Release|Any CPU + {E3DAA459-48D0-461E-A17E-453816D15090}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E3DAA459-48D0-461E-A17E-453816D15090}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E3DAA459-48D0-461E-A17E-453816D15090}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E3DAA459-48D0-461E-A17E-453816D15090}.Release|Any CPU.Build.0 = Release|Any CPU + {8A5EB8BE-EDF3-444E-AC15-A3E9DEF1FC7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A5EB8BE-EDF3-444E-AC15-A3E9DEF1FC7F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A5EB8BE-EDF3-444E-AC15-A3E9DEF1FC7F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A5EB8BE-EDF3-444E-AC15-A3E9DEF1FC7F}.Release|Any CPU.Build.0 = Release|Any CPU + {7E9F2ABB-373C-40BF-8D62-CBDD64DA8E36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E9F2ABB-373C-40BF-8D62-CBDD64DA8E36}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E9F2ABB-373C-40BF-8D62-CBDD64DA8E36}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E9F2ABB-373C-40BF-8D62-CBDD64DA8E36}.Release|Any CPU.Build.0 = Release|Any CPU + {2222D3B2-0148-4AAC-955C-679E7F20C2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2222D3B2-0148-4AAC-955C-679E7F20C2FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2222D3B2-0148-4AAC-955C-679E7F20C2FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2222D3B2-0148-4AAC-955C-679E7F20C2FA}.Release|Any CPU.Build.0 = Release|Any CPU + {980FAC95-52E8-499D-96A9-943EE4861EA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {980FAC95-52E8-499D-96A9-943EE4861EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {980FAC95-52E8-499D-96A9-943EE4861EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {980FAC95-52E8-499D-96A9-943EE4861EA0}.Release|Any CPU.Build.0 = Release|Any CPU + {3CD28041-00F7-4A40-BEFD-4F77809BCBF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3CD28041-00F7-4A40-BEFD-4F77809BCBF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3CD28041-00F7-4A40-BEFD-4F77809BCBF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3CD28041-00F7-4A40-BEFD-4F77809BCBF7}.Release|Any CPU.Build.0 = Release|Any CPU + {B3E3E076-4B77-433F-9466-D0A0D8D9EAFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3E3E076-4B77-433F-9466-D0A0D8D9EAFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3E3E076-4B77-433F-9466-D0A0D8D9EAFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3E3E076-4B77-433F-9466-D0A0D8D9EAFA}.Release|Any CPU.Build.0 = Release|Any CPU + {FBDD6EA4-FA23-47B3-8A41-538AE2EA575E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FBDD6EA4-FA23-47B3-8A41-538AE2EA575E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FBDD6EA4-FA23-47B3-8A41-538AE2EA575E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FBDD6EA4-FA23-47B3-8A41-538AE2EA575E}.Release|Any CPU.Build.0 = Release|Any CPU + {42BF3911-0DC7-4831-A989-98D48C17CC74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42BF3911-0DC7-4831-A989-98D48C17CC74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42BF3911-0DC7-4831-A989-98D48C17CC74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42BF3911-0DC7-4831-A989-98D48C17CC74}.Release|Any CPU.Build.0 = Release|Any CPU + {2DF6ABEC-5B49-435D-A583-4C97C61D1558}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2DF6ABEC-5B49-435D-A583-4C97C61D1558}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2DF6ABEC-5B49-435D-A583-4C97C61D1558}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2DF6ABEC-5B49-435D-A583-4C97C61D1558}.Release|Any CPU.Build.0 = Release|Any CPU + {5C914B09-68BF-4BCD-BF9E-2F682F03590D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5C914B09-68BF-4BCD-BF9E-2F682F03590D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5C914B09-68BF-4BCD-BF9E-2F682F03590D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5C914B09-68BF-4BCD-BF9E-2F682F03590D}.Release|Any CPU.Build.0 = Release|Any CPU + {51F7D757-1DBC-452B-84FF-45307ADCDF5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51F7D757-1DBC-452B-84FF-45307ADCDF5C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51F7D757-1DBC-452B-84FF-45307ADCDF5C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51F7D757-1DBC-452B-84FF-45307ADCDF5C}.Release|Any CPU.Build.0 = Release|Any CPU + {4DA26E46-B765-4A8C-BAE1-5E99D6138DAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4DA26E46-B765-4A8C-BAE1-5E99D6138DAF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4DA26E46-B765-4A8C-BAE1-5E99D6138DAF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4DA26E46-B765-4A8C-BAE1-5E99D6138DAF}.Release|Any CPU.Build.0 = Release|Any CPU + {F5CCD8B1-98F4-151B-C4FA-6E651CEC6193}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5CCD8B1-98F4-151B-C4FA-6E651CEC6193}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5CCD8B1-98F4-151B-C4FA-6E651CEC6193}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5CCD8B1-98F4-151B-C4FA-6E651CEC6193}.Release|Any CPU.Build.0 = Release|Any CPU + {EF96A6E6-190B-457B-AD9C-1057CD7EDBB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF96A6E6-190B-457B-AD9C-1057CD7EDBB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF96A6E6-190B-457B-AD9C-1057CD7EDBB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF96A6E6-190B-457B-AD9C-1057CD7EDBB2}.Release|Any CPU.Build.0 = Release|Any CPU + {1864BBD1-5A3D-4FB1-B799-B736C5016191}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1864BBD1-5A3D-4FB1-B799-B736C5016191}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1864BBD1-5A3D-4FB1-B799-B736C5016191}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1864BBD1-5A3D-4FB1-B799-B736C5016191}.Release|Any CPU.Build.0 = Release|Any CPU + {C6FC0FBB-6E0B-437B-82B7-294D830109EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6FC0FBB-6E0B-437B-82B7-294D830109EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6FC0FBB-6E0B-437B-82B7-294D830109EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6FC0FBB-6E0B-437B-82B7-294D830109EA}.Release|Any CPU.Build.0 = Release|Any CPU + {B2DD7DE5-8D23-4BA8-9AC6-808BF8FFF3CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2DD7DE5-8D23-4BA8-9AC6-808BF8FFF3CA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2DD7DE5-8D23-4BA8-9AC6-808BF8FFF3CA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2DD7DE5-8D23-4BA8-9AC6-808BF8FFF3CA}.Release|Any CPU.Build.0 = Release|Any CPU + {A3DB8E19-9047-4FF6-87E7-69BDC09647D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3DB8E19-9047-4FF6-87E7-69BDC09647D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3DB8E19-9047-4FF6-87E7-69BDC09647D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3DB8E19-9047-4FF6-87E7-69BDC09647D1}.Release|Any CPU.Build.0 = Release|Any CPU + {8BD20BCF-DC47-4B94-B40E-1A6B7137265C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8BD20BCF-DC47-4B94-B40E-1A6B7137265C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8BD20BCF-DC47-4B94-B40E-1A6B7137265C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8BD20BCF-DC47-4B94-B40E-1A6B7137265C}.Release|Any CPU.Build.0 = Release|Any CPU + {51026F8A-3101-41C7-BDD0-9275FE436410}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51026F8A-3101-41C7-BDD0-9275FE436410}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51026F8A-3101-41C7-BDD0-9275FE436410}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51026F8A-3101-41C7-BDD0-9275FE436410}.Release|Any CPU.Build.0 = Release|Any CPU + {5653B9BD-331E-C526-0DA7-BD8CB9C9274C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5653B9BD-331E-C526-0DA7-BD8CB9C9274C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5653B9BD-331E-C526-0DA7-BD8CB9C9274C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5653B9BD-331E-C526-0DA7-BD8CB9C9274C}.Release|Any CPU.Build.0 = Release|Any CPU + {4C08CAB6-8668-5DC7-96F5-0335E6AEF680}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C08CAB6-8668-5DC7-96F5-0335E6AEF680}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C08CAB6-8668-5DC7-96F5-0335E6AEF680}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C08CAB6-8668-5DC7-96F5-0335E6AEF680}.Release|Any CPU.Build.0 = Release|Any CPU + {708FB37D-DCFE-2FEB-DADE-F5C80ACDE10F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {708FB37D-DCFE-2FEB-DADE-F5C80ACDE10F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {708FB37D-DCFE-2FEB-DADE-F5C80ACDE10F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {708FB37D-DCFE-2FEB-DADE-F5C80ACDE10F}.Release|Any CPU.Build.0 = Release|Any CPU + {62E6B22B-2057-8EFC-30D4-B6F497FEF9D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62E6B22B-2057-8EFC-30D4-B6F497FEF9D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62E6B22B-2057-8EFC-30D4-B6F497FEF9D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62E6B22B-2057-8EFC-30D4-B6F497FEF9D8}.Release|Any CPU.Build.0 = Release|Any CPU + {0B9B763F-D6DA-4D29-B810-7A4CADF152DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B9B763F-D6DA-4D29-B810-7A4CADF152DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B9B763F-D6DA-4D29-B810-7A4CADF152DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B9B763F-D6DA-4D29-B810-7A4CADF152DB}.Release|Any CPU.Build.0 = Release|Any CPU + {D4B62927-75B2-4147-8B63-1154BA1AB9CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4B62927-75B2-4147-8B63-1154BA1AB9CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4B62927-75B2-4147-8B63-1154BA1AB9CE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4B62927-75B2-4147-8B63-1154BA1AB9CE}.Release|Any CPU.Build.0 = Release|Any CPU + {C8474D6A-5A65-4D39-AA23-A9EBF8A405AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8474D6A-5A65-4D39-AA23-A9EBF8A405AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8474D6A-5A65-4D39-AA23-A9EBF8A405AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8474D6A-5A65-4D39-AA23-A9EBF8A405AC}.Release|Any CPU.Build.0 = Release|Any CPU + {2C743056-A568-443E-B659-5B6731CD9B24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C743056-A568-443E-B659-5B6731CD9B24}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C743056-A568-443E-B659-5B6731CD9B24}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C743056-A568-443E-B659-5B6731CD9B24}.Release|Any CPU.Build.0 = Release|Any CPU + {820EF0D4-C0F7-468A-A2A5-70A7EF64FF8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {820EF0D4-C0F7-468A-A2A5-70A7EF64FF8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {820EF0D4-C0F7-468A-A2A5-70A7EF64FF8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {820EF0D4-C0F7-468A-A2A5-70A7EF64FF8A}.Release|Any CPU.Build.0 = Release|Any CPU + {12BA2B1B-FC9D-4C8C-8D0B-265248CE992D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12BA2B1B-FC9D-4C8C-8D0B-265248CE992D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12BA2B1B-FC9D-4C8C-8D0B-265248CE992D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12BA2B1B-FC9D-4C8C-8D0B-265248CE992D}.Release|Any CPU.Build.0 = Release|Any CPU + {D409F69A-8459-7B08-E513-7235D92D8EA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D409F69A-8459-7B08-E513-7235D92D8EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D409F69A-8459-7B08-E513-7235D92D8EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D409F69A-8459-7B08-E513-7235D92D8EA0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ZSharp.AST/ZSharp.AST.csproj b/ZSharp.AST/ZSharp.AST.csproj index 02f17bce..a11d0188 100644 --- a/ZSharp.AST/ZSharp.AST.csproj +++ b/ZSharp.AST/ZSharp.AST.csproj @@ -1,17 +1,13 @@ - net8.0 + net9.0 enable enable - - - - - + diff --git a/ZSharp.AST/nodes/def/module/Module.cs b/ZSharp.AST/nodes/def/module/Module.cs index 938a9f8e..0a2ca899 100644 --- a/ZSharp.AST/nodes/def/module/Module.cs +++ b/ZSharp.AST/nodes/def/module/Module.cs @@ -1,7 +1,13 @@ namespace ZSharp.AST { - public sealed class Module : Expression + public sealed class Module(ModuleTokens tokens) : Expression(tokens) { + public new ModuleTokens TokenInfo + { + get => As(); + init => base.TokenInfo = value; + } + public List Body { get; set; } = []; public required string Name { get; set; } diff --git a/ZSharp.AST/nodes/def/module/ModuleTokens.cs b/ZSharp.AST/nodes/def/module/ModuleTokens.cs new file mode 100644 index 00000000..a7e7e418 --- /dev/null +++ b/ZSharp.AST/nodes/def/module/ModuleTokens.cs @@ -0,0 +1,11 @@ +using ZSharp.Text; + +namespace ZSharp.AST +{ + public sealed class ModuleTokens : TokenInfo + { + public Token ModuleKeyword { get; init; } + + public Token Name { get; init; } + } +} diff --git a/ZSharp.AST/nodes/def/oop/Constructor.cs b/ZSharp.AST/nodes/def/oop/Constructor.cs index 9255c23f..6612c455 100644 --- a/ZSharp.AST/nodes/def/oop/Constructor.cs +++ b/ZSharp.AST/nodes/def/oop/Constructor.cs @@ -1,7 +1,13 @@ namespace ZSharp.AST { - public sealed class Constructor : Statement + public sealed class Constructor(ConstructorTokens tokens) : Expression(tokens) { + public new ConstructorTokens TokenInfo + { + get => As(); + init => base.TokenInfo = value; + } + public string? Name { get; set; } public required Signature Signature { get; set; } diff --git a/ZSharp.AST/nodes/def/oop/ConstructorTokens.cs b/ZSharp.AST/nodes/def/oop/ConstructorTokens.cs new file mode 100644 index 00000000..00b89159 --- /dev/null +++ b/ZSharp.AST/nodes/def/oop/ConstructorTokens.cs @@ -0,0 +1,11 @@ +using ZSharp.Text; + +namespace ZSharp.AST +{ + public sealed class ConstructorTokens : TokenInfo + { + public Token NewKeyword { get; init; } + + public Token? Name { get; init; } + } +} diff --git a/ZSharp.AST/nodes/def/oop/OOPDefinition.cs b/ZSharp.AST/nodes/def/oop/OOPDefinition.cs index c3427e08..62803624 100644 --- a/ZSharp.AST/nodes/def/oop/OOPDefinition.cs +++ b/ZSharp.AST/nodes/def/oop/OOPDefinition.cs @@ -1,7 +1,13 @@ namespace ZSharp.AST { - public class OOPDefinition : Expression + public class OOPDefinition(OOPDefinitionTokens tokens) : Expression(tokens) { + public new OOPDefinitionTokens TokenInfo + { + get => As(); + init => base.TokenInfo = value; + } + public required string Type { get; set; } public string Name { get; set; } = string.Empty; diff --git a/ZSharp.AST/nodes/def/oop/OOPDefinitionTokens.cs b/ZSharp.AST/nodes/def/oop/OOPDefinitionTokens.cs new file mode 100644 index 00000000..c3bb5568 --- /dev/null +++ b/ZSharp.AST/nodes/def/oop/OOPDefinitionTokens.cs @@ -0,0 +1,15 @@ +using ZSharp.Text; + +namespace ZSharp.AST +{ + public sealed class OOPDefinitionTokens : TokenInfo + { + public Token Type { get; init; } + + public Token? Name { get; init; } + + public Token? OfKeyword { get; init; } + + public Token? BasesSeparator { get; init; } + } +} diff --git a/ZSharp.AST/nodes/expr/call/IndexExpression.cs b/ZSharp.AST/nodes/expr/call/IndexExpression.cs new file mode 100644 index 00000000..6ee83498 --- /dev/null +++ b/ZSharp.AST/nodes/expr/call/IndexExpression.cs @@ -0,0 +1,9 @@ +namespace ZSharp.AST +{ + public sealed class IndexExpression : Expression + { + public required Expression Target { get; set; } + + public List Arguments { get; set; } = []; + } +} diff --git a/ZSharp.AST/nodes/expr/cast/CastExpression.cs b/ZSharp.AST/nodes/expr/cast/CastExpression.cs new file mode 100644 index 00000000..bfa48063 --- /dev/null +++ b/ZSharp.AST/nodes/expr/cast/CastExpression.cs @@ -0,0 +1,9 @@ +namespace ZSharp.AST +{ + public sealed class CastExpression : Expression + { + public required Expression Expression { get; set; } + + public required Expression TargetType { get; set; } + } +} diff --git a/ZSharp.AST/nodes/expr/cast/IsOfExpression.cs b/ZSharp.AST/nodes/expr/cast/IsOfExpression.cs new file mode 100644 index 00000000..f0353392 --- /dev/null +++ b/ZSharp.AST/nodes/expr/cast/IsOfExpression.cs @@ -0,0 +1,11 @@ +namespace ZSharp.AST +{ + public sealed class IsOfExpression : Expression + { + public required Expression Expression { get; set; } + + public string? Name { get; set; } + + public required Expression OfType { get; set; } + } +} diff --git a/ZSharp.AST/nodes/expr/flow/WhileExpression.cs b/ZSharp.AST/nodes/expr/flow/WhileExpression.cs index fed026a1..04dfc0b6 100644 --- a/ZSharp.AST/nodes/expr/flow/WhileExpression.cs +++ b/ZSharp.AST/nodes/expr/flow/WhileExpression.cs @@ -1,6 +1,7 @@ namespace ZSharp.AST { - public sealed class WhileExpression : Expression + public sealed class WhileExpression : Expression + where TElse : Node { public required Expression Condition { get; set; } @@ -8,6 +9,6 @@ public sealed class WhileExpression : Expression public required Statement Body { get; set; } - public Statement? Else { get; set; } + public TElse? Else { get; set; } } } diff --git a/ZSharp.AST/nodes/expr/literals/ArrayLiteral.cs b/ZSharp.AST/nodes/expr/literals/ArrayLiteral.cs new file mode 100644 index 00000000..9b99b92a --- /dev/null +++ b/ZSharp.AST/nodes/expr/literals/ArrayLiteral.cs @@ -0,0 +1,7 @@ +namespace ZSharp.AST +{ + public sealed class ArrayLiteral : Expression + { + public List Items { get; set; } = []; + } +} diff --git a/ZSharp.AST/nodes/expr/LiteralExpression.cs b/ZSharp.AST/nodes/expr/literals/LiteralExpression.cs similarity index 100% rename from ZSharp.AST/nodes/expr/LiteralExpression.cs rename to ZSharp.AST/nodes/expr/literals/LiteralExpression.cs diff --git a/ZSharp.AST/nodes/leaf/IdentifierExpression.cs b/ZSharp.AST/nodes/leaf/IdentifierExpression.cs index 4a0af27d..25ad53a8 100644 --- a/ZSharp.AST/nodes/leaf/IdentifierExpression.cs +++ b/ZSharp.AST/nodes/leaf/IdentifierExpression.cs @@ -1,7 +1,13 @@ namespace ZSharp.AST { - public class IdentifierExpression(string name) : Expression + public class IdentifierExpression(IdentifierTokens tokens) : Expression { - public string Name { get; set; } = name; + public new IdentifierTokens TokenInfo + { + get => As(); + init => base.TokenInfo = value; + } + + public string Name { get; set; } = tokens.Identifier.Value; } } diff --git a/ZSharp.AST/nodes/leaf/IdentifierTokens.cs b/ZSharp.AST/nodes/leaf/IdentifierTokens.cs new file mode 100644 index 00000000..a698bfbf --- /dev/null +++ b/ZSharp.AST/nodes/leaf/IdentifierTokens.cs @@ -0,0 +1,9 @@ +using ZSharp.Text; + +namespace ZSharp.AST +{ + public sealed class IdentifierTokens(Token identifier) : TokenInfo + { + public Token Identifier { get; } = identifier; + } +} diff --git a/ZSharp.AST/nodes/abs/Parameter.cs b/ZSharp.AST/nodes/sig/Parameter.cs similarity index 66% rename from ZSharp.AST/nodes/abs/Parameter.cs rename to ZSharp.AST/nodes/sig/Parameter.cs index 8ecf1571..22a6f1a6 100644 --- a/ZSharp.AST/nodes/abs/Parameter.cs +++ b/ZSharp.AST/nodes/sig/Parameter.cs @@ -1,7 +1,13 @@ namespace ZSharp.AST { - public sealed class Parameter : Node + public sealed class Parameter(ParameterTokens tokens) : Node(tokens) { + public new ParameterTokens TokenInfo + { + get => As(); + init => base.TokenInfo = value; + } + public string? Alias { get; set; } public required string Name { get; set; } diff --git a/ZSharp.AST/nodes/sig/ParameterTokens.cs b/ZSharp.AST/nodes/sig/ParameterTokens.cs new file mode 100644 index 00000000..3dfcc1df --- /dev/null +++ b/ZSharp.AST/nodes/sig/ParameterTokens.cs @@ -0,0 +1,15 @@ +using ZSharp.Text; + +namespace ZSharp.AST +{ + public sealed class ParameterTokens : TokenInfo + { + public Token Name { get; init; } + + public Token? AsKeyword { get; init; } + + public Token? TypeSeparator { get; init; } + + public Token? ValueSeparator { get; init; } + } +} diff --git a/ZSharp.AST/nodes/abs/Signature.cs b/ZSharp.AST/nodes/sig/Signature.cs similarity index 100% rename from ZSharp.AST/nodes/abs/Signature.cs rename to ZSharp.AST/nodes/sig/Signature.cs diff --git a/ZSharp.AST/nodes/stmt/expr/DefinitionStatement.cs b/ZSharp.AST/nodes/stmt/expr/DefinitionStatement.cs new file mode 100644 index 00000000..7bee9277 --- /dev/null +++ b/ZSharp.AST/nodes/stmt/expr/DefinitionStatement.cs @@ -0,0 +1,10 @@ +namespace ZSharp.AST +{ + public sealed class DefinitionStatement : Statement + { + public required Expression Definition { get; init; } + + public override string ToString() + => $"{Definition}"; + } +} diff --git a/ZSharp.AST/nodes/stmt/IfStatement.cs b/ZSharp.AST/nodes/stmt/flow/IfStatement.cs similarity index 100% rename from ZSharp.AST/nodes/stmt/IfStatement.cs rename to ZSharp.AST/nodes/stmt/flow/IfStatement.cs diff --git a/ZSharp.AST/nodes/stmt/flow/for/ForStatement.cs b/ZSharp.AST/nodes/stmt/flow/for/ForStatement.cs new file mode 100644 index 00000000..6f111ad4 --- /dev/null +++ b/ZSharp.AST/nodes/stmt/flow/for/ForStatement.cs @@ -0,0 +1,13 @@ +namespace ZSharp.AST +{ + public sealed class ForStatement : Statement + { + public required ForValue Value { get; set; } + + public required Expression Source { get; set; } + + public required Statement Body { get; set; } + + public Statement? Else { get; set; } + } +} diff --git a/ZSharp.AST/nodes/stmt/flow/for/ForValue.cs b/ZSharp.AST/nodes/stmt/flow/for/ForValue.cs new file mode 100644 index 00000000..684059a4 --- /dev/null +++ b/ZSharp.AST/nodes/stmt/flow/for/ForValue.cs @@ -0,0 +1,6 @@ +namespace ZSharp.AST +{ + public abstract class ForValue + { + } +} diff --git a/ZSharp.AST/nodes/stmt/flow/for/LetForValue.cs b/ZSharp.AST/nodes/stmt/flow/for/LetForValue.cs new file mode 100644 index 00000000..ae8a1871 --- /dev/null +++ b/ZSharp.AST/nodes/stmt/flow/for/LetForValue.cs @@ -0,0 +1,9 @@ +namespace ZSharp.AST +{ + public sealed class LetForValue : ForValue + { + public required string Name { get; set; } + + public Expression? Type { get; set; } + } +} diff --git a/ZSharp.AST/nodes/stmt/import/ImportTokens.cs b/ZSharp.AST/nodes/stmt/import/ImportTokens.cs index 6f9caeeb..9577a0e2 100644 --- a/ZSharp.AST/nodes/stmt/import/ImportTokens.cs +++ b/ZSharp.AST/nodes/stmt/import/ImportTokens.cs @@ -7,5 +7,8 @@ public sealed class ImportTokens : TokenInfo public required Token ImportKeyword { get; init; } public required Token Semicolon { get; init; } + + public override string ToString() + => $"{ImportKeyword.Span}"; } } diff --git a/ZSharp.AST/nodes/stmt/import/ImportedName.cs b/ZSharp.AST/nodes/stmt/import/ImportedName.cs index 3891eaa0..ba4742d6 100644 --- a/ZSharp.AST/nodes/stmt/import/ImportedName.cs +++ b/ZSharp.AST/nodes/stmt/import/ImportedName.cs @@ -1,6 +1,6 @@ namespace ZSharp.AST { - public sealed class ImportedName + public sealed class ImportedName : Node { public required string Name { get; set; } diff --git a/ZSharp.CLI/CLIArgumentLogOrigin.cs b/ZSharp.CLI/CLIArgumentLogOrigin.cs new file mode 100644 index 00000000..8f61f73f --- /dev/null +++ b/ZSharp.CLI/CLIArgumentLogOrigin.cs @@ -0,0 +1,10 @@ +using ZSharp.Logging; + +namespace ZSharp.CLI +{ + internal class CLIArgumentLogOrigin(string argument) : LogOrigin + { + public override string ToString() + => $"CLI Argument '{argument}'"; + } +} diff --git a/ZSharp.CLI/Program.cs b/ZSharp.CLI/Program.cs new file mode 100644 index 00000000..2b6cc6c5 --- /dev/null +++ b/ZSharp.CLI/Program.cs @@ -0,0 +1,257 @@ +using ZSharp.CLI; +using ZSharp.Importer.ILLoader; +using ZSharp.Interpreter; +using ZSharp.Parser; +using ZSharp.SourceCompiler; +using ZSharp.SourceCompiler.Script; +using ZSharp.Text; +using ZSharp.Tokenizer; + +var interpreter = new Interpreter(); + +var filePath = args.Length == 0 ? null : args[0]; + +if (filePath is null) +{ + interpreter.Log.Error("Missing input file path argument.", new CLIArgumentLogOrigin("")); + + return; +} + +#region Parsing + +ZSharp.AST.Document documentNode; +using (StreamReader stream = File.OpenText(filePath)) +{ + var zsharpParser = new ZSharpParser(); + var parser = new Parser(Tokenizer.Tokenize(new(stream))); + + var expressionParser = zsharpParser.Expression; + var statementParser = zsharpParser.Statement; + + expressionParser.Terminal( + TokenType.String, + token => new ZSharp.AST.LiteralExpression(token.Value, ZSharp.AST.LiteralType.String) + ); + expressionParser.Terminal( + TokenType.Number, + token => new ZSharp.AST.LiteralExpression(token.Value, ZSharp.AST.LiteralType.Number) + ); + expressionParser.Terminal( + TokenType.Decimal, + token => new ZSharp.AST.LiteralExpression(token.Value, ZSharp.AST.LiteralType.Decimal) + ); + expressionParser.Terminal( + TokenType.Identifier, + token => token.Value switch + { + "null" => ZSharp.AST.LiteralExpression.Null(), + "true" => ZSharp.AST.LiteralExpression.True(), + "false" => ZSharp.AST.LiteralExpression.False(), + _ => new ZSharp.AST.IdentifierExpression(new(token)), + } + ); + expressionParser.Nud( + TokenType.LParen, + parser => + { + parser.Eat(TokenType.LParen); + var expression = parser.Parse(); + parser.Eat(TokenType.RParen); + + return expression; + }, + 10000 + ); + expressionParser.Nud( + LangParser.Keywords.Let, + LangParser.ParseLetExpression + ); + expressionParser.Nud( + LangParser.Keywords.Class, + zsharpParser.Class.Parse + ); + + expressionParser.InfixR("=", 10); + expressionParser.InfixL("<", 20); + expressionParser.InfixL("+", 50); + expressionParser.InfixL("-", 50); + expressionParser.InfixL("*", 70); + expressionParser.InfixL("/", 70); + expressionParser.InfixL("**", 80); + + expressionParser.InfixL("==", 30); + expressionParser.InfixL("!=", 30); + + expressionParser.InfixL(LangParser.Keywords.Or, 15); + + expressionParser.Led(TokenType.LParen, LangParser.ParseCallExpression, 100); + expressionParser.Led(TokenType.LBracket, LangParser.ParseIndexExpression, 100); + expressionParser.Nud(TokenType.LBracket, LangParser.ParseArrayLiteral); + expressionParser.Led(".", LangParser.ParseMemberAccess, 150); + expressionParser.Led(LangParser.Keywords.As, LangParser.ParseCastExpression, 20); + expressionParser.Led(LangParser.Keywords.Is, LangParser.ParseIsOfExpression, 20); + + expressionParser.Separator(TokenType.Comma); + expressionParser.Separator(TokenType.RParen); + expressionParser.Separator(TokenType.RBracket); + expressionParser.Separator(TokenType.Semicolon); + + expressionParser.Separator(LangParser.Keywords.In); // until it's an operator + + expressionParser.AddKeywordParser( + LangParser.Keywords.While, + LangParser.ParseWhileExpression + ); + + statementParser.AddKeywordParser( + LangParser.Keywords.While, + Utils.ExpressionStatement(LangParser.ParseWhileExpression, semicolon: false) + ); + + statementParser.AddKeywordParser( + LangParser.Keywords.If, + LangParser.ParseIfStatement + ); + + statementParser.AddKeywordParser( + LangParser.Keywords.For, + LangParser.ParseForStatement + ); + + statementParser.AddKeywordParser( + LangParser.Keywords.Case, + LangParser.ParseCaseStatement + ); + + zsharpParser.Document.AddKeywordParser( + LangParser.Keywords.If, + LangParser.ParseIfStatement + ); + + //zsharpParser.Function.AddKeywordParser( + // LangParser.Keywords.While, + // Utils.ExpressionStatement(LangParser.ParseWhileExpression, semicolon: false) + //); + + zsharpParser.RegisterParsers(parser); + documentNode = zsharpParser.Parse(parser); + + Console.WriteLine($"Finished parsing document with {documentNode.Statements.Count} statements!"); +} + +#endregion + +#region Setup Interpreter + +new ZSharp.Compiler.CGDispatchers.Direct.Dispatcher(interpreter.Compiler).Apply(); +new ZSharp.Compiler.CGDispatchers.Typed.Dispatcher(interpreter.Compiler).Apply(); +new ZSharp.Compiler.CGDispatchers.Proxy.Dispatcher(interpreter.Compiler).Apply(); + +new ZSharp.Compiler.TSDispatchers.Static.Dispatcher(interpreter.Compiler).Apply(); + +new ZSharp.Compiler.IRDispatchers.Static.Dispatcher(interpreter.Compiler).Apply(); + +new ZSharp.Compiler.EvaluatorDispatchers.Direct.Dispatcher(interpreter.Compiler).Apply(); +new ZSharp.Compiler.EvaluatorDispatchers.IR.Dispatcher(interpreter.Compiler, interpreter.Runtime, interpreter.RTLoader).Apply(); +var scriptCompiler = new ScriptCompiler(interpreter, documentNode, filePath); + +interpreter.ILLoader.OnLoadOperator = (@operator, method) => +{ + interpreter.Log.Warning( + $"Skip loading operator {@operator} ({method.GetParameters().Length} parameters)" + + $"because overloading is not implemented yet", + ZSCScriptLogOrigin.Instance + ); + //scriptCompiler.Context.Operators.Op(@operator.Operator, interpreter.ILLoader.LoadMethod(method)); +}; + +StandardTypes.VoidType = interpreter.ILLoader.TypeSystem.Void; + +#region Standard Operators + +interpreter.Operators.Op(LangParser.Symbols.MemberAccess, interpreter.ILLoader.Expose( + (Delegate)( + (object obj, string memberName) => + { + var type = obj.GetType(); + var property = type.GetProperty(memberName); + if (property is not null) + return property.GetValue(obj); + var field = type.GetField(memberName); + if (field is not null) + return field.GetValue(obj); + throw new Exception($"Member '{memberName}' not found on type '{type.FullName}'"); + } + ) +)); + +#endregion + +#region Import System + +var stringImporter = new StringImporter(); + +scriptCompiler.Context.ImportSystem.ImportFunction = interpreter.ILLoader.Expose( + (Delegate)( + (string source) => stringImporter.Import(source).Unwrap() as object + ) +); + +#endregion + +#region Importers + +#region Core Library + +var coreImporter = new CoreLibraryImporter(); +stringImporter.RegisterImporter("core", coreImporter); + +coreImporter.Add( + "compiler", + interpreter.ILLoader.LoadModule(typeof(Core.Compiler.ModuleScope).Module) +); + +#endregion + +#region Standard Library + +var stdImporter = new StandardLibraryImporter(); +stringImporter.RegisterImporter("std", stdImporter); + +stdImporter.Add( + "io", + interpreter.ILLoader.LoadModule(typeof(Standard.IO.ModuleScope).Module) +); +stdImporter.Add( + "fs", + interpreter.ILLoader.LoadModule(typeof(Standard.FileSystem.ModuleScope).Module) +); +stdImporter.Add( + "types", + interpreter.ILLoader.LoadTypeAsModule(typeof(StandardTypes)) +); +#endregion + +#endregion + +#endregion + +#region Compilation + +scriptCompiler.Compile(); + +#endregion + + +Console.WriteLine(); + +foreach (var log in interpreter.Log.Logs) +{ + Console.WriteLine(log.ToString()); +} + +Console.WriteLine(); +Console.WriteLine("Press any key to exit..."); +if (Console.ReadKey().Key == ConsoleKey.Z) + Console.WriteLine("\bYou chose wisely :)"); diff --git a/ZSharp.CLI/StandardTypes.cs b/ZSharp.CLI/StandardTypes.cs new file mode 100644 index 00000000..ddb22eff --- /dev/null +++ b/ZSharp.CLI/StandardTypes.cs @@ -0,0 +1,20 @@ +using ZSharp.Compiler; +using ZSharp.Importer.ILLoader; + +namespace ZSharp.CLI +{ + [ModuleScope] + [ImportType(typeof(Test), Namespace = "")] + public static class StandardTypes + { + [Alias("Void")] + public static CompilerObject VoidType = null!; + + } + + public class Test(string s) + { + public override string ToString() + => $"Test: {s}"; + } +} diff --git a/ZSharp.CLI/ZSCScriptLogOrigin.cs b/ZSharp.CLI/ZSCScriptLogOrigin.cs new file mode 100644 index 00000000..407c0b18 --- /dev/null +++ b/ZSharp.CLI/ZSCScriptLogOrigin.cs @@ -0,0 +1,12 @@ +using ZSharp.Logging; + +namespace ZSharp.CLI +{ + internal sealed class ZSCScriptLogOrigin() : LogOrigin + { + public static ZSCScriptLogOrigin Instance = new(); + + public override string ToString() + => "[Z# Script Compiler]"; + } +} diff --git a/ZSharp.CLI/ZSharp.CLI.csproj b/ZSharp.CLI/ZSharp.CLI.csproj new file mode 100644 index 00000000..966ca74b --- /dev/null +++ b/ZSharp.CLI/ZSharp.CLI.csproj @@ -0,0 +1,50 @@ + + + + Exe + net9.0 + enable + enable + zs + + + + embedded + + + + none + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + + + + + + + diff --git a/ZSharp.CLI/test.zs b/ZSharp.CLI/test.zs new file mode 100644 index 00000000..c117cc14 --- /dev/null +++ b/ZSharp.CLI/test.zs @@ -0,0 +1,22 @@ +import { Directory } from "std:fs"; +import { print } from "std:io"; + +print("[CT] Hello, World!"); + +fun nodeTypeNotImplemented() {} + +module A { + print("[CT] Inside module A"); + + fun main() { + print("[RT] Hello, World!"); + } +} + +if (false) { + print("[CT] Condition is true"); +} else { + print("[CT] Condition is false"); +} + +A.main(); diff --git a/ZSharp.CT.CompilerAPI/Fields_Globals.cs b/ZSharp.CT.CompilerAPI/Fields_Globals.cs deleted file mode 100644 index eed1e082..00000000 --- a/ZSharp.CT.CompilerAPI/Fields_Globals.cs +++ /dev/null @@ -1,10 +0,0 @@ -using ZSharp.Runtime.NET.IL2IR; - -namespace ZS.CompilerAPI -{ - [HideInIR] - public static class Fields_Globals - { - public static ZSharp.Compiler.Compiler compiler; - } -} diff --git a/ZSharp.CT.CompilerAPI/Impl_Globals.cs b/ZSharp.CT.CompilerAPI/Impl_Globals.cs deleted file mode 100644 index dd8b6e0c..00000000 --- a/ZSharp.CT.CompilerAPI/Impl_Globals.cs +++ /dev/null @@ -1,10 +0,0 @@ -using ZSharp.Runtime.NET.IL2IR; - -namespace ZS.CompilerAPI -{ - [ModuleGlobals] - public static class Impl_Globals - { - public static ZSharp.Compiler.Compiler GetCompiler() => Fields_Globals.compiler; - } -} diff --git a/ZSharp.CT.RuntimeAPI/Fields_Globals.cs b/ZSharp.CT.RuntimeAPI/Fields_Globals.cs deleted file mode 100644 index 31ac3262..00000000 --- a/ZSharp.CT.RuntimeAPI/Fields_Globals.cs +++ /dev/null @@ -1,10 +0,0 @@ -using ZSharp.Runtime.NET.IL2IR; - -namespace ZS.RuntimeAPI -{ - [HideInIR] - public static class Fields_Globals - { - public static ZSharp.Runtime.NET.Runtime runtime; - } -} diff --git a/ZSharp.CT.RuntimeAPI/Impl_Globals.cs b/ZSharp.CT.RuntimeAPI/Impl_Globals.cs deleted file mode 100644 index 15f50ed0..00000000 --- a/ZSharp.CT.RuntimeAPI/Impl_Globals.cs +++ /dev/null @@ -1,19 +0,0 @@ -using ZSharp.Runtime.NET.IL2IR; - -namespace ZS.RuntimeAPI -{ - [ModuleGlobals] - public static class Impl_Globals - { - public static ZSharp.Objects.CompilerObject InfoOf(object obj) - { - if (obj is ZSharp.Runtime.NET.ICompileTime ct) - return ct.GetCO(); - - throw new(); - } - - public static object GetObject(Type type) - => Fields_Globals.runtime.GetObject(type); - } -} diff --git a/ZSharp.CT.StandardLibrary/Impl_Globals.cs b/ZSharp.CT.StandardLibrary/Impl_Globals.cs deleted file mode 100644 index e729a670..00000000 --- a/ZSharp.CT.StandardLibrary/Impl_Globals.cs +++ /dev/null @@ -1,32 +0,0 @@ -using ZSharp.Runtime.NET.IL2IR; - - -namespace Standard.IO -{ - [ModuleGlobals] - public static class Impl_Globals - { - [Alias(Name = "print")] - public static void Print(string value) - => Console.WriteLine(value); - - [Alias(Name = "input")] - public static string Input(string prompt) - { - Console.Write(prompt); - return Console.ReadLine()!; - } - - [Alias(Name = "_+_")] - public static string Concat(string a, string b) - => a + b; - - [Alias(Name = "string()")] - public static string ToString(int x) - => x.ToString(); - - [Alias(Name = "int32.parse()")] - public static int ParseInt32(string s) - => int.Parse(s); - } -} diff --git a/ZSharp.Compiler.CG.Direct/GlobalUsings.cs b/ZSharp.Compiler.CG.Direct/GlobalUsings.cs new file mode 100644 index 00000000..3bfc54ae --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using MemberName = string; +global using MemberIndex = int; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.CT.CompilerAPI/ZSharp.CT.CompilerAPI.csproj b/ZSharp.Compiler.CG.Direct/ZSharp.Compiler.CG.Direct.csproj similarity index 66% rename from ZSharp.CT.CompilerAPI/ZSharp.CT.CompilerAPI.csproj rename to ZSharp.Compiler.CG.Direct/ZSharp.Compiler.CG.Direct.csproj index bf34e599..2469cf2f 100644 --- a/ZSharp.CT.CompilerAPI/ZSharp.CT.CompilerAPI.csproj +++ b/ZSharp.Compiler.CG.Direct/ZSharp.Compiler.CG.Direct.csproj @@ -1,14 +1,14 @@  - net8.0 + net9.0 enable enable + - diff --git a/ZSharp.Compiler.CG.Direct/dispatcher/Dispatcher.cs b/ZSharp.Compiler.CG.Direct/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..4fdc11af --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/dispatcher/Dispatcher.cs @@ -0,0 +1,28 @@ +namespace ZSharp.Compiler.CGDispatchers.Direct +{ + public partial class Dispatcher(Compiler compiler) + { + private readonly Compiler compiler = compiler; + private CG @base; + + public void Apply() + { + @base = compiler.CG; + + ref var cg = ref compiler.CG; + + cg.Call = Call; + cg.Cast = Cast; + cg.Get = Get; + cg.GetIndex = Index; + cg.GetMemberByIndex = Member; + cg.GetMemberByName = Member; + cg.ImplicitCast = ImplicitCast; + cg.Match = Match; + cg.Set = Set; + cg.SetIndex = Index; + cg.SetMemberByIndex = Member; + cg.SetMemberByName = Member; + } + } +} diff --git a/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Call.cs b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Call.cs new file mode 100644 index 00000000..0f955521 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Call.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Direct +{ + partial class Dispatcher + { + public IResult Call(CompilerObject callee, Argument[] arguments) + { + var result = @base.Call(callee, arguments); + + if (result.IsError && callee.Is(out var callable)) + result = callable.Call(compiler, arguments); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Cast.cs b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Cast.cs new file mode 100644 index 00000000..1378bbd0 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Cast.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Direct +{ + partial class Dispatcher + { + public IResult Cast(CompilerObject @object, CompilerObject type) + { + var result = @base.Cast(@object, type); + + if (result.IsError && @object.Is(out var castTo)) + result = castTo.Cast(compiler, type); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.ImplicitCast.cs b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.ImplicitCast.cs new file mode 100644 index 00000000..0ee7d1c0 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.ImplicitCast.cs @@ -0,0 +1,18 @@ +namespace ZSharp.Compiler.CGDispatchers.Direct +{ + partial class Dispatcher + { + public IResult ImplicitCast(CompilerObject @object, CompilerObject type) + { + var result = @base.ImplicitCast(@object, type); + + if (result.IsError && @object.Is(out var castTo)) + result = castTo.ImplicitCast(compiler, type); + + if (result.IsError && type.Is(out var castFrom)) + result = castFrom.ImplicitCast(compiler, @object); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Index.cs b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Index.cs new file mode 100644 index 00000000..7064c39a --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Index.cs @@ -0,0 +1,25 @@ +namespace ZSharp.Compiler.CGDispatchers.Direct +{ + partial class Dispatcher + { + public IResult Index(CompilerObject @object, Argument[] arguments) + { + var result = @base.GetIndex(@object, arguments); + + if (result.IsError && @object.Is(out var index)) + result = index.Index(compiler, arguments); + + return result; + } + + public IResult Index(CompilerObject @object, Argument[] arguments, CompilerObject value) + { + var result = @base.GetIndex(@object, arguments); + + if (result.IsError && @object.Is(out var index)) + result = index.Index(compiler, arguments, value); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Match.cs b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Match.cs new file mode 100644 index 00000000..3f3d2d6a --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.Match.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Direct +{ + partial class Dispatcher + { + public IResult Match(CompilerObject @object, CompilerObject pattern) + { + var result = @base.Match(@object, pattern); + + if (result.IsError && @object.Is(out var match)) + result = match.Match(compiler, pattern); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.MemberAccess.cs b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.MemberAccess.cs new file mode 100644 index 00000000..f1b143dd --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.MemberAccess.cs @@ -0,0 +1,45 @@ +namespace ZSharp.Compiler.CGDispatchers.Direct +{ + partial class Dispatcher + { + public IResult Member(CompilerObject @object, MemberIndex index) + { + var result = @base.GetMemberByIndex(@object, index); + + if (result.IsError && @object.Is>(out var member)) + result = member.Member(compiler, index); + + return result; + } + + public IResult Member(CompilerObject @object, MemberIndex index, CompilerObject value) + { + var result = @base.SetMemberByIndex(@object, index, value); + + if (result.IsError && @object.Is>(out var member)) + result = member.Member(compiler, index, value); + + return result; + } + + public IResult Member(CompilerObject @object, MemberName name) + { + var result = @base.GetMemberByName(@object, name); + + if (result.IsError && @object.Is>(out var member)) + result = member.Member(compiler, name); + + return result; + } + + public IResult Member(CompilerObject @object, MemberName name, CompilerObject value) + { + var result = @base.SetMemberByName(@object, name, value); + + if (result.IsError && @object.Is>(out var member)) + result = member.Member(compiler, name, value); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.ValueAccess.cs b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.ValueAccess.cs new file mode 100644 index 00000000..90e1c2bd --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/dispatcher/services/Dispatcher.ValueAccess.cs @@ -0,0 +1,25 @@ +namespace ZSharp.Compiler.CGDispatchers.Direct +{ + partial class Dispatcher + { + public IResult Get(CompilerObject @object) + { + var result = @base.Get(@object); + + if (result.IsError && @object.Is(out var get)) + result = get.Get(compiler); + + return result; + } + + public IResult Set(CompilerObject @object, CompilerObject value) + { + var result = @base.Set(@object, value); + + if (result.IsError && @object.Is(out var set)) + result = set.Set(compiler, value); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/callable/ICTCallable.cs b/ZSharp.Compiler.CG.Direct/protocols/callable/ICTCallable.cs new file mode 100644 index 00000000..bc8884d7 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/callable/ICTCallable.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTCallable + { + public IResult Call(Compiler compiler, Argument[] arguments); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/implicit casting/ICTImplicitCastFrom.cs b/ZSharp.Compiler.CG.Direct/protocols/implicit casting/ICTImplicitCastFrom.cs new file mode 100644 index 00000000..f3f8a828 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/implicit casting/ICTImplicitCastFrom.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTImplicitCastFrom + { + public IResult ImplicitCast(Compiler compiler, CompilerObject value); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/implicit casting/ICTImplicitCastTo.cs b/ZSharp.Compiler.CG.Direct/protocols/implicit casting/ICTImplicitCastTo.cs new file mode 100644 index 00000000..b66776d5 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/implicit casting/ICTImplicitCastTo.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTImplicitCastTo + { + public IResult ImplicitCast(Compiler compiler, CompilerObject type); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/index/ICTGetIndex.cs b/ZSharp.Compiler.CG.Direct/protocols/index/ICTGetIndex.cs new file mode 100644 index 00000000..931e80d7 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/index/ICTGetIndex.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTGetIndex + { + public IResult Index(Compiler compiler, Argument[] arguments); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/index/ICTSetIndex.cs b/ZSharp.Compiler.CG.Direct/protocols/index/ICTSetIndex.cs new file mode 100644 index 00000000..75a2a017 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/index/ICTSetIndex.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTSetIndex + { + public IResult Index(Compiler compiler, Argument[] arguments, CompilerObject value); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/member access/ICTGetMember.cs b/ZSharp.Compiler.CG.Direct/protocols/member access/ICTGetMember.cs new file mode 100644 index 00000000..4c93538f --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/member access/ICTGetMember.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTGetMember + { + public IResult Member(Compiler compiler, M member); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/member access/ICTSetMember.cs b/ZSharp.Compiler.CG.Direct/protocols/member access/ICTSetMember.cs new file mode 100644 index 00000000..82680cd7 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/member access/ICTSetMember.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTSetMember + { + public IResult Member(Compiler compiler, M member, CompilerObject value); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/type casting/ICTCastTo.cs b/ZSharp.Compiler.CG.Direct/protocols/type casting/ICTCastTo.cs new file mode 100644 index 00000000..5dd9046a --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/type casting/ICTCastTo.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTCastTo + { + public IResult Cast(Compiler compiler, CompilerObject targetType); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/type matching/ICTTypeMatch.cs b/ZSharp.Compiler.CG.Direct/protocols/type matching/ICTTypeMatch.cs new file mode 100644 index 00000000..62a88fae --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/type matching/ICTTypeMatch.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTTypeMatch + { + public IResult Match(Compiler compiler, CompilerObject type); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/value access/ICTGet.cs b/ZSharp.Compiler.CG.Direct/protocols/value access/ICTGet.cs new file mode 100644 index 00000000..83ce7d79 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/value access/ICTGet.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTGet + { + public IResult Get(Compiler compiler); + } +} diff --git a/ZSharp.Compiler.CG.Direct/protocols/value access/ICTSet.cs b/ZSharp.Compiler.CG.Direct/protocols/value access/ICTSet.cs new file mode 100644 index 00000000..35df8a19 --- /dev/null +++ b/ZSharp.Compiler.CG.Direct/protocols/value access/ICTSet.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTSet + { + public IResult Set(Compiler compiler, CompilerObject value); + } +} diff --git a/ZSharp.Compiler.CG.Proxy/GlobalUsings.cs b/ZSharp.Compiler.CG.Proxy/GlobalUsings.cs new file mode 100644 index 00000000..3bfc54ae --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using MemberName = string; +global using MemberIndex = int; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler.CG.Proxy/ZSharp.Compiler.CG.Proxy.csproj b/ZSharp.Compiler.CG.Proxy/ZSharp.Compiler.CG.Proxy.csproj new file mode 100644 index 00000000..2469cf2f --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/ZSharp.Compiler.CG.Proxy.csproj @@ -0,0 +1,14 @@ + + + + net9.0 + enable + enable + + + + + + + + diff --git a/ZSharp.Compiler.CG.Proxy/dispatcher/Dispatcher.cs b/ZSharp.Compiler.CG.Proxy/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..b8e5daab --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/dispatcher/Dispatcher.cs @@ -0,0 +1,30 @@ +namespace ZSharp.Compiler.CGDispatchers.Proxy +{ + public partial class Dispatcher(Compiler compiler) + { + private readonly Compiler compiler = compiler; + private CG @base; + + private ref CG CG => ref compiler.CG; + + public void Apply() + { + @base = compiler.CG; + + ref var cg = ref CG; + + cg.Call = Call; + cg.Cast = Cast; + cg.Get = Get; + cg.GetIndex = Index; + cg.GetMemberByIndex = Member; + cg.GetMemberByName = Member; + cg.ImplicitCast = ImplicitCast; + cg.Match = Match; + cg.Set = Set; + cg.SetIndex = Index; + cg.SetMemberByIndex = Member; + cg.SetMemberByName = Member; + } + } +} diff --git a/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Call.cs b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Call.cs new file mode 100644 index 00000000..9ec03475 --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Call.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Proxy +{ + partial class Dispatcher + { + public IResult Call(CompilerObject callee, Argument[] arguments) + { + var result = @base.Call(callee, arguments); + + if (result.IsError && callee.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Call(proxied, arguments)); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Cast.cs b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Cast.cs new file mode 100644 index 00000000..532b2389 --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Cast.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Proxy +{ + partial class Dispatcher + { + public IResult Cast(CompilerObject @object, CompilerObject type) + { + var result = @base.Cast(@object, type); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Cast(proxied, type)); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.ImplicitCast.cs b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.ImplicitCast.cs new file mode 100644 index 00000000..f14f27bd --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.ImplicitCast.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Proxy +{ + partial class Dispatcher + { + public IResult ImplicitCast(CompilerObject @object, CompilerObject type) + { + var result = @base.ImplicitCast(@object, type); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.ImplicitCast(proxied, type)); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Index.cs b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Index.cs new file mode 100644 index 00000000..1c1e09f2 --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Index.cs @@ -0,0 +1,25 @@ +namespace ZSharp.Compiler.CGDispatchers.Proxy +{ + partial class Dispatcher + { + public IResult Index(CompilerObject @object, Argument[] arguments) + { + var result = @base.GetIndex(@object, arguments); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Index(proxied, arguments)); + + return result; + } + + public IResult Index(CompilerObject @object, Argument[] arguments, CompilerObject value) + { + var result = @base.GetIndex(@object, arguments); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Index(proxied, arguments, value)); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Match.cs b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Match.cs new file mode 100644 index 00000000..569a0935 --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.Match.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Proxy +{ + partial class Dispatcher + { + public IResult Match(CompilerObject @object, CompilerObject pattern) + { + var result = @base.Match(@object, pattern); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Match(proxied, pattern)); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.MemberAccess.cs b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.MemberAccess.cs new file mode 100644 index 00000000..a3aedf80 --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.MemberAccess.cs @@ -0,0 +1,45 @@ +namespace ZSharp.Compiler.CGDispatchers.Proxy +{ + partial class Dispatcher + { + public IResult Member(CompilerObject @object, MemberIndex index) + { + var result = @base.GetMemberByIndex(@object, index); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Member(proxied, index)); + + return result; + } + + public IResult Member(CompilerObject @object, MemberIndex index, CompilerObject value) + { + var result = @base.SetMemberByIndex(@object, index, value); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Member(proxied, index, value)); + + return result; + } + + public IResult Member(CompilerObject @object, MemberName name) + { + var result = @base.GetMemberByName(@object, name); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Member(proxied, name)); + + return result; + } + + public IResult Member(CompilerObject @object, MemberName name, CompilerObject value) + { + var result = @base.SetMemberByName(@object, name, value); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Member(proxied, name, value)); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.ValueAccess.cs b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.ValueAccess.cs new file mode 100644 index 00000000..99784859 --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/dispatcher/services/Dispatcher.ValueAccess.cs @@ -0,0 +1,25 @@ +namespace ZSharp.Compiler.CGDispatchers.Proxy +{ + partial class Dispatcher + { + public IResult Get(CompilerObject @object) + { + var result = @base.Get(@object); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Get(proxied)); + + return result; + } + + public IResult Set(CompilerObject @object, CompilerObject value) + { + var result = @base.Set(@object, value); + + if (result.IsError && @object.Is(out var proxy)) + result = proxy.Apply(proxied => CG.Set(proxied, value)); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Proxy/protocols/IProxy.cs b/ZSharp.Compiler.CG.Proxy/protocols/IProxy.cs new file mode 100644 index 00000000..fe4e0a84 --- /dev/null +++ b/ZSharp.Compiler.CG.Proxy/protocols/IProxy.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IProxy + { + public IResult Apply(Func> fn) where R : class; + } +} diff --git a/ZSharp.Compiler.CG.Typed/GlobalUsings.cs b/ZSharp.Compiler.CG.Typed/GlobalUsings.cs new file mode 100644 index 00000000..3bfc54ae --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using MemberName = string; +global using MemberIndex = int; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler.CG.Typed/ZSharp.Compiler.CG.Typed.csproj b/ZSharp.Compiler.CG.Typed/ZSharp.Compiler.CG.Typed.csproj new file mode 100644 index 00000000..2469cf2f --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/ZSharp.Compiler.CG.Typed.csproj @@ -0,0 +1,14 @@ + + + + net9.0 + enable + enable + + + + + + + + diff --git a/ZSharp.Compiler.CG.Typed/dispatcher/Dispatcher.cs b/ZSharp.Compiler.CG.Typed/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..e10ead34 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/dispatcher/Dispatcher.cs @@ -0,0 +1,28 @@ +namespace ZSharp.Compiler.CGDispatchers.Typed +{ + public partial class Dispatcher(Compiler compiler) + { + private readonly Compiler compiler = compiler; + private CG @base; + + public void Apply() + { + @base = compiler.CG; + + ref var cg = ref compiler.CG; + + cg.Call = Call; + cg.Cast = Cast; + cg.Get = Get; + cg.GetIndex = Index; + cg.GetMemberByIndex = Member; + cg.GetMemberByName = Member; + cg.ImplicitCast = ImplicitCast; + cg.Match = Match; + cg.Set = Set; + cg.SetIndex = Index; + cg.SetMemberByIndex = Member; + cg.SetMemberByName = Member; + } + } +} diff --git a/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Call.cs b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Call.cs new file mode 100644 index 00000000..43db0bb7 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Call.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Typed +{ + partial class Dispatcher + { + public IResult Call(CompilerObject callee, Argument[] arguments) + { + var result = @base.Call(callee, arguments); + + if (result.IsError && compiler.RuntimeDescriptor(callee, out var rtd) && rtd.Is(out var callable)) + result = callable.Call(compiler, callee, arguments); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Cast.cs b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Cast.cs new file mode 100644 index 00000000..b886c715 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Cast.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Typed +{ + partial class Dispatcher + { + public IResult Cast(CompilerObject @object, CompilerObject type) + { + var result = @base.Cast(@object, type); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is(out var castTo)) + result = castTo.Cast(compiler, @object, type); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.ImplicitCast.cs b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.ImplicitCast.cs new file mode 100644 index 00000000..0388ce63 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.ImplicitCast.cs @@ -0,0 +1,24 @@ +namespace ZSharp.Compiler.CGDispatchers.Typed +{ + partial class Dispatcher + { + public IResult ImplicitCast(CompilerObject @object, CompilerObject type) + { + var result = @base.ImplicitCast(@object, type); + + if (result.IsOk || !compiler.RuntimeDescriptor(@object, out var rtd)) + return result; + + if (result.IsError && rtd.Is(out var castTo)) + result = castTo.ImplicitCast(compiler, @object, type); + + //if (result.IsError && rtd.Is(out var castFrom)) + // result = castFrom.ImplicitCast(compiler, @object); + + if (result.IsError && compiler.Reflection.IsSameDefinition(type, rtd)) + result = Result.Ok(@object); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Index.cs b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Index.cs new file mode 100644 index 00000000..54688b97 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Index.cs @@ -0,0 +1,25 @@ +namespace ZSharp.Compiler.CGDispatchers.Typed +{ + partial class Dispatcher + { + public IResult Index(CompilerObject @object, Argument[] arguments) + { + var result = @base.GetIndex(@object, arguments); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is(out var index)) + result = index.Index(compiler, @object, arguments); + + return result; + } + + public IResult Index(CompilerObject @object, Argument[] arguments, CompilerObject value) + { + var result = @base.GetIndex(@object, arguments); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is(out var index)) + result = index.Index(compiler, @object, arguments, value); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Match.cs b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Match.cs new file mode 100644 index 00000000..9845e765 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.Match.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.CGDispatchers.Typed +{ + partial class Dispatcher + { + public IResult Match(CompilerObject @object, CompilerObject pattern) + { + var result = @base.Match(@object, pattern); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is(out var match)) + result = match.Match(compiler, @object, pattern); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.MemberAccess.cs b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.MemberAccess.cs new file mode 100644 index 00000000..89437ebc --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.MemberAccess.cs @@ -0,0 +1,45 @@ +namespace ZSharp.Compiler.CGDispatchers.Typed +{ + partial class Dispatcher + { + public IResult Member(CompilerObject @object, MemberIndex index) + { + var result = @base.GetMemberByIndex(@object, index); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is>(out var member)) + result = member.Member(compiler, @object, index); + + return result; + } + + public IResult Member(CompilerObject @object, MemberIndex index, CompilerObject value) + { + var result = @base.SetMemberByIndex(@object, index, value); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is>(out var member)) + result = member.Member(compiler, @object, index, value); + + return result; + } + + public IResult Member(CompilerObject @object, MemberName name) + { + var result = @base.GetMemberByName(@object, name); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is>(out var member)) + result = member.Member(compiler, @object, name); + + return result; + } + + public IResult Member(CompilerObject @object, MemberName name, CompilerObject value) + { + var result = @base.SetMemberByName(@object, name, value); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is>(out var member)) + result = member.Member(compiler, @object, name, value); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.ValueAccess.cs b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.ValueAccess.cs new file mode 100644 index 00000000..95c37767 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/dispatcher/services/Dispatcher.ValueAccess.cs @@ -0,0 +1,25 @@ +namespace ZSharp.Compiler.CGDispatchers.Typed +{ + partial class Dispatcher + { + public IResult Get(CompilerObject @object) + { + var result = @base.Get(@object); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is(out var get)) + result = get.Get(compiler, @object); + + return result; + } + + public IResult Set(CompilerObject @object, CompilerObject value) + { + var result = @base.Set(@object, value); + + if (result.IsError && compiler.RuntimeDescriptor(@object, out var rtd) && rtd.Is(out var set)) + result = set.Set(compiler, @object, value); + + return result; + } + } +} diff --git a/ZSharp.Compiler.CG.Typed/extensions/CompilerExtensions.cs b/ZSharp.Compiler.CG.Typed/extensions/CompilerExtensions.cs new file mode 100644 index 00000000..87a0d69a --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/extensions/CompilerExtensions.cs @@ -0,0 +1,21 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Compiler +{ + public static class CompilerExtensions + { + public static IResult GetRuntimeDescriptor(this Compiler compiler, CompilerObject @object) + { + if (@object.Is(out var hasRuntimeDescriptor)) + return hasRuntimeDescriptor.GetRuntimeDescriptor(compiler); + + if (compiler.TS.IsTyped(@object, out var type)) + return Result.Ok(type); + + return Result.Error($"No runtime descriptor found for object {@object}."); + } + + public static bool RuntimeDescriptor(this Compiler compiler, CompilerObject @object, [NotNullWhen(true)] out CompilerObject? rt) + => compiler.GetRuntimeDescriptor(@object).Ok(out rt); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/callable/IRTCallable.cs b/ZSharp.Compiler.CG.Typed/protocols/callable/IRTCallable.cs new file mode 100644 index 00000000..4e500b03 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/callable/IRTCallable.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTCallable + { + public IResult Call(Compiler compiler, CompilerObject @object, Argument[] arguments); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/implicit casting/IRTImplicitCastTo.cs b/ZSharp.Compiler.CG.Typed/protocols/implicit casting/IRTImplicitCastTo.cs new file mode 100644 index 00000000..14d4405a --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/implicit casting/IRTImplicitCastTo.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTImplicitCastTo + { + public IResult ImplicitCast(Compiler compiler, CompilerObject @object, CompilerObject type); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/index/IRTGetIndex.cs b/ZSharp.Compiler.CG.Typed/protocols/index/IRTGetIndex.cs new file mode 100644 index 00000000..160133c4 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/index/IRTGetIndex.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTGetIndex + { + public IResult Index(Compiler compiler, CompilerObject @object, Argument[] arguments); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/index/IRTSetIndex.cs b/ZSharp.Compiler.CG.Typed/protocols/index/IRTSetIndex.cs new file mode 100644 index 00000000..a780bba6 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/index/IRTSetIndex.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTSetIndex + { + public IResult Index(Compiler compiler, CompilerObject @object, Argument[] arguments, CompilerObject value); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/member access/IRTGetMember.cs b/ZSharp.Compiler.CG.Typed/protocols/member access/IRTGetMember.cs new file mode 100644 index 00000000..b3b83a3b --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/member access/IRTGetMember.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTGetMember + { + public IResult Member(Compiler compiler, CompilerObject @object, M member); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/member access/IRTSetMember.cs b/ZSharp.Compiler.CG.Typed/protocols/member access/IRTSetMember.cs new file mode 100644 index 00000000..36dd69d8 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/member access/IRTSetMember.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTSetMember + { + public IResult Member(Compiler compiler, CompilerObject @object, M member, CompilerObject value); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/runtime/IHasRuntimeDescriptor.cs b/ZSharp.Compiler.CG.Typed/protocols/runtime/IHasRuntimeDescriptor.cs new file mode 100644 index 00000000..feb03346 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/runtime/IHasRuntimeDescriptor.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IHasRuntimeDescriptor + { + public IResult GetRuntimeDescriptor(Compiler compiler); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/type casting/IRTCastFrom.cs b/ZSharp.Compiler.CG.Typed/protocols/type casting/IRTCastFrom.cs new file mode 100644 index 00000000..45805fce --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/type casting/IRTCastFrom.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTCastFrom + { + public IResult Cast(Compiler compiler, CompilerObject value); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/type casting/IRTCastTo.cs b/ZSharp.Compiler.CG.Typed/protocols/type casting/IRTCastTo.cs new file mode 100644 index 00000000..454be3c1 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/type casting/IRTCastTo.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTCastTo + { + public IResult Cast(Compiler compiler, CompilerObject value, CompilerObject targetType); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/type matching/IRTTypeMatch.cs b/ZSharp.Compiler.CG.Typed/protocols/type matching/IRTTypeMatch.cs new file mode 100644 index 00000000..01cb8980 --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/type matching/IRTTypeMatch.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTTypeMatch + { + public IResult Match(Compiler compiler, CompilerObject value, CompilerObject type); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/value access/IRTGet.cs b/ZSharp.Compiler.CG.Typed/protocols/value access/IRTGet.cs new file mode 100644 index 00000000..6d3d7e5c --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/value access/IRTGet.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTGet + { + public IResult Get(Compiler compiler, CompilerObject @object); + } +} diff --git a/ZSharp.Compiler.CG.Typed/protocols/value access/IRTSet.cs b/ZSharp.Compiler.CG.Typed/protocols/value access/IRTSet.cs new file mode 100644 index 00000000..0b8c295b --- /dev/null +++ b/ZSharp.Compiler.CG.Typed/protocols/value access/IRTSet.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IRTSet + { + public IResult Set(Compiler compiler, CompilerObject @object, CompilerObject value); + } +} diff --git a/ZSharp.Compiler.CG/GlobalUsings.cs b/ZSharp.Compiler.CG/GlobalUsings.cs new file mode 100644 index 00000000..3bfc54ae --- /dev/null +++ b/ZSharp.Compiler.CG/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using MemberName = string; +global using MemberIndex = int; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler.CG/ZSharp.Compiler.CG.csproj b/ZSharp.Compiler.CG/ZSharp.Compiler.CG.csproj new file mode 100644 index 00000000..873c5245 --- /dev/null +++ b/ZSharp.Compiler.CG/ZSharp.Compiler.CG.csproj @@ -0,0 +1,16 @@ + + + + net9.0 + enable + enable + ZSharp.Compiler + + + + + + + + + diff --git a/ZSharp.Compiler.CG/cg/CG.cs b/ZSharp.Compiler.CG/cg/CG.cs new file mode 100644 index 00000000..862012ba --- /dev/null +++ b/ZSharp.Compiler.CG/cg/CG.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public partial struct CG() + { + + } +} diff --git a/ZSharp.Compiler.CG/cg/services/CG.Call.cs b/ZSharp.Compiler.CG/cg/services/CG.Call.cs new file mode 100644 index 00000000..b30eed0e --- /dev/null +++ b/ZSharp.Compiler.CG/cg/services/CG.Call.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + public delegate IResult Call(CompilerObject callee, Argument[] arguments); + + partial struct CG + { + public Call Call { get; set; } = Dispatcher.Call; + } +} diff --git a/ZSharp.Compiler.CG/cg/services/CG.Cast.cs b/ZSharp.Compiler.CG/cg/services/CG.Cast.cs new file mode 100644 index 00000000..6a936b64 --- /dev/null +++ b/ZSharp.Compiler.CG/cg/services/CG.Cast.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + public delegate IResult Cast(CompilerObject @object, CompilerObject type); + + partial struct CG + { + public Cast Cast { get; set; } = Dispatcher.Cast; + } +} diff --git a/ZSharp.Compiler.CG/cg/services/CG.ImplicitCast.cs b/ZSharp.Compiler.CG/cg/services/CG.ImplicitCast.cs new file mode 100644 index 00000000..7bea2caa --- /dev/null +++ b/ZSharp.Compiler.CG/cg/services/CG.ImplicitCast.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + public delegate IResult ImplicitCast(CompilerObject @object, CompilerObject type); + + partial struct CG + { + public ImplicitCast ImplicitCast { get; set; } = Dispatcher.ImplicitCast; + } +} diff --git a/ZSharp.Compiler.CG/cg/services/CG.Index.cs b/ZSharp.Compiler.CG/cg/services/CG.Index.cs new file mode 100644 index 00000000..d7ce798d --- /dev/null +++ b/ZSharp.Compiler.CG/cg/services/CG.Index.cs @@ -0,0 +1,18 @@ +namespace ZSharp.Compiler +{ + public delegate IResult GetIndex(CompilerObject @object, Argument[] arguments); + public delegate IResult SetIndex(CompilerObject @object, Argument[] arguments, CompilerObject value); + + partial struct CG + { + public GetIndex GetIndex { get; set; } = Dispatcher.Index; + + public SetIndex SetIndex { get; set; } = Dispatcher.Index; + + public readonly IResult Index(CompilerObject @object, Argument[] arguments) + => GetIndex(@object, arguments); + + public readonly IResult Index(CompilerObject @object, Argument[] arguments, CompilerObject value) + => SetIndex(@object, arguments, value); + } +} diff --git a/ZSharp.Compiler.CG/cg/services/CG.Match.cs b/ZSharp.Compiler.CG/cg/services/CG.Match.cs new file mode 100644 index 00000000..55c931f8 --- /dev/null +++ b/ZSharp.Compiler.CG/cg/services/CG.Match.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + public delegate IResult Match(CompilerObject @object, CompilerObject pattern); + + partial struct CG + { + public Match Match { get; set; } = Dispatcher.Match; + } +} diff --git a/ZSharp.Compiler.CG/cg/services/CG.MemberAccess.cs b/ZSharp.Compiler.CG/cg/services/CG.MemberAccess.cs new file mode 100644 index 00000000..4b0e4793 --- /dev/null +++ b/ZSharp.Compiler.CG/cg/services/CG.MemberAccess.cs @@ -0,0 +1,55 @@ +namespace ZSharp.Compiler +{ + public delegate IResult GetMember(CompilerObject @object, T member); + + public delegate IResult SetMember(CompilerObject @object, T member, CompilerObject value); + + partial struct CG + { + public GetMember GetMemberByIndex { get; set; } = Dispatcher.Member; + + public SetMember SetMemberByIndex { get; set; } = Dispatcher.Member; + + public GetMember GetMemberByName { get; set; } = Dispatcher.Member; + + public SetMember SetMemberByName { get; set; } = Dispatcher.Member; + + /// + /// The get member (.) operator. + /// + /// + /// + /// + public readonly IResult Member(CompilerObject @object, MemberIndex index) + => GetMemberByIndex(@object, index); + + /// + /// The set member (.=) operator. + /// + /// + /// + /// + /// + public readonly IResult Member(CompilerObject @object, MemberIndex index, CompilerObject value) + => SetMemberByIndex(@object, index, value); + + /// + /// The member (.) operator. + /// + /// + /// + /// + public readonly IResult Member(CompilerObject @object, MemberName name) + => GetMemberByName(@object, name); + + /// + /// The set member (.=) operator. + /// + /// + /// + /// + /// + public readonly IResult Member(CompilerObject @object, MemberName name, CompilerObject value) + => SetMemberByName(@object, name, value); + } +} diff --git a/ZSharp.Compiler.CG/cg/services/CG.ValueAccess.cs b/ZSharp.Compiler.CG/cg/services/CG.ValueAccess.cs new file mode 100644 index 00000000..bed1a4ff --- /dev/null +++ b/ZSharp.Compiler.CG/cg/services/CG.ValueAccess.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Compiler +{ + public delegate IResult Get(CompilerObject @object); + + public delegate IResult Set(CompilerObject @object, CompilerObject value); + + public partial struct CG + { + public Get Get { get; set; } = Dispatcher.Get; + + public Set Set { get; set; } = Dispatcher.Set; + } +} diff --git a/ZSharp.Compiler/core/concepts/callable/Argument.cs b/ZSharp.Compiler.CG/core/Argument.cs similarity index 100% rename from ZSharp.Compiler/core/concepts/callable/Argument.cs rename to ZSharp.Compiler.CG/core/Argument.cs diff --git a/ZSharp.Compiler.CG/core/CastResult.cs b/ZSharp.Compiler.CG/core/CastResult.cs new file mode 100644 index 00000000..ead66c23 --- /dev/null +++ b/ZSharp.Compiler.CG/core/CastResult.cs @@ -0,0 +1,14 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Compiler +{ + public sealed class CastResult + { + public required CompilerObject Cast { get; set; } + + public ZSharp.IR.VM.Instruction? OnFail { get; init; } = null; + + [MemberNotNullWhen(true, nameof(OnFail))] + public bool CanFail => OnFail is not null; + } +} diff --git a/ZSharp.Compiler.CG/core/MatchResult.cs b/ZSharp.Compiler.CG/core/MatchResult.cs new file mode 100644 index 00000000..b571fb74 --- /dev/null +++ b/ZSharp.Compiler.CG/core/MatchResult.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + public sealed class MatchResult + { + public required CompilerObject Match { get; set; } + + public ZSharp.IR.VM.Instruction OnMatch { get; init; } = new ZSharp.IR.VM.Nop(); + } +} diff --git a/ZSharp.Compiler.CG/dispatcher/Dispatcher.Call.cs b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Call.cs new file mode 100644 index 00000000..ec6d5fff --- /dev/null +++ b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Call.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult Call(CompilerObject callee, Argument[] arguments) + => Result.Error( + $"Object [{callee}] does not support call operation." + ); + } +} diff --git a/ZSharp.Compiler.CG/dispatcher/Dispatcher.Cast.cs b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Cast.cs new file mode 100644 index 00000000..77584f8b --- /dev/null +++ b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Cast.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult Cast(CompilerObject @object, CompilerObject type) + => Result.Error( + "Cast operation is not supported." + ); + } +} diff --git a/ZSharp.Compiler.CG/dispatcher/Dispatcher.ImplicitCast.cs b/ZSharp.Compiler.CG/dispatcher/Dispatcher.ImplicitCast.cs new file mode 100644 index 00000000..30f501a2 --- /dev/null +++ b/ZSharp.Compiler.CG/dispatcher/Dispatcher.ImplicitCast.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult ImplicitCast(CompilerObject @object, CompilerObject type) + => Result.Error( + "Implicit casting is not supported for the given object and type." + ); + } +} diff --git a/ZSharp.Compiler.CG/dispatcher/Dispatcher.Index.cs b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Index.cs new file mode 100644 index 00000000..f8e59ee2 --- /dev/null +++ b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Index.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult Index(CompilerObject @object, Argument[] arguments) + => Result.Error( + "Object does not support index operation." + ); + + public static IResult Index(CompilerObject @object, Argument[] arguments, CompilerObject value) + => Result.Error( + "Object does not support index assignment operation." + ); + } +} diff --git a/ZSharp.Compiler.CG/dispatcher/Dispatcher.Match.cs b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Match.cs new file mode 100644 index 00000000..3a150e39 --- /dev/null +++ b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Match.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult Match(CompilerObject @object, CompilerObject pattern) + => Result.Error( + "Pattern matching is not supported in the current context." + ); + } +} diff --git a/ZSharp.Compiler.CG/dispatcher/Dispatcher.MemberAccess.cs b/ZSharp.Compiler.CG/dispatcher/Dispatcher.MemberAccess.cs new file mode 100644 index 00000000..05cbfba8 --- /dev/null +++ b/ZSharp.Compiler.CG/dispatcher/Dispatcher.MemberAccess.cs @@ -0,0 +1,25 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult Member(CompilerObject @object, MemberIndex index) + => Result.Error( + $"Object [{@object}] does not support member access by index." + ); + + public static IResult Member(CompilerObject @object, MemberIndex index, CompilerObject value) + => Result.Error( + $"Object [{@object}] does not support member assignment by index." + ); + + public static IResult Member(CompilerObject @object, MemberName name) + => Result.Error( + $"Object [{@object}] does not support member access by name." + ); + + public static IResult Member(CompilerObject @object, MemberName name, CompilerObject value) + => Result.Error( + $"Object [{@object}] does not support member assignment by name." + ); + } +} diff --git a/ZSharp.Compiler.CG/dispatcher/Dispatcher.Runtime.cs b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Runtime.cs new file mode 100644 index 00000000..5c6701cd --- /dev/null +++ b/ZSharp.Compiler.CG/dispatcher/Dispatcher.Runtime.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult RuntimeDescriptor(CompilerObject @object) + => Result.Error( + "Object does not support runtime descriptor protocol" + ); + } +} diff --git a/ZSharp.Compiler.CG/dispatcher/Dispatcher.ValueAccess.cs b/ZSharp.Compiler.CG/dispatcher/Dispatcher.ValueAccess.cs new file mode 100644 index 00000000..2551698f --- /dev/null +++ b/ZSharp.Compiler.CG/dispatcher/Dispatcher.ValueAccess.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult Get(CompilerObject @object) + => Result.Error( + "Object does not support get" + ); + + public static IResult Set(CompilerObject @object, CompilerObject value) + => Result.Error( + "Object does not support set" + ); + } +} diff --git a/ZSharp.Compiler.CG/dispatcher/Dispatcher.cs b/ZSharp.Compiler.CG/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..cd652665 --- /dev/null +++ b/ZSharp.Compiler.CG/dispatcher/Dispatcher.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler +{ + internal static partial class Dispatcher + { + } +} diff --git a/ZSharp.Compiler.Context/GlobalUsings.cs b/ZSharp.Compiler.Context/GlobalUsings.cs new file mode 100644 index 00000000..3bfc54ae --- /dev/null +++ b/ZSharp.Compiler.Context/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using MemberName = string; +global using MemberIndex = int; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler.Context/ZSharp.Compiler.Context.csproj b/ZSharp.Compiler.Context/ZSharp.Compiler.Context.csproj new file mode 100644 index 00000000..de110900 --- /dev/null +++ b/ZSharp.Compiler.Context/ZSharp.Compiler.Context.csproj @@ -0,0 +1,14 @@ + + + + net9.0 + enable + enable + ZSharp.Compiler + + + + + + + diff --git a/ZSharp.Compiler.Context/capabilities/object/IObjectContext.cs b/ZSharp.Compiler.Context/capabilities/object/IObjectContext.cs new file mode 100644 index 00000000..c825f460 --- /dev/null +++ b/ZSharp.Compiler.Context/capabilities/object/IObjectContext.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Compiler +{ + public interface IObjectContext + : IContext + { + public CompilerObject Object { get; } + } + + public interface IObjectContext + : IObjectContext + where T : CompilerObject + { + new public T Object { get; } + + CompilerObject IObjectContext.Object => Object; + } +} diff --git a/ZSharp.Compiler.Context/capabilities/scoping/ILookupContext.cs b/ZSharp.Compiler.Context/capabilities/scoping/ILookupContext.cs new file mode 100644 index 00000000..56d72b00 --- /dev/null +++ b/ZSharp.Compiler.Context/capabilities/scoping/ILookupContext.cs @@ -0,0 +1,13 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Compiler +{ + public interface ILookupContext + : IContext + { + public IResult Get(MemberName name); + + public sealed bool Get(MemberName name, [NotNullWhen(true)] out CompilerObject? value) + => Get(name).Ok(out value); + } +} diff --git a/ZSharp.Compiler.Context/capabilities/scoping/IScopeContext.cs b/ZSharp.Compiler.Context/capabilities/scoping/IScopeContext.cs new file mode 100644 index 00000000..7e52d8ee --- /dev/null +++ b/ZSharp.Compiler.Context/capabilities/scoping/IScopeContext.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Compiler +{ + public interface IScopeContext + : IContext + , ILookupContext + { + public IResult Add(MemberName name, CompilerObject value); + + public IResult Set(MemberName name, CompilerObject value); + } +} diff --git a/ZSharp.Compiler.Context/capabilities/storage/IStorage.cs b/ZSharp.Compiler.Context/capabilities/storage/IStorage.cs new file mode 100644 index 00000000..d61f8ee9 --- /dev/null +++ b/ZSharp.Compiler.Context/capabilities/storage/IStorage.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IStorage + { + + } +} diff --git a/ZSharp.Compiler.Context/capabilities/storage/IStorageContext.cs b/ZSharp.Compiler.Context/capabilities/storage/IStorageContext.cs new file mode 100644 index 00000000..a066cf82 --- /dev/null +++ b/ZSharp.Compiler.Context/capabilities/storage/IStorageContext.cs @@ -0,0 +1,12 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Compiler +{ + public interface IStorageContext + { + public IResult CreateStorage(StorageOptions options); + + public sealed bool CreateStorage(StorageOptions options, [NotNullWhen(true)] out CompilerObject? result) + => CreateStorage(options).Ok(out result); + } +} diff --git a/ZSharp.Compiler.Context/capabilities/storage/IStorageDescriptor.cs b/ZSharp.Compiler.Context/capabilities/storage/IStorageDescriptor.cs new file mode 100644 index 00000000..12b28250 --- /dev/null +++ b/ZSharp.Compiler.Context/capabilities/storage/IStorageDescriptor.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler +{ + public interface IStorageDescriptor + { + } +} diff --git a/ZSharp.Compiler.Context/capabilities/storage/StorageOptions.cs b/ZSharp.Compiler.Context/capabilities/storage/StorageOptions.cs new file mode 100644 index 00000000..e3e2a1c9 --- /dev/null +++ b/ZSharp.Compiler.Context/capabilities/storage/StorageOptions.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Compiler +{ + public sealed class StorageOptions + { + public string Name { get; init; } = string.Empty; + + public required CompilerObject Type { get; init; } + + public CompilerObject? Initializer { get; init; } + + public bool? IsReadOnly { get; init; } + } +} diff --git a/ZSharp.Compiler.Context/capabilities/type inference/ITypeInferenceContext.cs b/ZSharp.Compiler.Context/capabilities/type inference/ITypeInferenceContext.cs new file mode 100644 index 00000000..e1275c11 --- /dev/null +++ b/ZSharp.Compiler.Context/capabilities/type inference/ITypeInferenceContext.cs @@ -0,0 +1,12 @@ +namespace ZSharp.Compiler +{ + public interface ITypeInferenceContext + { + protected sealed T OnCreate(T inferrer) + where T : TypeInferrer + { + inferrer.Context = this; + return inferrer; + } + } +} diff --git a/ZSharp.Compiler.Context/capabilities/type inference/TypeInferrer.cs b/ZSharp.Compiler.Context/capabilities/type inference/TypeInferrer.cs new file mode 100644 index 00000000..e6e84d71 --- /dev/null +++ b/ZSharp.Compiler.Context/capabilities/type inference/TypeInferrer.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + public abstract class TypeInferrer + : CompilerObject + { + public ITypeInferenceContext Context { get; internal set; } + } +} diff --git a/ZSharp.Compiler.Context/core/IContext.cs b/ZSharp.Compiler.Context/core/IContext.cs new file mode 100644 index 00000000..74741dfb --- /dev/null +++ b/ZSharp.Compiler.Context/core/IContext.cs @@ -0,0 +1,78 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Compiler +{ + public interface IContext + { + private static IContextChainStrategy DefaultStrategy { get; } = new ParentContextStrategy(); + + public IContext? Parent { get; set; } + + public T? FindFirstContext(IContextChainStrategy? strategy = null) + where T : class, IContext + { + strategy ??= DefaultStrategy; + + var context = this; + + do + { + if (context is T capability) return capability; + } while ((context = strategy.NextContext(context!)) is not null); + + return null; + } + + public IEnumerable FindContext(IContextChainStrategy? strategy = null) + where T : class, IContext + { + strategy ??= DefaultStrategy; + + var context = this; + + do + { + if (context is T capability) + yield return capability; + } while ((context = strategy.NextContext(context!)) is not null); + } + + public bool PerformOperation( + Func operation, + IContextChainStrategy? strategy = null + ) + where T : class, IContext + { + strategy ??= DefaultStrategy; + + var context = this; + + do + { + if (context is T capability && operation(capability)) return true; + } while ((context = strategy.NextContext(context!)) is not null); + + + return false; + } + + public bool PerformOperation( + Func operation, + [NotNullWhen(true)] out T? ctx, + IContextChainStrategy? strategy = null + ) + where T : class, IContext + { + strategy ??= DefaultStrategy; + + var context = this; + + do + { + if (context is T capability && operation(capability)) return (ctx = capability) is not null; + } while ((context = strategy.NextContext(context!)) is not null); + + return (ctx = null) is not null; + } + } +} diff --git a/ZSharp.Compiler.Context/core/IContextChainStrategy.cs b/ZSharp.Compiler.Context/core/IContextChainStrategy.cs new file mode 100644 index 00000000..af9837f0 --- /dev/null +++ b/ZSharp.Compiler.Context/core/IContextChainStrategy.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface IContextChainStrategy + { + public IContext? NextContext(IContext context); + } +} diff --git a/ZSharp.Compiler.Context/strategies/ParentContextStrategy.cs b/ZSharp.Compiler.Context/strategies/ParentContextStrategy.cs new file mode 100644 index 00000000..b9625c0c --- /dev/null +++ b/ZSharp.Compiler.Context/strategies/ParentContextStrategy.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + public sealed class ParentContextStrategy : IContextChainStrategy + { + IContext? IContextChainStrategy.NextContext(IContext context) + => context.Parent; + } +} diff --git a/ZSharp.Compiler.Core/CompilerObject.cs b/ZSharp.Compiler.Core/CompilerObject.cs new file mode 100644 index 00000000..194fc479 --- /dev/null +++ b/ZSharp.Compiler.Core/CompilerObject.cs @@ -0,0 +1,11 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Compiler +{ + public interface CompilerObject + { + public bool Is([NotNullWhen(true)] out T? result) + where T : class + => (result = this as T) is not null; + } +} diff --git a/ZSharp.CT.StandardLibrary.Math/ZSharp.CT.StandardLibrary.Math.csproj b/ZSharp.Compiler.Core/ZSharp.Compiler.Core.csproj similarity index 60% rename from ZSharp.CT.StandardLibrary.Math/ZSharp.CT.StandardLibrary.Math.csproj rename to ZSharp.Compiler.Core/ZSharp.Compiler.Core.csproj index 0aed9cf9..1884a869 100644 --- a/ZSharp.CT.StandardLibrary.Math/ZSharp.CT.StandardLibrary.Math.csproj +++ b/ZSharp.Compiler.Core/ZSharp.Compiler.Core.csproj @@ -1,13 +1,13 @@  - net8.0 + net9.0 enable enable - + diff --git a/ZSharp.Compiler.Core/result/Error.cs b/ZSharp.Compiler.Core/result/Error.cs new file mode 100644 index 00000000..1f6921bf --- /dev/null +++ b/ZSharp.Compiler.Core/result/Error.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler +{ + public abstract class Error + { + } +} diff --git a/ZSharp.Compiler.Core/result/Result.cs b/ZSharp.Compiler.Core/result/Result.cs new file mode 100644 index 00000000..3aded28d --- /dev/null +++ b/ZSharp.Compiler.Core/result/Result.cs @@ -0,0 +1,50 @@ +using CommonZ; +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Compiler +{ + public class Result + : IResult + where TResult : class? + { + private readonly TResult? result; + private readonly Error? error; + + [MemberNotNullWhen(true, nameof(result))] + public bool IsOk => result is not null; + + [MemberNotNullWhen(true, nameof(error))] + public bool IsError => error is not null; + + private Result(TResult? result, Error? error) + { + this.result = result; + this.error = error; + } + + public static Result Ok(TResult result) + => new(result, null); + + public static Result Error(Error error) + => new(null, error); + + public static Result Error(string message) + => Error(new ErrorMessage(message)); + + TResult IResult.Unwrap() + => result ?? throw new InvalidOperationException(error!.ToString()); + + Error IResult.UnwrapError() + => error ?? throw new InvalidOperationException("Result is Ok."); + + IResult IResult.When(Func map) + => IsOk + ? Result.Ok(map(result)) + : Result.Error(error!); + + IResult IResult.Else(Func map) + => IsOk + ? Result.Ok(result) + : Result.Error(map(error!)); + } +} diff --git a/ZSharp.Compiler.Core/result/errors/ErrorMessage.cs b/ZSharp.Compiler.Core/result/errors/ErrorMessage.cs new file mode 100644 index 00000000..c6a9ca75 --- /dev/null +++ b/ZSharp.Compiler.Core/result/errors/ErrorMessage.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Compiler +{ + public class ErrorMessage(string message) + : Error + { + public string Message { get; } = message; + + public override string ToString() + => Message; + } +} diff --git a/ZSharp.Compiler.Evaluation.Direct/GlobalUsings.cs b/ZSharp.Compiler.Evaluation.Direct/GlobalUsings.cs new file mode 100644 index 00000000..3bfc54ae --- /dev/null +++ b/ZSharp.Compiler.Evaluation.Direct/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using MemberName = string; +global using MemberIndex = int; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler.Evaluation.Direct/ZSharp.Compiler.Evaluation.Direct.csproj b/ZSharp.Compiler.Evaluation.Direct/ZSharp.Compiler.Evaluation.Direct.csproj new file mode 100644 index 00000000..648e0ee7 --- /dev/null +++ b/ZSharp.Compiler.Evaluation.Direct/ZSharp.Compiler.Evaluation.Direct.csproj @@ -0,0 +1,15 @@ + + + + net9.0 + enable + enable + + + + + + + + + diff --git a/ZSharp.Compiler.Evaluation.Direct/dispatcher/Dispatcher.cs b/ZSharp.Compiler.Evaluation.Direct/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..90b049d9 --- /dev/null +++ b/ZSharp.Compiler.Evaluation.Direct/dispatcher/Dispatcher.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Compiler.EvaluatorDispatchers.Direct +{ + public partial class Dispatcher( + Compiler compiler + ) + { + private readonly Compiler compiler = compiler; + + private Evaluator @base; + + public void Apply() + { + @base = compiler.Evaluator; + + ref var evaluator = ref compiler.Evaluator; + + evaluator.Evaluate = Evaluate; + } + } +} diff --git a/ZSharp.Compiler.Evaluation.Direct/dispatcher/services/Dispatcher.Evaluate.cs b/ZSharp.Compiler.Evaluation.Direct/dispatcher/services/Dispatcher.Evaluate.cs new file mode 100644 index 00000000..811cc0df --- /dev/null +++ b/ZSharp.Compiler.Evaluation.Direct/dispatcher/services/Dispatcher.Evaluate.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.EvaluatorDispatchers.Direct +{ + partial class Dispatcher + { + public IResult Evaluate(CompilerObject @object) + { + var result = @base.Evaluate(@object); + + if (result.IsError && @object.Is(out var evaluate)) + result = evaluate.Evaluate(compiler); + + return result; + } + } +} diff --git a/ZSharp.Compiler.Evaluation.Direct/protocols/evaluate/ICTEvaluate.cs b/ZSharp.Compiler.Evaluation.Direct/protocols/evaluate/ICTEvaluate.cs new file mode 100644 index 00000000..707921d5 --- /dev/null +++ b/ZSharp.Compiler.Evaluation.Direct/protocols/evaluate/ICTEvaluate.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICTEvaluate + { + public IResult Evaluate(Compiler compiler); + } +} diff --git a/ZSharp.Compiler.Evaluation.IR/GlobalUsings.cs b/ZSharp.Compiler.Evaluation.IR/GlobalUsings.cs new file mode 100644 index 00000000..3bfc54ae --- /dev/null +++ b/ZSharp.Compiler.Evaluation.IR/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using MemberName = string; +global using MemberIndex = int; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler.Evaluation.IR/ZSharp.Compiler.Evaluation.IR.csproj b/ZSharp.Compiler.Evaluation.IR/ZSharp.Compiler.Evaluation.IR.csproj new file mode 100644 index 00000000..cb67154b --- /dev/null +++ b/ZSharp.Compiler.Evaluation.IR/ZSharp.Compiler.Evaluation.IR.csproj @@ -0,0 +1,17 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + diff --git a/ZSharp.Compiler.Evaluation.IR/dispatcher/Dispatcher.cs b/ZSharp.Compiler.Evaluation.IR/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..2e06a2cb --- /dev/null +++ b/ZSharp.Compiler.Evaluation.IR/dispatcher/Dispatcher.cs @@ -0,0 +1,24 @@ +namespace ZSharp.Compiler.EvaluatorDispatchers.IR +{ + public partial class Dispatcher( + Compiler compiler, + Platform.Runtime.Runtime runtime, + Importer.RT.Loader loader + ) + { + private readonly Compiler compiler = compiler; + private readonly Platform.Runtime.Runtime runtime = runtime; + private readonly Importer.RT.Loader loader = loader; + + private Evaluator @base; + + public void Apply() + { + @base = compiler.Evaluator; + + ref var evaluator = ref compiler.Evaluator; + + evaluator.Evaluate = Evaluate; + } + } +} diff --git a/ZSharp.Compiler.Evaluation.IR/dispatcher/services/Dispatcher.Evaluate.cs b/ZSharp.Compiler.Evaluation.IR/dispatcher/services/Dispatcher.Evaluate.cs new file mode 100644 index 00000000..31a85993 --- /dev/null +++ b/ZSharp.Compiler.Evaluation.IR/dispatcher/services/Dispatcher.Evaluate.cs @@ -0,0 +1,21 @@ +namespace ZSharp.Compiler.EvaluatorDispatchers.IR +{ + partial class Dispatcher + { + public IResult Evaluate(CompilerObject @object) + { + var result = @base.Evaluate(@object); + + if (result.IsOk) return result; + + var irCodeResult = compiler.IR.CompileCode(@object, runtime); + + if (irCodeResult.When(out var irCode).Error(out var error)) + return Result.Error(error); + + var value = runtime.Evaluate(irCode!.Instructions, irCode.RequireValueType()); + + return loader.Load(value); + } + } +} diff --git a/ZSharp.Compiler.Evaluation/GlobalUsings.cs b/ZSharp.Compiler.Evaluation/GlobalUsings.cs new file mode 100644 index 00000000..501033a9 --- /dev/null +++ b/ZSharp.Compiler.Evaluation/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.CT.StandardLibrary/ZSharp.CT.StandardLibrary.csproj b/ZSharp.Compiler.Evaluation/ZSharp.Compiler.Evaluation.csproj similarity index 59% rename from ZSharp.CT.StandardLibrary/ZSharp.CT.StandardLibrary.csproj rename to ZSharp.Compiler.Evaluation/ZSharp.Compiler.Evaluation.csproj index 0aed9cf9..a46878d7 100644 --- a/ZSharp.CT.StandardLibrary/ZSharp.CT.StandardLibrary.csproj +++ b/ZSharp.Compiler.Evaluation/ZSharp.Compiler.Evaluation.csproj @@ -1,13 +1,13 @@  - net8.0 + net9.0 enable enable - + diff --git a/ZSharp.Compiler.Evaluation/dispatcher/Dispatcher.Evaluate.cs b/ZSharp.Compiler.Evaluation/dispatcher/Dispatcher.Evaluate.cs new file mode 100644 index 00000000..af85fc0e --- /dev/null +++ b/ZSharp.Compiler.Evaluation/dispatcher/Dispatcher.Evaluate.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult Evaluate(CompilerObject @object) + => Result.Error( + $"Object [{@object}] does not support evaluation." + ); + } +} diff --git a/ZSharp.Compiler.Evaluation/dispatcher/Dispatcher.cs b/ZSharp.Compiler.Evaluation/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..cd652665 --- /dev/null +++ b/ZSharp.Compiler.Evaluation/dispatcher/Dispatcher.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler +{ + internal static partial class Dispatcher + { + } +} diff --git a/ZSharp.Compiler.Evaluation/evaluator/Evaluator.cs b/ZSharp.Compiler.Evaluation/evaluator/Evaluator.cs new file mode 100644 index 00000000..8bcea188 --- /dev/null +++ b/ZSharp.Compiler.Evaluation/evaluator/Evaluator.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public partial struct Evaluator() + { + + } +} diff --git a/ZSharp.Compiler.Evaluation/evaluator/services/Evaluator.Evaluate.cs b/ZSharp.Compiler.Evaluation/evaluator/services/Evaluator.Evaluate.cs new file mode 100644 index 00000000..c077d6b7 --- /dev/null +++ b/ZSharp.Compiler.Evaluation/evaluator/services/Evaluator.Evaluate.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + public delegate IResult Evaluate(CompilerObject @object); + + partial struct Evaluator + { + public Evaluate Evaluate { get; set; } = Dispatcher.Evaluate; + } +} diff --git a/ZSharp.Compiler.Features/GlobalUsings.cs b/ZSharp.Compiler.Features/GlobalUsings.cs new file mode 100644 index 00000000..501033a9 --- /dev/null +++ b/ZSharp.Compiler.Features/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler.IRLoader/ZSharp.Compiler.IRLoader.csproj b/ZSharp.Compiler.Features/ZSharp.Compiler.Features.csproj similarity index 85% rename from ZSharp.Compiler.IRLoader/ZSharp.Compiler.IRLoader.csproj rename to ZSharp.Compiler.Features/ZSharp.Compiler.Features.csproj index 7e575a54..01691937 100644 --- a/ZSharp.Compiler.IRLoader/ZSharp.Compiler.IRLoader.csproj +++ b/ZSharp.Compiler.Features/ZSharp.Compiler.Features.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable diff --git a/ZSharp.Compiler.Features/callable/BoundParameter.cs b/ZSharp.Compiler.Features/callable/BoundParameter.cs new file mode 100644 index 00000000..439b8442 --- /dev/null +++ b/ZSharp.Compiler.Features/callable/BoundParameter.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler.Features.Callable +{ + public sealed class BoundParameter + { + public required CompilerObject ParameterObject { get; init; } + + public required CompilerObject ArgumentObject { get; init; } + } +} diff --git a/ZSharp.Compiler.Features/callable/BoundSignature.cs b/ZSharp.Compiler.Features/callable/BoundSignature.cs new file mode 100644 index 00000000..845a56af --- /dev/null +++ b/ZSharp.Compiler.Features/callable/BoundSignature.cs @@ -0,0 +1,45 @@ +using CommonZ.Utils; + +namespace ZSharp.Compiler.Features.Callable +{ + public sealed class BoundSignature + { + public required CompilerObject SignatureObject { get; init; } + + public Collection Parameters { get; init; } = []; + + public static IResult Create(Compiler compiler, CompilerObject @object, IArgumentStream arguments) + { + if (!@object.Is(out var signature)) + return Result.Error($"Object '{@object}' is not a signature."); + + var boundSignature = new BoundSignature + { + SignatureObject = @object, + }; + foreach (var parameterObject in signature.Parameters(compiler)) + { + if (!parameterObject.Is(out var parameter)) + return Result.Error($"Object '{parameterObject}' is not a parameter."); + + if ( + parameter.Match(compiler, arguments) + .When(out var value) + .Error(out var error) + ) return Result.Error(error); + + boundSignature.Parameters.Add( + new() + { + ParameterObject = (CompilerObject)parameter, + ArgumentObject = value!, + } + ); + } + if (arguments.HasArguments) + return Result.Error($"Too many arguments provided for signature '{@object}'."); + + return Result.Ok(boundSignature); + } + } +} diff --git a/ZSharp.Compiler.Features/callable/CallSite.cs b/ZSharp.Compiler.Features/callable/CallSite.cs new file mode 100644 index 00000000..724f714e --- /dev/null +++ b/ZSharp.Compiler.Features/callable/CallSite.cs @@ -0,0 +1,11 @@ +using CommonZ.Utils; + +namespace ZSharp.Compiler.Features.Callable +{ + public sealed class CallSite + { + public required CompilerObject Callable { get; init; } + + public Collection Arguments { get; init; } = []; + } +} diff --git a/ZSharp.Compiler.Features/callable/Callable.cs b/ZSharp.Compiler.Features/callable/Callable.cs new file mode 100644 index 00000000..519357f0 --- /dev/null +++ b/ZSharp.Compiler.Features/callable/Callable.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler.Features.Callable +{ + public sealed class Callable + { + } +} diff --git a/ZSharp.Compiler.Features/callable/IArgumentStream.cs b/ZSharp.Compiler.Features/callable/IArgumentStream.cs new file mode 100644 index 00000000..b2665c4e --- /dev/null +++ b/ZSharp.Compiler.Features/callable/IArgumentStream.cs @@ -0,0 +1,19 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Compiler.Features.Callable +{ + public interface IArgumentStream + { + public bool HasArguments { get; } + + public CompilerObject? PopArgument(); + + public CompilerObject? PopArgument(string name); + + public bool PopArgument([NotNullWhen(true)] out CompilerObject? argument) + => (argument = PopArgument()) is not null; + + public bool PopArgument(string name, [NotNullWhen(true)] out CompilerObject? argument) + => (argument = PopArgument(name)) is not null; + } +} diff --git a/ZSharp.Compiler.Features/callable/IParameter.cs b/ZSharp.Compiler.Features/callable/IParameter.cs new file mode 100644 index 00000000..cc381eb2 --- /dev/null +++ b/ZSharp.Compiler.Features/callable/IParameter.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler.Features.Callable +{ + public interface IParameter + { + public IResult Match(Compiler compiler, IArgumentStream arguments); + } +} diff --git a/ZSharp.Compiler.Features/callable/ISignature.cs b/ZSharp.Compiler.Features/callable/ISignature.cs new file mode 100644 index 00000000..3745ea31 --- /dev/null +++ b/ZSharp.Compiler.Features/callable/ISignature.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler.Features.Callable +{ + public interface ISignature + { + public IEnumerable Parameters(Compiler compiler); + } +} diff --git a/ZSharp.Compiler.Features/generic/Generic.cs b/ZSharp.Compiler.Features/generic/Generic.cs new file mode 100644 index 00000000..2a394f3a --- /dev/null +++ b/ZSharp.Compiler.Features/generic/Generic.cs @@ -0,0 +1,32 @@ +using CommonZ.Utils; + +namespace ZSharp.Compiler.Features.Generic +{ + public sealed class Generic + { + public bool IsGenericDefinition(CompilerObject @object) + { + throw new NotImplementedException(); + } + + public bool IsGenericInstance(CompilerObject @object) + { + throw new NotImplementedException(); + } + + public Mapping GetGenericArguments(CompilerObject @object) + { + throw new NotImplementedException(); + } + + public CompilerObject GetGenericDefinition(CompilerObject @object) + { + throw new NotImplementedException(); + } + + public IGenericParameter[] GetGenericParameters(CompilerObject @object) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Compiler.Features/generic/IGenericParameter.cs b/ZSharp.Compiler.Features/generic/IGenericParameter.cs new file mode 100644 index 00000000..3ad68e54 --- /dev/null +++ b/ZSharp.Compiler.Features/generic/IGenericParameter.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler.Features.Generic +{ + public interface IGenericParameter : CompilerObject + { + public string Name { get; } + + public CompilerObject Owner { get; } + } +} diff --git a/ZSharp.Compiler.IR.Static/GlobalUsings.cs b/ZSharp.Compiler.IR.Static/GlobalUsings.cs new file mode 100644 index 00000000..2693dd4f --- /dev/null +++ b/ZSharp.Compiler.IR.Static/GlobalUsings.cs @@ -0,0 +1,4 @@ +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; + +global using TargetPlatform = object; diff --git a/ZSharp.Compiler.IR.Static/ZSharp.Compiler.IR.Static.csproj b/ZSharp.Compiler.IR.Static/ZSharp.Compiler.IR.Static.csproj new file mode 100644 index 00000000..563f4b9d --- /dev/null +++ b/ZSharp.Compiler.IR.Static/ZSharp.Compiler.IR.Static.csproj @@ -0,0 +1,14 @@ + + + + net9.0 + enable + enable + + + + + + + + diff --git a/ZSharp.Compiler.IR.Static/dispatcher/Dispatcher.cs b/ZSharp.Compiler.IR.Static/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..c2d84402 --- /dev/null +++ b/ZSharp.Compiler.IR.Static/dispatcher/Dispatcher.cs @@ -0,0 +1,22 @@ +namespace ZSharp.Compiler.IRDispatchers.Static +{ + public partial class Dispatcher(Compiler compiler) + { + private readonly Compiler compiler = compiler; + private IR @base; + + public void Apply() + { + @base = compiler.IR; + + ref var ir = ref compiler.IR; + + ir.CompileCode = CompileCode; + ir.DefinitionInCompiler = this; + ir.DefinitionAsCompiler = this; + ir.ReferenceCompiler = this; + ir.CompileType = CompileType; + ir.TypeCompiler = this; + } + } +} diff --git a/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Code.cs b/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Code.cs new file mode 100644 index 00000000..2d996dc4 --- /dev/null +++ b/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Code.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.IRDispatchers.Static +{ + partial class Dispatcher + { + public IResult CompileCode(CompilerObject @object, TargetPlatform? target) + { + var result = @base.CompileCode(@object, target); + + if (result.IsError && @object.Is(out var compile)) + result = compile.CompileIRCode(compiler, target); + + return result; + } + } +} diff --git a/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Definition.cs b/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Definition.cs new file mode 100644 index 00000000..868a9d45 --- /dev/null +++ b/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Definition.cs @@ -0,0 +1,30 @@ +namespace ZSharp.Compiler.IRDispatchers.Static +{ + partial class Dispatcher + : IIRDefinitionInCompiler + , IIRDefinitionAsCompiler + { + bool IIRDefinitionInCompiler.CompileDefinition(CompilerObject @object, Owner owner, TargetPlatform? target) + { + var result = @base.CompileDefinition(@object, owner, target); + + if (!result && @object.Is>(out var compile)) + { + compile.CompileIRDefinition(compiler, owner, target); + result = true; + } + + return result; + } + + IResult IIRDefinitionAsCompiler.CompileDefinition(CompilerObject @object, object? target) + { + var result = @base.CompileDefinition(@object, target); + + if (result.IsError && @object.Is>(out var compile)) + result = compile.CompileIRDefinition(compiler, target); + + return result; + } + } +} diff --git a/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Reference.cs b/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Reference.cs new file mode 100644 index 00000000..f43db6ad --- /dev/null +++ b/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Reference.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Compiler.IRDispatchers.Static +{ + partial class Dispatcher + : IIRReferenceCompiler + { + IResult IIRReferenceCompiler.CompileReference(CompilerObject @object) where T : class + { + var result = @base.CompileReference(@object); + + if (result.IsError && @object.Is>(out var compile)) + result = compile.CompileIRReference(compiler); + + return result; + } + } +} diff --git a/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Type.cs b/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Type.cs new file mode 100644 index 00000000..5215586c --- /dev/null +++ b/ZSharp.Compiler.IR.Static/dispatcher/services/Dispatcher.Type.cs @@ -0,0 +1,26 @@ +namespace ZSharp.Compiler.IRDispatchers.Static +{ + partial class Dispatcher + : IIRTypeCompiler + { + public IResult CompileType(CompilerObject @object) + { + var result = @base.CompileType(@object); + + if (result.IsError && @object.Is(out var compile)) + result = compile.CompileIRType(compiler); + + return result; + } + + IResult IIRTypeCompiler.CompileType(CompilerObject @object) + { + var result = @base.CompileTypeAs(@object); + + if (result.IsError && @object.Is>(out var compile)) + result = compile.CompileIRType(compiler); + + return result; + } + } +} diff --git a/ZSharp.Compiler.IR.Static/objects/RawIRCode.cs b/ZSharp.Compiler.IR.Static/objects/RawIRCode.cs new file mode 100644 index 00000000..edff616b --- /dev/null +++ b/ZSharp.Compiler.IR.Static/objects/RawIRCode.cs @@ -0,0 +1,28 @@ +using CommonZ.Utils; +using ZSharp.Compiler; + +namespace ZSharp.Objects +{ + public sealed class RawIRCode(IRCode code) + : CompilerObject + , ICompileIRCode + { + private readonly IRCode code = code; + + IResult ICompileIRCode.CompileIRCode(Compiler.Compiler compiler, object? target) + => Result.Ok(code); + + public static CompilerObject From(Collection code, CompilerObject type) + => new UntypedIRCode(code, type); + + public static CompilerObject From(Collection code, IR.IType type) + => From(new() + { + Instructions = code, + Types = [type] + }); + + public static CompilerObject From(IRCode code) + => new RawIRCode(code); + } +} diff --git a/ZSharp.Compiler.IR.Static/objects/UntypedIRCode.cs b/ZSharp.Compiler.IR.Static/objects/UntypedIRCode.cs new file mode 100644 index 00000000..b1351dfb --- /dev/null +++ b/ZSharp.Compiler.IR.Static/objects/UntypedIRCode.cs @@ -0,0 +1,29 @@ +using CommonZ.Utils; +using ZSharp.Compiler; + +namespace ZSharp.Objects +{ + internal sealed class UntypedIRCode(Collection code, CompilerObject type) + : CompilerObject + , ICompileIRCode + , ITyped + { + CompilerObject ITyped.Type => type; + + IResult ICompileIRCode.CompileIRCode(Compiler.Compiler compiler, object? target) + { + if ( + compiler.IR.CompileType(type) + .When(out var irType) + .Error(out var error) + ) + return Result.Error(error!); + + return Result.Ok(new() + { + Instructions = code, + Types = [irType!] + }); + } + } +} diff --git a/ZSharp.Compiler.IR.Static/protocols/ICompileIRCode.cs b/ZSharp.Compiler.IR.Static/protocols/ICompileIRCode.cs new file mode 100644 index 00000000..34366d7f --- /dev/null +++ b/ZSharp.Compiler.IR.Static/protocols/ICompileIRCode.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public interface ICompileIRCode + { + public IResult CompileIRCode(Compiler compiler, TargetPlatform? target); + } +} diff --git a/ZSharp.Compiler.IR.Static/protocols/ICompileIRDefinitionAs.cs b/ZSharp.Compiler.IR.Static/protocols/ICompileIRDefinitionAs.cs new file mode 100644 index 00000000..e0216734 --- /dev/null +++ b/ZSharp.Compiler.IR.Static/protocols/ICompileIRDefinitionAs.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + public interface ICompileIRDefinitionAs + where T : ZSharp.IR.IRDefinition + { + public IResult CompileIRDefinition(Compiler compiler, TargetPlatform? target); + } +} diff --git a/ZSharp.Compiler.IR.Static/protocols/ICompileIRDefinitionIn.cs b/ZSharp.Compiler.IR.Static/protocols/ICompileIRDefinitionIn.cs new file mode 100644 index 00000000..e490ff13 --- /dev/null +++ b/ZSharp.Compiler.IR.Static/protocols/ICompileIRDefinitionIn.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + public interface ICompileIRDefinitionIn + where Owner : ZSharp.IR.IRDefinition + { + public void CompileIRDefinition(Compiler compiler, Owner owner, TargetPlatform? target); + } +} diff --git a/ZSharp.Compiler.IR.Static/protocols/ICompileIRReference.cs b/ZSharp.Compiler.IR.Static/protocols/ICompileIRReference.cs new file mode 100644 index 00000000..41fb56f3 --- /dev/null +++ b/ZSharp.Compiler.IR.Static/protocols/ICompileIRReference.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + public interface ICompileIRReference + where T : class + { + public IResult CompileIRReference(Compiler compiler); + } +} diff --git a/ZSharp.Compiler.IR.Static/protocols/ICompileIRType.cs b/ZSharp.Compiler.IR.Static/protocols/ICompileIRType.cs new file mode 100644 index 00000000..de509342 --- /dev/null +++ b/ZSharp.Compiler.IR.Static/protocols/ICompileIRType.cs @@ -0,0 +1,19 @@ +using IType = ZSharp.IR.IType; + +namespace ZSharp.Compiler +{ + public interface ICompileIRType + { + public IResult CompileIRType(Compiler compiler); + } + + public interface ICompileIRType + : ICompileIRType + where T : class, IType + { + IResult ICompileIRType.CompileIRType(Compiler compiler) + => CompileIRType(compiler).When(type => type as IType); + + public new IResult CompileIRType(Compiler compiler); + } +} \ No newline at end of file diff --git a/ZSharp.Compiler.IR/GlobalUsings.cs b/ZSharp.Compiler.IR/GlobalUsings.cs new file mode 100644 index 00000000..1a6f1d13 --- /dev/null +++ b/ZSharp.Compiler.IR/GlobalUsings.cs @@ -0,0 +1,4 @@ +global using ZSharp.IR; + +global using TargetPlatform = object; +global using IResult = IResult; diff --git a/ZSharp.Compiler.IR/ZSharp.Compiler.IR.csproj b/ZSharp.Compiler.IR/ZSharp.Compiler.IR.csproj new file mode 100644 index 00000000..056a1118 --- /dev/null +++ b/ZSharp.Compiler.IR/ZSharp.Compiler.IR.csproj @@ -0,0 +1,15 @@ + + + + net9.0 + enable + enable + ZSharp.IRCompiler + + + + + + + + diff --git a/ZSharp.Compiler/core/code/IRCode.cs b/ZSharp.Compiler.IR/core/IRCode.cs similarity index 68% rename from ZSharp.Compiler/core/code/IRCode.cs rename to ZSharp.Compiler.IR/core/IRCode.cs index d8d4a121..71470257 100644 --- a/ZSharp.Compiler/core/code/IRCode.cs +++ b/ZSharp.Compiler.IR/core/IRCode.cs @@ -4,11 +4,11 @@ namespace ZSharp.Compiler { public sealed class IRCode { - public IRInstructions Instructions { get; init; } = []; + public Collection Instructions { get; init; } = []; public int MaxStackSize { get; set; } - public Collection Types { get; init; } = []; + public Collection Types { get; init; } = []; public bool IsVoid => Types.Count == 0; @@ -18,7 +18,7 @@ public sealed class IRCode public IRCode() { } - public IRCode(IEnumerable instructions) + public IRCode(IEnumerable instructions) { Instructions = [.. instructions]; } @@ -29,9 +29,12 @@ public void RequireVoidType() throw new InvalidOperationException(); } - public CompilerObject RequireValueType() + public IType RequireValueType() => IsValue ? Types[0] : throw new InvalidOperationException(); + public IType RequireValueType(IType? @default) + => IsValue ? Types[0] : (@default ?? throw new InvalidOperationException()); + public void Append(IRCode other) { Instructions.AddRange(other.Instructions); @@ -44,9 +47,9 @@ public void Append(IRCode other) public static readonly IRCode Empty = new() { - Instructions = Collection.Empty, + Instructions = [], MaxStackSize = 0, - Types = Collection.Empty, + Types = [], }; } } diff --git a/ZSharp.Compiler.IR/dispatcher/Dispatcher.cs b/ZSharp.Compiler.IR/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..6bf6b9e2 --- /dev/null +++ b/ZSharp.Compiler.IR/dispatcher/Dispatcher.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + internal partial class Dispatcher + { + internal static Dispatcher Instance { get; } = new(); + } +} diff --git a/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Code.cs b/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Code.cs new file mode 100644 index 00000000..41166394 --- /dev/null +++ b/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Code.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public IResult CompileCode(CompilerObject @object, TargetPlatform? target) + => Result.Error( + $"Object {@object} does not support compile IR code" + ); + } +} diff --git a/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Definition.cs b/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Definition.cs new file mode 100644 index 00000000..06d4fe47 --- /dev/null +++ b/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Definition.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + : IIRDefinitionInCompiler + , IIRDefinitionAsCompiler + { + public bool CompileDefinition(CompilerObject @object, Owner owner, TargetPlatform? target) + where Owner : IRDefinition + => false; + + public IResult CompileDefinition(CompilerObject @object, object? target) where T : IRDefinition + => Result.Error( + $"Object {@object} does not support compile IR definition of type {typeof(T)}" + ); + } +} diff --git a/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Reference.cs b/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Reference.cs new file mode 100644 index 00000000..308c1bd6 --- /dev/null +++ b/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Reference.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + : IIRReferenceCompiler + { + public IResult CompileReference(CompilerObject @object) where T : class + => Result.Error( + $"Object {@object} does not support compile IR reference" + ); + } +} diff --git a/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Type.cs b/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Type.cs new file mode 100644 index 00000000..1fc52436 --- /dev/null +++ b/ZSharp.Compiler.IR/dispatcher/services/Dispatcher.Type.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + : IIRTypeCompiler + { + public IResult CompileType(CompilerObject @object) + => Result.Error( + $"Object {@object} does not support compile IR type" + ); + + IResult IIRTypeCompiler.CompileType(CompilerObject @object) + => Result.Error( + $"Object {@object} does not support compile IR type" + ); + } +} diff --git a/ZSharp.Compiler.IR/ir/IR.cs b/ZSharp.Compiler.IR/ir/IR.cs new file mode 100644 index 00000000..f415c6b1 --- /dev/null +++ b/ZSharp.Compiler.IR/ir/IR.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public partial struct IR(RuntimeModule runtimeModule) + { + public RuntimeModule RuntimeModule { get; } = runtimeModule; + } +} diff --git a/ZSharp.Compiler.IR/ir/services/IR.Code.cs b/ZSharp.Compiler.IR/ir/services/IR.Code.cs new file mode 100644 index 00000000..3de36578 --- /dev/null +++ b/ZSharp.Compiler.IR/ir/services/IR.Code.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + public delegate IResult CompileIRCode(CompilerObject @object, TargetPlatform? target); + + partial struct IR + { + public CompileIRCode CompileCode { get; set; } = Dispatcher.Instance.CompileCode; + } +} diff --git a/ZSharp.Compiler.IR/ir/services/IR.Definition.cs b/ZSharp.Compiler.IR/ir/services/IR.Definition.cs new file mode 100644 index 00000000..3457b14f --- /dev/null +++ b/ZSharp.Compiler.IR/ir/services/IR.Definition.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Compiler +{ + partial struct IR + { + public IIRDefinitionAsCompiler DefinitionAsCompiler { get; set; } = Dispatcher.Instance; + + public IIRDefinitionInCompiler DefinitionInCompiler { get; set; } = Dispatcher.Instance; + + public IResult CompileDefinition(CompilerObject @object, TargetPlatform? target) + where T : IRDefinition + => DefinitionAsCompiler.CompileDefinition(@object, target); + + public bool CompileDefinition(CompilerObject @object, Owner owner, TargetPlatform? target) + where Owner : IRDefinition + => DefinitionInCompiler.CompileDefinition(@object, owner, target); + } +} diff --git a/ZSharp.Compiler.IR/ir/services/IR.Reference.cs b/ZSharp.Compiler.IR/ir/services/IR.Reference.cs new file mode 100644 index 00000000..77ac1a58 --- /dev/null +++ b/ZSharp.Compiler.IR/ir/services/IR.Reference.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Compiler +{ + partial struct IR + { + public IIRReferenceCompiler ReferenceCompiler { get; set; } = Dispatcher.Instance; + + public IResult CompileReference(CompilerObject @object) + where T : class + => ReferenceCompiler.CompileReference(@object); + } +} diff --git a/ZSharp.Compiler.IR/ir/services/IR.Type.cs b/ZSharp.Compiler.IR/ir/services/IR.Type.cs new file mode 100644 index 00000000..17fab085 --- /dev/null +++ b/ZSharp.Compiler.IR/ir/services/IR.Type.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler +{ + public delegate IResult CompileType(CompilerObject @object); + + partial struct IR + { + public CompileType CompileType { get; set; } = Dispatcher.Instance.CompileType; + + public IIRTypeCompiler TypeCompiler { get; set; } = Dispatcher.Instance; + + public IResult CompileTypeAs(CompilerObject @object) + where T : class, IType + => TypeCompiler.CompileType(@object); + } +} diff --git a/ZSharp.Compiler.IR/protocols/IIRDefinitionAsCompiler.cs b/ZSharp.Compiler.IR/protocols/IIRDefinitionAsCompiler.cs new file mode 100644 index 00000000..c0718aee --- /dev/null +++ b/ZSharp.Compiler.IR/protocols/IIRDefinitionAsCompiler.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + public interface IIRDefinitionAsCompiler + { + public IResult CompileDefinition(CompilerObject @object, TargetPlatform? target) + where T : IRDefinition; + } +} diff --git a/ZSharp.Compiler.IR/protocols/IIRDefinitionInCompiler.cs b/ZSharp.Compiler.IR/protocols/IIRDefinitionInCompiler.cs new file mode 100644 index 00000000..995dc6d2 --- /dev/null +++ b/ZSharp.Compiler.IR/protocols/IIRDefinitionInCompiler.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + public interface IIRDefinitionInCompiler + { + public bool CompileDefinition(CompilerObject @object, Owner owner, TargetPlatform? target) + where Owner : IRDefinition; + } +} diff --git a/ZSharp.Compiler.IR/protocols/IIRReferenceCompiler.cs b/ZSharp.Compiler.IR/protocols/IIRReferenceCompiler.cs new file mode 100644 index 00000000..552bed51 --- /dev/null +++ b/ZSharp.Compiler.IR/protocols/IIRReferenceCompiler.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + public interface IIRReferenceCompiler + { + public IResult CompileReference(CompilerObject @object) + where T : class; + } +} diff --git a/ZSharp.Compiler.IR/protocols/IIRTypeCompiler.cs b/ZSharp.Compiler.IR/protocols/IIRTypeCompiler.cs new file mode 100644 index 00000000..b0eea7a6 --- /dev/null +++ b/ZSharp.Compiler.IR/protocols/IIRTypeCompiler.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + public interface IIRTypeCompiler + { + public IResult CompileType(CompilerObject @object) + where T : class, IType; + } +} \ No newline at end of file diff --git a/ZSharp.Compiler.IRLoader/Context.cs b/ZSharp.Compiler.IRLoader/Context.cs deleted file mode 100644 index a540eaa0..00000000 --- a/ZSharp.Compiler.IRLoader/Context.cs +++ /dev/null @@ -1,11 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.Compiler.IRLoader -{ - public sealed class Context - { - public Cache Objects { get; } = []; - - public Cache Types { get; } = []; - } -} diff --git a/ZSharp.Compiler.IRLoader/GlobalUsings.cs b/ZSharp.Compiler.IRLoader/GlobalUsings.cs deleted file mode 100644 index c747969f..00000000 --- a/ZSharp.Compiler.IRLoader/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using ZSharp.Objects; diff --git a/ZSharp.Compiler.IRLoader/ir loader/IRLoader.API.cs b/ZSharp.Compiler.IRLoader/ir loader/IRLoader.API.cs deleted file mode 100644 index 63f0dd3a..00000000 --- a/ZSharp.Compiler.IRLoader/ir loader/IRLoader.API.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler.IRLoader -{ - public partial class IRLoader - { - public partial Module Import(IR.Module module); - } -} diff --git a/ZSharp.Compiler.IRLoader/ir loader/IRLoader.Impl.cs b/ZSharp.Compiler.IRLoader/ir loader/IRLoader.Impl.cs deleted file mode 100644 index 23276277..00000000 --- a/ZSharp.Compiler.IRLoader/ir loader/IRLoader.Impl.cs +++ /dev/null @@ -1,139 +0,0 @@ -namespace ZSharp.Compiler.IRLoader -{ - public partial class IRLoader - { - public Context Context { get; } = new(); - - public partial Module Import(IR.Module module) - => Import(module, new(module.Name!) - { - IR = module, - }); - - public CompilerObject Import(IR.IType type) - => Load(type); - - public CompilerObject Import(IR.Function function) - => Context.Objects.Cache(function)!; - - private Module Import(IR.Module module, Module result) - { - result ??= new(module.Name!) - { - IR = module, - }; - - List actions = []; - - if (module.HasSubmodules) - foreach (var submodule in module.Submodules) - actions.Add(Load(submodule, result)); - - if (module.HasFunctions) - foreach (var function in module.Functions) - actions.Add(Load(function, result)); - - foreach (var action in actions) - action(); - - return result; - } - - private Action Load(IR.Module module, Module owner) - { - Module result = new(module.Name!) - { - IR = module, - }; - - Context.Objects.Cache(module, result); - - owner.Content.Add(result); - - if (result.Name is not null && result.Name != string.Empty) - owner.Members.Add(result.Name, result); - - return () => Import(module, result); - } - - private Action Load(IR.Function function, Module owner) - { - RTFunction result = new(function.Name) - { - IR = function - }; - - Context.Objects.Cache(function, result); - - owner.Content.Add(result); - - if (result.Name is not null && result.Name != string.Empty) - owner.Members.Add(result.Name, result); // TODO: overloading - - return () => - { - result.Signature = Load(function.Signature); - - result.ReturnType = Load(function.ReturnType); - }; - } - - private Action Load(IR.OOPType type) - => type switch - { - IR.Class @class => Load(@class), - //IR.Interface @interface => Load(@interface), - //IR.Struct @struct => Load(@struct), - _ => throw new NotImplementedException(), - }; - - private Action Load(IR.Class @class) - { - throw new NotImplementedException(); - } - - private CompilerObject Load(IR.IType type) - { - if (Context.Types.Cache(type, out var result)) - return result; - - throw new NotImplementedException(); - } - - private Signature Load(IR.Signature signature) - { - Signature result = new(); - - if (signature.HasArgs) - foreach (var arg in signature.Args.Parameters) - result.Args.Add(Load(arg)); - - if (signature.IsVarArgs) - result.VarArgs = Load(signature.Args.Var!); - - if (signature.HasKwArgs) - foreach (var arg in signature.KwArgs.Parameters) - result.KwArgs.Add(Load(arg)); - - if (signature.IsVarKwArgs) - result.VarKwArgs = Load(signature.KwArgs.Var!); - - return result; - } - - private Parameter Load(IR.Parameter parameter) - { - var type = Load(parameter.Type); - - return new(parameter.Name) - { - IR = parameter, - Initializer = parameter.Initializer is null ? null : new RawCode(new(parameter.Initializer) - { - Types = [type] - }), - Type = type, - }; - } - } -} diff --git a/ZSharp.Compiler.IRLoader/ir loader/IRLoader.cs b/ZSharp.Compiler.IRLoader/ir loader/IRLoader.cs deleted file mode 100644 index 26c9153e..00000000 --- a/ZSharp.Compiler.IRLoader/ir loader/IRLoader.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace ZSharp.Compiler.IRLoader -{ - public sealed partial class IRLoader : Feature - { - public IRLoader(Compiler compiler) : base(compiler) - { - Initialize(); - } - - private void Initialize() - { - foreach (var type in new CompilerObject[] { - Compiler.TypeSystem.Type, - Compiler.TypeSystem.Float32, - Compiler.TypeSystem.String, - Compiler.TypeSystem.Int32, - Compiler.TypeSystem.Void, - Compiler.TypeSystem.Boolean, - }) - Context.Types.Cache(Compiler.CompileIRType(type), type); - } - } -} diff --git a/ZSharp.Compiler.Overloading/GlobalUsings.cs b/ZSharp.Compiler.Overloading/GlobalUsings.cs new file mode 100644 index 00000000..3bfc54ae --- /dev/null +++ b/ZSharp.Compiler.Overloading/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using MemberName = string; +global using MemberIndex = int; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.CT.RuntimeAPI/ZSharp.CT.RuntimeAPI.csproj b/ZSharp.Compiler.Overloading/ZSharp.Compiler.Overloading.csproj similarity index 59% rename from ZSharp.CT.RuntimeAPI/ZSharp.CT.RuntimeAPI.csproj rename to ZSharp.Compiler.Overloading/ZSharp.Compiler.Overloading.csproj index 0aed9cf9..a46878d7 100644 --- a/ZSharp.CT.RuntimeAPI/ZSharp.CT.RuntimeAPI.csproj +++ b/ZSharp.Compiler.Overloading/ZSharp.Compiler.Overloading.csproj @@ -1,13 +1,13 @@  - net8.0 + net9.0 enable enable - + diff --git a/ZSharp.Compiler.Overloading/dispatcher/Dispatcher.T.cs b/ZSharp.Compiler.Overloading/dispatcher/Dispatcher.T.cs new file mode 100644 index 00000000..d6c15b5e --- /dev/null +++ b/ZSharp.Compiler.Overloading/dispatcher/Dispatcher.T.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult F(CompilerObject @object) + => Result.Error($"Object '{@object}' does not implement F"); + } +} diff --git a/ZSharp.Compiler.Overloading/dispatcher/Dispatcher.cs b/ZSharp.Compiler.Overloading/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..cd652665 --- /dev/null +++ b/ZSharp.Compiler.Overloading/dispatcher/Dispatcher.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler +{ + internal static partial class Dispatcher + { + } +} diff --git a/ZSharp.Compiler.Overloading/overloading/Overloading.cs b/ZSharp.Compiler.Overloading/overloading/Overloading.cs new file mode 100644 index 00000000..1a4058c4 --- /dev/null +++ b/ZSharp.Compiler.Overloading/overloading/Overloading.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public partial struct Overloading() + { + + } +} diff --git a/ZSharp.Compiler.Overloading/overloading/services/Overloading.T.cs b/ZSharp.Compiler.Overloading/overloading/services/Overloading.T.cs new file mode 100644 index 00000000..ff9fb3c8 --- /dev/null +++ b/ZSharp.Compiler.Overloading/overloading/services/Overloading.T.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + public delegate IResult F(CompilerObject callee); + + partial struct Overloading + { + public F CaFll { get; set; } = Dispatcher.F; + } +} diff --git a/ZSharp.Compiler.Reflection/GlobalUsings.cs b/ZSharp.Compiler.Reflection/GlobalUsings.cs new file mode 100644 index 00000000..3bfc54ae --- /dev/null +++ b/ZSharp.Compiler.Reflection/GlobalUsings.cs @@ -0,0 +1,5 @@ +global using MemberName = string; +global using MemberIndex = int; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler.Reflection/ZSharp.Compiler.Reflection.csproj b/ZSharp.Compiler.Reflection/ZSharp.Compiler.Reflection.csproj new file mode 100644 index 00000000..a46878d7 --- /dev/null +++ b/ZSharp.Compiler.Reflection/ZSharp.Compiler.Reflection.csproj @@ -0,0 +1,13 @@ + + + + net9.0 + enable + enable + + + + + + + diff --git a/ZSharp.Compiler.Reflection/dispatcher/Dispatcher.Definition.cs b/ZSharp.Compiler.Reflection/dispatcher/Dispatcher.Definition.cs new file mode 100644 index 00000000..022d25d8 --- /dev/null +++ b/ZSharp.Compiler.Reflection/dispatcher/Dispatcher.Definition.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static bool IsSameDefinition(CompilerObject left, CompilerObject right) + => ReferenceEquals(left, right); + } +} diff --git a/ZSharp.Compiler.Reflection/dispatcher/Dispatcher.cs b/ZSharp.Compiler.Reflection/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..cd652665 --- /dev/null +++ b/ZSharp.Compiler.Reflection/dispatcher/Dispatcher.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler +{ + internal static partial class Dispatcher + { + } +} diff --git a/ZSharp.Compiler.Reflection/reflection/Reflection.cs b/ZSharp.Compiler.Reflection/reflection/Reflection.cs new file mode 100644 index 00000000..2c128acc --- /dev/null +++ b/ZSharp.Compiler.Reflection/reflection/Reflection.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler +{ + public partial struct Reflection() + { + + } +} diff --git a/ZSharp.Compiler.Reflection/reflection/services/Reflection.Definition.cs b/ZSharp.Compiler.Reflection/reflection/services/Reflection.Definition.cs new file mode 100644 index 00000000..420f3288 --- /dev/null +++ b/ZSharp.Compiler.Reflection/reflection/services/Reflection.Definition.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + public delegate bool AreSameDefinition(CompilerObject left, CompilerObject right); + + partial struct Reflection + { + public AreSameDefinition IsSameDefinition { get; set; } = Dispatcher.IsSameDefinition; + } +} diff --git a/ZSharp.Compiler.TS.Static/GlobalUsings.cs b/ZSharp.Compiler.TS.Static/GlobalUsings.cs new file mode 100644 index 00000000..501033a9 --- /dev/null +++ b/ZSharp.Compiler.TS.Static/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.ZSSourceCompiler/ZSharp.ZSSourceCompiler.csproj b/ZSharp.Compiler.TS.Static/ZSharp.Compiler.TS.Static.csproj similarity index 70% rename from ZSharp.ZSSourceCompiler/ZSharp.ZSSourceCompiler.csproj rename to ZSharp.Compiler.TS.Static/ZSharp.Compiler.TS.Static.csproj index 8a2bf752..01691937 100644 --- a/ZSharp.ZSSourceCompiler/ZSharp.ZSSourceCompiler.csproj +++ b/ZSharp.Compiler.TS.Static/ZSharp.Compiler.TS.Static.csproj @@ -1,13 +1,12 @@  - net8.0 + net9.0 enable enable - diff --git a/ZSharp.Compiler.TS.Static/dispatcher/Dispatcher.T.cs b/ZSharp.Compiler.TS.Static/dispatcher/Dispatcher.T.cs new file mode 100644 index 00000000..2becf8f9 --- /dev/null +++ b/ZSharp.Compiler.TS.Static/dispatcher/Dispatcher.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Compiler.TSDispatchers.Static +{ + partial class Dispatcher + { + + } +} diff --git a/ZSharp.Compiler.TS.Static/dispatcher/Dispatcher.TypeOf.cs b/ZSharp.Compiler.TS.Static/dispatcher/Dispatcher.TypeOf.cs new file mode 100644 index 00000000..d2e55698 --- /dev/null +++ b/ZSharp.Compiler.TS.Static/dispatcher/Dispatcher.TypeOf.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler.TSDispatchers.Static +{ + partial class Dispatcher + { + public IResult TypeOf(CompilerObject @object) + { + var result = @base.TypeOf(@object); + + if (result.IsError && @object.Is(out var typed)) + result = Result.Ok(typed.Type); + + return result; + } + } +} diff --git a/ZSharp.Compiler.TS.Static/dispatcher/Dispatcher.cs b/ZSharp.Compiler.TS.Static/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..5d326666 --- /dev/null +++ b/ZSharp.Compiler.TS.Static/dispatcher/Dispatcher.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Compiler.TSDispatchers.Static +{ + public sealed partial class Dispatcher(Compiler compiler) + { + private readonly Compiler compiler = compiler; + private TS @base; + + public void Apply() + { + @base = compiler.TS; + + ref var ts = ref compiler.TS; + + ts.TypeOf = TypeOf; + } + } +} diff --git a/ZSharp.Compiler/compiler core/core/type system/ITyped.cs b/ZSharp.Compiler.TS.Static/protocols/ITyped.cs similarity index 59% rename from ZSharp.Compiler/compiler core/core/type system/ITyped.cs rename to ZSharp.Compiler.TS.Static/protocols/ITyped.cs index 6a2029ed..24c95fcf 100644 --- a/ZSharp.Compiler/compiler core/core/type system/ITyped.cs +++ b/ZSharp.Compiler.TS.Static/protocols/ITyped.cs @@ -3,8 +3,5 @@ public interface ITyped { public CompilerObject Type { get; } - - public CompilerObject GetType(Compiler compiler) - => Type; } } diff --git a/ZSharp.Compiler.TS/GlobalUsings.cs b/ZSharp.Compiler.TS/GlobalUsings.cs new file mode 100644 index 00000000..501033a9 --- /dev/null +++ b/ZSharp.Compiler.TS/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler.TS/ZSharp.Compiler.TS.csproj b/ZSharp.Compiler.TS/ZSharp.Compiler.TS.csproj new file mode 100644 index 00000000..466792ff --- /dev/null +++ b/ZSharp.Compiler.TS/ZSharp.Compiler.TS.csproj @@ -0,0 +1,17 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + diff --git a/ZSharp.Compiler.TS/dispatcher/Dispatcher.T.cs b/ZSharp.Compiler.TS/dispatcher/Dispatcher.T.cs new file mode 100644 index 00000000..e648a27e --- /dev/null +++ b/ZSharp.Compiler.TS/dispatcher/Dispatcher.T.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult Do(CompilerObject @object) + => Result.Error( + "Object does not support do" + ); + } +} diff --git a/ZSharp.Compiler.TS/dispatcher/Dispatcher.cs b/ZSharp.Compiler.TS/dispatcher/Dispatcher.cs new file mode 100644 index 00000000..cd652665 --- /dev/null +++ b/ZSharp.Compiler.TS/dispatcher/Dispatcher.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler +{ + internal static partial class Dispatcher + { + } +} diff --git a/ZSharp.Compiler.TS/dispatcher/services/Dispatcher.IsAssignable.cs b/ZSharp.Compiler.TS/dispatcher/services/Dispatcher.IsAssignable.cs new file mode 100644 index 00000000..c97c4c9a --- /dev/null +++ b/ZSharp.Compiler.TS/dispatcher/services/Dispatcher.IsAssignable.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static bool IsAssignableTo(CompilerObject target, CompilerObject source) + => false; + } +} diff --git a/ZSharp.Compiler.TS/dispatcher/services/Dispatcher.TypeOf.cs b/ZSharp.Compiler.TS/dispatcher/services/Dispatcher.TypeOf.cs new file mode 100644 index 00000000..b5071c85 --- /dev/null +++ b/ZSharp.Compiler.TS/dispatcher/services/Dispatcher.TypeOf.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + partial class Dispatcher + { + public static IResult TypeOf(CompilerObject @object) + => Result.Error( + "Object does not support typeof" + ); + } +} diff --git a/ZSharp.Compiler.TS/ts/TS.T.cs b/ZSharp.Compiler.TS/ts/TS.T.cs new file mode 100644 index 00000000..e71e3dd8 --- /dev/null +++ b/ZSharp.Compiler.TS/ts/TS.T.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler +{ + partial struct TS + { + } +} diff --git a/ZSharp.Compiler.TS/ts/TS.cs b/ZSharp.Compiler.TS/ts/TS.cs new file mode 100644 index 00000000..e4a68279 --- /dev/null +++ b/ZSharp.Compiler.TS/ts/TS.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Compiler +{ + public partial struct TS() + { + } +} diff --git a/ZSharp.Compiler.TS/ts/services/TS.IsAssignable.cs b/ZSharp.Compiler.TS/ts/services/TS.IsAssignable.cs new file mode 100644 index 00000000..1002e5f9 --- /dev/null +++ b/ZSharp.Compiler.TS/ts/services/TS.IsAssignable.cs @@ -0,0 +1,12 @@ +namespace ZSharp.Compiler +{ + public delegate bool IsAssignableTo(CompilerObject target, CompilerObject source); + + partial struct TS + { + public IsAssignableTo IsAssignableTo { get; set; } = Dispatcher.IsAssignableTo; + + public bool IsAssignableFrom(CompilerObject source, CompilerObject target) + => IsAssignableTo(target, source); + } +} diff --git a/ZSharp.Compiler.TS/ts/services/TS.Make.cs b/ZSharp.Compiler.TS/ts/services/TS.Make.cs new file mode 100644 index 00000000..125bf29b --- /dev/null +++ b/ZSharp.Compiler.TS/ts/services/TS.Make.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Compiler +{ + partial struct TS + { + public CompilerObject Array(CompilerObject type) + { + throw new NotImplementedException(); + } + + public CompilerObject Pointer(CompilerObject type) + { + throw new NotImplementedException(); + } + + public CompilerObject Reference(CompilerObject type) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Compiler.TS/ts/services/TS.TypeOf.cs b/ZSharp.Compiler.TS/ts/services/TS.TypeOf.cs new file mode 100644 index 00000000..3c2b1a46 --- /dev/null +++ b/ZSharp.Compiler.TS/ts/services/TS.TypeOf.cs @@ -0,0 +1,14 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Compiler +{ + public delegate IResult TypeOf(CompilerObject @object); + + partial struct TS + { + public TypeOf TypeOf { get; set; } = Dispatcher.TypeOf; + + public bool IsTyped(CompilerObject @object, [NotNullWhen(true)] out CompilerObject? result) + => TypeOf(@object).Ok(out result); + } +} diff --git a/ZSharp.Compiler.TS/ts/types/TS.Types.Float.cs b/ZSharp.Compiler.TS/ts/types/TS.Types.Float.cs new file mode 100644 index 00000000..44b129e1 --- /dev/null +++ b/ZSharp.Compiler.TS/ts/types/TS.Types.Float.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Compiler +{ + partial struct TS + { + public CompilerObject Float32 { get; set; } + + public CompilerObject Float64 { get; set; } + } +} diff --git a/ZSharp.Compiler.TS/ts/types/TS.Types.Indirect.cs b/ZSharp.Compiler.TS/ts/types/TS.Types.Indirect.cs new file mode 100644 index 00000000..c838f97d --- /dev/null +++ b/ZSharp.Compiler.TS/ts/types/TS.Types.Indirect.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Compiler +{ + partial struct TS + { + public CompilerObject ArrayType { get; set; } + + public CompilerObject PointerType { get; set; } + + public CompilerObject ReferenceType { get; set; } + } +} diff --git a/ZSharp.Compiler.TS/ts/types/TS.Types.Others.cs b/ZSharp.Compiler.TS/ts/types/TS.Types.Others.cs new file mode 100644 index 00000000..3df80918 --- /dev/null +++ b/ZSharp.Compiler.TS/ts/types/TS.Types.Others.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Compiler +{ + partial struct TS + { + public CompilerObject Boolean { get; set; } + + public CompilerObject Null { get; set; } + + public CompilerObject String { get; set; } + + public CompilerObject Type { get; set; } + + public CompilerObject Void { get; set; } + } +} diff --git a/ZSharp.Compiler.TS/ts/types/TS.Types.SInt.cs b/ZSharp.Compiler.TS/ts/types/TS.Types.SInt.cs new file mode 100644 index 00000000..b1641480 --- /dev/null +++ b/ZSharp.Compiler.TS/ts/types/TS.Types.SInt.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Compiler +{ + partial struct TS + { + public CompilerObject SInt8 { get; set; } + + public CompilerObject SInt16 { get; set; } + + public CompilerObject SInt32 { get; set; } + + public CompilerObject SInt64 { get; set; } + } +} diff --git a/ZSharp.Compiler.TS/ts/types/TS.Types.UInt.cs b/ZSharp.Compiler.TS/ts/types/TS.Types.UInt.cs new file mode 100644 index 00000000..c3e2b260 --- /dev/null +++ b/ZSharp.Compiler.TS/ts/types/TS.Types.UInt.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Compiler +{ + partial struct TS + { + public CompilerObject UInt8 { get; set; } + + public CompilerObject UInt16 { get; set; } + + public CompilerObject UInt32 { get; set; } + + public CompilerObject UInt64 { get; set; } + } +} diff --git a/ZSharp.Compiler/GlobalUsings.cs b/ZSharp.Compiler/GlobalUsings.cs index c6f6ef04..3bfc54ae 100644 --- a/ZSharp.Compiler/GlobalUsings.cs +++ b/ZSharp.Compiler/GlobalUsings.cs @@ -1,13 +1,5 @@ global using MemberName = string; global using MemberIndex = int; -global using IRType = ZSharp.IR.IType; - -global using DefaultIntegerType = int; - -global using Args = CommonZ.Utils.Collection; -global using KwArgs = CommonZ.Utils.Mapping; - -global using IRInstructions = CommonZ.Utils.Collection; - -global using CompilerObject = ZSharp.Objects.CompilerObject; +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Compiler/ZSharp.Compiler.csproj b/ZSharp.Compiler/ZSharp.Compiler.csproj index afe2b65a..0c467a6d 100644 --- a/ZSharp.Compiler/ZSharp.Compiler.csproj +++ b/ZSharp.Compiler/ZSharp.Compiler.csproj @@ -1,17 +1,32 @@  - net8.0 + net9.0 enable enable + + + + + + + + + + + + + + - + + diff --git a/ZSharp.Compiler/cg objects/Type.cs b/ZSharp.Compiler/cg objects/Type.cs deleted file mode 100644 index 17115f45..00000000 --- a/ZSharp.Compiler/cg objects/Type.cs +++ /dev/null @@ -1,28 +0,0 @@ -using ZSharp.Compiler; -using ZSharp.IR; - -namespace ZSharp.Objects -{ - internal sealed class Type(IRType type) - : CompilerObject - , ICTReadable - , ICompileIRType - { - private readonly IRType type = type; - private readonly IRObject ir = type as IRObject ?? throw new(); - - CompilerObject ITyped.Type => this; - - IType ICompileIRType.CompileIRType(Compiler.Compiler compiler) - => type; - - public IRCode Read(Compiler.Compiler compiler) - => new([ - new IR.VM.GetObject(ir) - ]) - { - MaxStackSize = 1, - Types = [this] - }; - } -} diff --git a/ZSharp.Compiler/cg objects/Utils.cs b/ZSharp.Compiler/cg objects/Utils.cs deleted file mode 100644 index c53a71bb..00000000 --- a/ZSharp.Compiler/cg objects/Utils.cs +++ /dev/null @@ -1,23 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public static class Utils - { - public static (Args, KwArgs) SplitArguments(Argument[] arguments) - { - Args positional = []; - KwArgs named = []; - - foreach (var argument in arguments) - { - if (argument.Name is null) - positional.Add(argument.Object); - else - named[argument.Name] = argument.Object; - } - - return (positional, named); - } - } -} diff --git a/ZSharp.Compiler/cg objects/functional/CTFunction.cs b/ZSharp.Compiler/cg objects/functional/CTFunction.cs deleted file mode 100644 index 182e918f..00000000 --- a/ZSharp.Compiler/cg objects/functional/CTFunction.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Objects -{ - public abstract class CTFunction(string? name) : Function(name) - { - - } -} diff --git a/ZSharp.Compiler/cg objects/functional/Function.cs b/ZSharp.Compiler/cg objects/functional/Function.cs deleted file mode 100644 index ff3de551..00000000 --- a/ZSharp.Compiler/cg objects/functional/Function.cs +++ /dev/null @@ -1,26 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - /// - /// Defines the base structure for a function. - /// - /// A function must have a signature. - /// The signature is used to be able to choose an overload at CG. - /// - /// This is abstract because the behavior for calling a function is - /// different for each type of function. - /// - public abstract class Function(string? name) - : CompilerObject - , ICTCallable - { - public IR.Function? IR { get; set; } - - public string? Name { get; set; } = name; - - public CompilerObject? Body { get; set; } - - public abstract CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments); - } -} diff --git a/ZSharp.Compiler/cg objects/functional/body/Local.cs b/ZSharp.Compiler/cg objects/functional/body/Local.cs deleted file mode 100644 index b7c40ad2..00000000 --- a/ZSharp.Compiler/cg objects/functional/body/Local.cs +++ /dev/null @@ -1,92 +0,0 @@ -using ZSharp.Compiler; -using ZSharp.IR; - -namespace ZSharp.Objects -{ - public sealed class Local - : CompilerObject - , ICTAssignable - , ICTReadable - , ICompileIRObject - { - [Flags] - enum BuildState - { - None = 0, - Owner = 0b1, - Initializer = 0b100, - } - - private BuildState _state = BuildState.None; - - public IR.VM.Local? IR { get; set; } - - public required string Name { get; set; } - - public bool IsOwnerBuilt - { - get => _state.HasFlag(BuildState.Owner); - set => _state = value ? _state | BuildState.Owner : _state & ~BuildState.Owner; - } - - public bool IsInitializerBuilt - { - get => _state.HasFlag(BuildState.Initializer); - set => _state = value ? _state | BuildState.Initializer : _state & ~BuildState.Initializer; - } - - public CompilerObject? Type { get; set; } - - public CompilerObject? Initializer { get; set; } - - public IR.VM.Local CompileIRObject(Compiler.Compiler compiler, ICallableBody? owner) - { - if (Type is null) - throw new(); - - IR ??= new(Name, compiler.CompileIRType(Type)); - - if (!IsOwnerBuilt && owner is not null) - { - owner.Locals.Add(IR); - - IsOwnerBuilt = true; - } - - if (!IsInitializerBuilt && Initializer is not null) - { - IR.Initializer = compiler.CompileIRCode(Initializer).Instructions.ToArray(); - - IsInitializerBuilt = true; - } - - return IR; - } - - public IRCode Read(Compiler.Compiler compiler) - => new([new IR.VM.GetLocal(IR!)]) - { - MaxStackSize = 1, - Types = [Type] - }; - - public CompilerObject Assign(Compiler.Compiler compiler, CompilerObject value) - { - // TODO: check if read-only - - if (Type is null) - throw new(); - - var code = compiler.CompileIRCode(compiler.Cast(value, Type)); - - code.Instructions.AddRange( - [ - new IR.VM.Dup(), - new IR.VM.SetLocal(IR!) - ] - ); - - return new RawCode(code); - } - } -} diff --git a/ZSharp.Compiler/cg objects/functional/rt/RTFunction.cs b/ZSharp.Compiler/cg objects/functional/rt/RTFunction.cs deleted file mode 100644 index 60537a27..00000000 --- a/ZSharp.Compiler/cg objects/functional/rt/RTFunction.cs +++ /dev/null @@ -1,168 +0,0 @@ -using ZSharp.Compiler; -using ZSharp.IR; - -namespace ZSharp.Objects -{ - public class RTFunction(string? name) - : Function(name) - , ICTReadable - , ICompileIRObject - { - [Flags] - enum BuildState - { - None = 0, - Signature = 0b1, - Body = 0b10, - Owner = 0b100, - } - - private BuildState _state = BuildState.None; - - CompilerObject ITyped.Type => throw new NotImplementedException(); - - public Signature Signature { get; set; } = new(); - - public CompilerObject? ReturnType { get; set; } - - public bool IsSignatureBuilt - { - get => _state.HasFlag(BuildState.Signature); - set => _state = value ? _state | BuildState.Signature : _state & ~BuildState.Signature; - } - - public bool IsBodyBuilt - { - get => _state.HasFlag(BuildState.Body); - set => _state = value ? _state | BuildState.Body : _state & ~BuildState.Body; - } - - public bool IsOwnerBuilt - { - get => _state.HasFlag(BuildState.Owner); - set => _state = value ? _state | BuildState.Owner : _state & ~BuildState.Owner; - } - - public CompilerObject Call(IRCode[] arguments) - { - if (IR is null) - throw new("Function not compiled."); - - IRCode code = new(); - - foreach (var argument in arguments) - code.Append(argument); - - code.Instructions.Add(new IR.VM.Call(IR)); - - throw new NotImplementedException(); - //return new Code(code); - } - - public override CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) - { - var (args, kwargs) = Utils.SplitArguments(arguments); - - return Call(compiler, args, kwargs); - } - - public CompilerObject Call(Compiler.Compiler compiler, Args args, KwArgs kwArgs) - { - // TODO: type checking (when type system is implemented) - - IRCode - argsCode = new(), varArgsCode = new(), - kwArgsCode = new(), varKwArgsCode = new(); - - if (args.Count > Signature.Args.Count) - if (Signature.VarArgs is null) - throw new($"Function {Name} takes {Signature.Args.Count} arguments, but {args.Count} were given."); - else - throw new NotImplementedException("var args"); - else if (args.Count < Signature.Args.Count) - throw new($"Function {Name} takes {Signature.Args.Count} arguments, but {args.Count} were given."); - - for (int i = 0; i < Signature.Args.Count; i++) - argsCode.Append(compiler.CompileIRCode(args[i])); - - if (kwArgs.Count > Signature.KwArgs.Count) - if (Signature.VarKwArgs is null) - throw new($"Function {Name} takes {Signature.KwArgs.Count} keyword arguments, but {kwArgs.Count} were given."); - else - throw new NotImplementedException("var kwargs"); - else if (kwArgs.Count < Signature.KwArgs.Count) - throw new($"Function {Name} takes {Signature.KwArgs.Count} keyword arguments, but {kwArgs.Count} were given."); - - foreach (var kwArgParameter in Signature.KwArgs) - kwArgsCode.Append(compiler.CompileIRCode(kwArgs[kwArgParameter.Name])); - - IRCode result = new(); - result.Append(argsCode); - result.Append(varArgsCode); // should be empty - result.Append(kwArgsCode); - result.Append(varKwArgsCode); // should be empty - - result.Instructions.Add(new IR.VM.Call(IR!)); - - result.Types.Clear(); - if (ReturnType != compiler.TypeSystem.Void) - result.Types.Add(ReturnType ?? throw new()); // TODO: WTF?????? This is here because the - // IR -> CG loader is not yet implemented. - - result.MaxStackSize = Math.Max(result.MaxStackSize, result.Types.Count); - - return new RawCode(result); - } - - IRCode ICTReadable.Read(Compiler.Compiler compiler) - => new([ - new IR.VM.GetObject(IR!) - ]) - { - Types = [null!], // TODO: fix type - }; - - public IR.Function CompileIRObject(Compiler.Compiler compiler, IR.Module? owner) - { - IR ??= new(compiler.CompileIRType(ReturnType ?? throw new())) - { - Name = Name - }; - - if (owner is not null && !IsOwnerBuilt) - { - owner.Functions.Add(IR); - - IsOwnerBuilt = true; - } - - if (!IsSignatureBuilt) - { - foreach (var arg in Signature.Args) - IR.Signature.Args.Parameters.Add(compiler.CompileIRObject(arg, IR.Signature)); - - if (Signature.VarArgs is not null) - IR.Signature.Args.Var = compiler.CompileIRObject(Signature.VarArgs, IR.Signature); - - foreach (var kwArg in Signature.KwArgs) - IR.Signature.KwArgs.Parameters.Add(compiler.CompileIRObject(kwArg, IR.Signature)); - - if (Signature.VarKwArgs is not null) - IR.Signature.KwArgs.Var = compiler.CompileIRObject(Signature.VarKwArgs, IR.Signature); - - IsSignatureBuilt = true; - } - - if (Body is not null && !IsBodyBuilt) - { - IR.Body.Instructions.AddRange(compiler.CompileIRCode(Body).Instructions); - - IsBodyBuilt = true; - } - - // TODO: compile signature - - return IR; - } - } -} diff --git a/ZSharp.Compiler/cg objects/functional/signature/Parameter.cs b/ZSharp.Compiler/cg objects/functional/signature/Parameter.cs deleted file mode 100644 index 08e8101e..00000000 --- a/ZSharp.Compiler/cg objects/functional/signature/Parameter.cs +++ /dev/null @@ -1,37 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Parameter(string name) - : CompilerObject - , ICTReadable - , ICompileIRObject - { - public IR.Parameter? IR { get; set; } - - public string Name { get; } = name; - - public CompilerObject? Type { get; set; } - - public CompilerObject? Initializer { get; set; } - - public IR.Parameter CompileIRObject(Compiler.Compiler compiler, IR.Signature? owner) - { - if (Type is null) - throw new("Parameter type not set."); - - IR ??= new(Name, compiler.CompileIRType(Type)); - - return IR; - } - - public IRCode Read(Compiler.Compiler compiler) - => new([ - new IR.VM.GetArgument(IR!), - ]) - { - MaxStackSize = 1, - Types = [Type ?? throw new()] - }; - } -} diff --git a/ZSharp.Compiler/cg objects/functional/signature/Signature.cs b/ZSharp.Compiler/cg objects/functional/signature/Signature.cs deleted file mode 100644 index 8313ef23..00000000 --- a/ZSharp.Compiler/cg objects/functional/signature/Signature.cs +++ /dev/null @@ -1,17 +0,0 @@ -using ZSharp.Compiler; - -using Parameters = CommonZ.Utils.Collection; - -namespace ZSharp.Objects -{ - public sealed class Signature : CompilerObject - { - public Parameters Args { get; init; } = []; - - public Parameter? VarArgs { get; set; } - - public Parameters KwArgs { get; init; } = []; - - public Parameter? VarKwArgs { get; set; } - } -} diff --git a/ZSharp.Compiler/cg objects/imports/Import.cs b/ZSharp.Compiler/cg objects/imports/Import.cs deleted file mode 100644 index 4b922d13..00000000 --- a/ZSharp.Compiler/cg objects/imports/Import.cs +++ /dev/null @@ -1,13 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Import : CompilerObject - { - public required List Arguments { get; set; } - - public required List ImportedNames { get; set; } - - public string? Alias { get; set; } - } -} diff --git a/ZSharp.Compiler/cg objects/imports/ImportedName.cs b/ZSharp.Compiler/cg objects/imports/ImportedName.cs deleted file mode 100644 index f092aeb3..00000000 --- a/ZSharp.Compiler/cg objects/imports/ImportedName.cs +++ /dev/null @@ -1,11 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class ImportedName : CompilerObject - { - public required string Name { get; set; } - - public string? Alias { get; set; } - } -} diff --git a/ZSharp.Compiler/cg objects/literals/FalseLiteral.cs b/ZSharp.Compiler/cg objects/literals/FalseLiteral.cs deleted file mode 100644 index 247839d5..00000000 --- a/ZSharp.Compiler/cg objects/literals/FalseLiteral.cs +++ /dev/null @@ -1,20 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class FalseLiteral(CompilerObject type) - : CompilerObject - , ICTReadable - { - public CompilerObject Type { get; } = type; - - public IRCode Read(Compiler.Compiler compiler) - => new([ - new IR.VM.PutFalse() - ]) - { - MaxStackSize = 1, - Types = [Type] - }; - } -} diff --git a/ZSharp.Compiler/cg objects/literals/Float32Literal.cs b/ZSharp.Compiler/cg objects/literals/Float32Literal.cs deleted file mode 100644 index 1fb47b0d..00000000 --- a/ZSharp.Compiler/cg objects/literals/Float32Literal.cs +++ /dev/null @@ -1,22 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Float32Literal(float value, CompilerObject type) - : Literal(value) - , ICTReadable - { - public override CompilerObject Type { get; } = type; - - public override IRCode Read(Compiler.Compiler compiler) - => new( - [ - new IR.VM.PutFloat32(Value) - ] - ) - { - MaxStackSize = 1, - Types = [Type] - }; - } -} diff --git a/ZSharp.Compiler/cg objects/literals/IntegerLiteral.cs b/ZSharp.Compiler/cg objects/literals/IntegerLiteral.cs deleted file mode 100644 index d8c6b9f8..00000000 --- a/ZSharp.Compiler/cg objects/literals/IntegerLiteral.cs +++ /dev/null @@ -1,22 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class IntegerLiteral(DefaultIntegerType value, CompilerObject type) - : Literal(value) - , ICTReadable - { - public override CompilerObject Type { get; } = type; - - public override IRCode Read(Compiler.Compiler compiler) - => new( - [ - new IR.VM.PutInt32(Value) - ] - ) - { - MaxStackSize = 1, - Types = [Type] - }; - } -} diff --git a/ZSharp.Compiler/cg objects/literals/Literal.cs b/ZSharp.Compiler/cg objects/literals/Literal.cs deleted file mode 100644 index 6aac5f3b..00000000 --- a/ZSharp.Compiler/cg objects/literals/Literal.cs +++ /dev/null @@ -1,21 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public abstract class Literal(object? value) - : CompilerObject - , ICTReadable - { - public abstract CompilerObject Type { get; } - - public object? Value { get; } = value; - - public abstract IRCode Read(Compiler.Compiler compiler); - } - - public abstract class Literal(T value) - : Literal(value) - { - public new T Value => (T)base.Value!; - } -} diff --git a/ZSharp.Compiler/cg objects/literals/NullLiteral.cs b/ZSharp.Compiler/cg objects/literals/NullLiteral.cs deleted file mode 100644 index 9fb03011..00000000 --- a/ZSharp.Compiler/cg objects/literals/NullLiteral.cs +++ /dev/null @@ -1,18 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class NullLiteral(CompilerObject type) : Literal(null) - { - public override CompilerObject Type { get; } = type; - - public override IRCode Read(Compiler.Compiler compiler) - => new([ - new IR.VM.PutNull() - ]) - { - MaxStackSize = 1, - Types = [Type] - }; - } -} diff --git a/ZSharp.Compiler/cg objects/literals/StringLiteral.cs b/ZSharp.Compiler/cg objects/literals/StringLiteral.cs deleted file mode 100644 index cda5c3a2..00000000 --- a/ZSharp.Compiler/cg objects/literals/StringLiteral.cs +++ /dev/null @@ -1,19 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class StringLiteral(string value, CompilerObject type) - : Literal(value) - { - public override CompilerObject Type { get; } = type; - - public override IRCode Read(Compiler.Compiler compiler) - => new([ - new IR.VM.PutString(Value) - ]) - { - MaxStackSize = 1, - Types = [Type] - }; - } -} diff --git a/ZSharp.Compiler/cg objects/literals/TrueLiteral.cs b/ZSharp.Compiler/cg objects/literals/TrueLiteral.cs deleted file mode 100644 index af0d4905..00000000 --- a/ZSharp.Compiler/cg objects/literals/TrueLiteral.cs +++ /dev/null @@ -1,20 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class TrueLiteral(CompilerObject type) - : CompilerObject - , ICTReadable - { - public CompilerObject Type { get; } = type; - - public IRCode Read(Compiler.Compiler compiler) - => new([ - new IR.VM.PutTrue() - ]) - { - MaxStackSize = 1, - Types = [Type] - }; - } -} diff --git a/ZSharp.Compiler/cg objects/modular/Global.cs b/ZSharp.Compiler/cg objects/modular/Global.cs deleted file mode 100644 index 434dfc2d..00000000 --- a/ZSharp.Compiler/cg objects/modular/Global.cs +++ /dev/null @@ -1,99 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Global(string name) - : CompilerObject - , ICTAssignable - , ICTReadable - , ICompileIRObject - { - [Flags] - enum BuildState - { - None = 0, - Owner = 0b1, - Initializer = 0b10, - } - - private BuildState _state = BuildState.None; - - public IR.Global? IR { get; set; } - - public string Name { get; } = name; - - public bool IsReadOnly { get; set; } - - public bool IsOwnerBuilt - { - get => _state.HasFlag(BuildState.Owner); - set => _state = value ? _state | BuildState.Owner : _state & ~BuildState.Owner; - } - - public bool IsInitializerBuilt - { - get => _state.HasFlag(BuildState.Initializer); - set => _state = value ? _state | BuildState.Initializer : _state & ~BuildState.Initializer; - } - - public CompilerObject? Initializer { get; set; } - - public CompilerObject? Type { get; set; } - - public IR.Global CompileIRObject(Compiler.Compiler compiler, IR.Module? owner) - { - if (Type is null) - throw new(); - - IR ??= new(Name, compiler.CompileIRType(Type)); - - if (!IsOwnerBuilt && owner is not null) - { - owner.Globals.Add(IR!); - - IsOwnerBuilt = true; - } - - if (!IsInitializerBuilt && Initializer is not null) - { - IR.Initializer = compiler.CompileIRCode(Initializer).Instructions.ToArray(); - - IsInitializerBuilt = true; - } - - return IR; - } - - public IRCode Read(Compiler.Compiler compiler) - => new([new IR.VM.GetGlobal(IR!)]) - { - MaxStackSize = 1, - Types = [Type], - }; - - public CompilerObject Assign(Compiler.Compiler compiler, CompilerObject value) - { - if (IsReadOnly) - throw new(); - - if (Type is null) - throw new(); - - IR = compiler.CompileIRObject(this, null); - - var cast = compiler.Cast(value, Type); - var code = compiler.CompileIRCode(cast); - - code.Instructions.AddRange( - [ - new IR.VM.Dup(), - new IR.VM.SetGlobal(IR), - ] - ); - - code.RequireValueType(); - - return new RawCode(code); - } - } -} diff --git a/ZSharp.Compiler/cg objects/modular/Module.cs b/ZSharp.Compiler/cg objects/modular/Module.cs deleted file mode 100644 index 30402b34..00000000 --- a/ZSharp.Compiler/cg objects/modular/Module.cs +++ /dev/null @@ -1,52 +0,0 @@ -using CommonZ.Utils; -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Module(string name) - : CompilerObject - , ICTGetMember - , ICTReadable - , ICompileIRObject - { - CompilerObject ITyped.Type => throw new NotImplementedException(); - - public Collection Content { get; } = []; - - public Mapping Members { get; } = []; - - public Collection ImportedMembers { get; } = []; - - public IR.Module? IR { get; set; } - - public RTFunction InitFunction { get; } = new(null); - - public string? Name { get; set; } = name; - - public CompilerObject Member(Compiler.Compiler compiler, string member) - => Members[member]; - - IRCode ICTReadable.Read(Compiler.Compiler compiler) - => new([ - new IR.VM.GetObject(IR!) - ]) - { - Types = [null!], // TODO: fix type - }; - - public IR.Module CompileIRObject(Compiler.Compiler compiler, IR.Module? owner) - { - if (IR is not null) - return IR; - - IR = new(Name); - - owner?.Submodules.Add(IR); - - foreach (var item in Content) - compiler.CompileIRObject(item, IR); - - return IR; - } - } -} diff --git a/ZSharp.Compiler/cg objects/modular/ModuleMember.cs b/ZSharp.Compiler/cg objects/modular/ModuleMember.cs deleted file mode 100644 index 39d41f32..00000000 --- a/ZSharp.Compiler/cg objects/modular/ModuleMember.cs +++ /dev/null @@ -1,11 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public abstract class ModuleMember - : CompilerObject - //, IImportable - { - public required Module Module { get; init; } - } -} diff --git a/ZSharp.Compiler/cg objects/oop/Constructor.cs b/ZSharp.Compiler/cg objects/oop/Constructor.cs deleted file mode 100644 index b95456c0..00000000 --- a/ZSharp.Compiler/cg objects/oop/Constructor.cs +++ /dev/null @@ -1,70 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Constructor(string? name) - : CompilerObject - , ICTCallable - { - public IR.Constructor? IR { get; set; } - - public string? Name { get; set; } = name; - - public Signature Signature { get; set; } = new(); - - public Class? Owner { get; set; } - - public CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) - { - var (args, kwArgs) = Utils.SplitArguments(arguments); - - return Call(compiler, args, kwArgs); - } - - public CompilerObject Call(Compiler.Compiler compiler, Args args, KwArgs kwArgs) - { - // TODO: type checking (when type system is implemented) - - IRCode - argsCode = new(), varArgsCode = new(), - kwArgsCode = new(), varKwArgsCode = new(); - - if (args.Count > Signature.Args.Count) - if (Signature.VarArgs is null) - throw new($"Function {Name} takes {Signature.Args.Count} arguments, but {args.Count} were given."); - else - throw new NotImplementedException("var args"); - else if (args.Count < Signature.Args.Count) - throw new($"Function {Name} takes {Signature.Args.Count} arguments, but {args.Count} were given."); - - for (int i = 0; i < Signature.Args.Count; i++) - argsCode.Append(compiler.CompileIRCode(args[i])); - - if (kwArgs.Count > Signature.KwArgs.Count) - if (Signature.VarKwArgs is null) - throw new($"Function {Name} takes {Signature.KwArgs.Count} keyword arguments, but {kwArgs.Count} were given."); - else - throw new NotImplementedException("var kwargs"); - else if (kwArgs.Count < Signature.KwArgs.Count) - throw new($"Function {Name} takes {Signature.KwArgs.Count} keyword arguments, but {kwArgs.Count} were given."); - - foreach (var kwArgParameter in Signature.KwArgs) - kwArgsCode.Append(compiler.CompileIRCode(kwArgs[kwArgParameter.Name])); - - IRCode result = new(); - result.Append(argsCode); - result.Append(varArgsCode); // should be empty - result.Append(kwArgsCode); - result.Append(varKwArgsCode); // should be empty - - result.Instructions.Add(new IR.VM.CreateInstance(IR!)); - - result.Types.Clear(); - result.Types.Add(Owner ?? throw new()); - - result.MaxStackSize = Math.Max(result.MaxStackSize, result.Types.Count); - - return new RawCode(result); - } - } -} diff --git a/ZSharp.Compiler/cg objects/oop/class/IClass.cs b/ZSharp.Compiler/cg objects/oop/class/IClass.cs deleted file mode 100644 index 2e57d2e5..00000000 --- a/ZSharp.Compiler/cg objects/oop/class/IClass.cs +++ /dev/null @@ -1,13 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.Objects -{ - public interface IClass - { - public string? Name { get; } - - public IClass? Base { get; } - - //public Collection InterfaceImplementations { get; } - } -} diff --git a/ZSharp.Compiler/cg objects/oop/field/BoundField.cs b/ZSharp.Compiler/cg objects/oop/field/BoundField.cs deleted file mode 100644 index c48b48db..00000000 --- a/ZSharp.Compiler/cg objects/oop/field/BoundField.cs +++ /dev/null @@ -1,48 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class BoundField(Field field, CompilerObject instance) - : CompilerObject - , ICTAssignable - , ICTReadable - { - public Field Field { get; } = field; - - public CompilerObject Instance { get; } = instance; - - public CompilerObject? Type => Field.Type; - - public CompilerObject Assign(Compiler.Compiler compiler, CompilerObject value) - { - var instanceCode = compiler.CompileIRCode(Instance); - var valueCode = compiler.CompileIRCode(value); - - return new RawCode(new([ - ..valueCode.Instructions, - new IR.VM.Dup(), - ..instanceCode.Instructions, - new IR.VM.Swap(), - new IR.VM.SetField(Field.IR!), - ]) - { - MaxStackSize = Math.Max(Math.Max(instanceCode.MaxStackSize, valueCode.MaxStackSize), 2), - Types = [Type] - }); - } - - public IRCode Read(Compiler.Compiler compiler) - { - var code = compiler.CompileIRCode(Instance); - - return new([ - ..code.Instructions, - new IR.VM.GetField(Field.IR!) - ]) - { - MaxStackSize = Math.Max(code.MaxStackSize, 1), - Types = [Type] - }; - } - } -} diff --git a/ZSharp.Compiler/cg objects/oop/field/Field.cs b/ZSharp.Compiler/cg objects/oop/field/Field.cs deleted file mode 100644 index 00a413c9..00000000 --- a/ZSharp.Compiler/cg objects/oop/field/Field.cs +++ /dev/null @@ -1,26 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Field(string name) - : CompilerObject - , ICTReadable - , IRTBoundMember - { - public IR.Field? IR { get; set; } - - public string Name { get; set; } = name; - - public CompilerObject? Initializer { get; set; } - - public CompilerObject? Type { get; set; } - - public CompilerObject Bind(Compiler.Compiler compiler, CompilerObject value) - => new BoundField(this, value); - - public IRCode Read(Compiler.Compiler compiler) - { - throw new NotImplementedException(); - } - } -} diff --git a/ZSharp.Compiler/cg objects/oop/method/BoundMethod.cs b/ZSharp.Compiler/cg objects/oop/method/BoundMethod.cs deleted file mode 100644 index 3f6f99b1..00000000 --- a/ZSharp.Compiler/cg objects/oop/method/BoundMethod.cs +++ /dev/null @@ -1,16 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - internal sealed class BoundMethod(Method method, CompilerObject instance) - : CompilerObject - , ICTCallable - { - public Method Method { get; } = method; - - public CompilerObject Instance { get; } = instance; - - public CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) - => compiler.Call(Method, [new(Instance), .. arguments]); - } -} diff --git a/ZSharp.Compiler/cg objects/oop/method/Method.cs b/ZSharp.Compiler/cg objects/oop/method/Method.cs deleted file mode 100644 index 670aa62a..00000000 --- a/ZSharp.Compiler/cg objects/oop/method/Method.cs +++ /dev/null @@ -1,74 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Method(string? name) - : CompilerObject - , IRTBoundMember - , ICTCallable - { - public IR.Method? IR { get; set; } - - public string? Name { get; set; } = name; - - public Signature Signature { get; set; } = new(); - - public CompilerObject? ReturnType { get; set; } - - public CompilerObject Bind(Compiler.Compiler compiler, CompilerObject value) - => new BoundMethod(this, value); - - public CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) - { - var (args, kwargs) = Utils.SplitArguments(arguments); - - return Call(compiler, args, kwargs); - } - - public CompilerObject Call(Compiler.Compiler compiler, Args args, KwArgs kwArgs) - { - // TODO: type checking (when type system is implemented) - - IRCode - argsCode = new(), varArgsCode = new(), - kwArgsCode = new(), varKwArgsCode = new(); - - if (args.Count > Signature.Args.Count) - if (Signature.VarArgs is null) - throw new($"Function {Name} takes {Signature.Args.Count} arguments, but {args.Count} were given."); - else - throw new NotImplementedException("var args"); - else if (args.Count < Signature.Args.Count) - throw new($"Function {Name} takes {Signature.Args.Count} arguments, but {args.Count} were given."); - - for (int i = 0; i < Signature.Args.Count; i++) - argsCode.Append(compiler.CompileIRCode(args[i])); - - if (kwArgs.Count > Signature.KwArgs.Count) - if (Signature.VarKwArgs is null) - throw new($"Function {Name} takes {Signature.KwArgs.Count} keyword arguments, but {kwArgs.Count} were given."); - else - throw new NotImplementedException("var kwargs"); - else if (kwArgs.Count < Signature.KwArgs.Count) - throw new($"Function {Name} takes {Signature.KwArgs.Count} keyword arguments, but {kwArgs.Count} were given."); - - foreach (var kwArgParameter in Signature.KwArgs) - kwArgsCode.Append(compiler.CompileIRCode(kwArgs[kwArgParameter.Name])); - - IRCode result = new(); - result.Append(argsCode); - result.Append(varArgsCode); // should be empty - result.Append(kwArgsCode); - result.Append(varKwArgsCode); // should be empty - - result.Instructions.Add(new IR.VM.Call(IR!)); - - result.Types.Clear(); - result.Types.Add(ReturnType ?? throw new()); - - result.MaxStackSize = Math.Max(result.MaxStackSize, result.Types.Count); - - return new RawCode(result); - } - } -} diff --git a/ZSharp.Compiler/cg objects/overloading/IOverload.cs b/ZSharp.Compiler/cg objects/overloading/IOverload.cs deleted file mode 100644 index 823c551d..00000000 --- a/ZSharp.Compiler/cg objects/overloading/IOverload.cs +++ /dev/null @@ -1,16 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public interface IOverload - { - /// - /// Match the given arguments to this overload. - /// If the arguments don't match, return null. - /// - /// The arguments to match. - /// A describing how to pass the arguments - /// to the overload if the arguments match the overload, otherwise - //public OverloadMatchResult? Match(Compiler.Compiler compiler, Argument[] arguments); - } -} diff --git a/ZSharp.Compiler/cg objects/overloading/SimpleFunctionOverloadGroup.cs b/ZSharp.Compiler/cg objects/overloading/SimpleFunctionOverloadGroup.cs deleted file mode 100644 index 5567a4c5..00000000 --- a/ZSharp.Compiler/cg objects/overloading/SimpleFunctionOverloadGroup.cs +++ /dev/null @@ -1,48 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class SimpleFunctionOverloadGroup(string name) - : CompilerObject - , ICTCallable - { - public string Name { get; set; } = name; - - public List Overloads { get; } = []; - - public CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) - { - var (args, kwargs) = Utils.SplitArguments(arguments); - - CompilerObject? Match(RTFunction overload) - { - if (args.Count != overload.Signature.Args.Count) return null; - if (kwargs.Count != overload.Signature.KwArgs.Count) return null; - - foreach (var (arg, param) in args.Zip(overload.Signature.Args)) - { - var code = compiler.CompileIRCode(arg); - - if (compiler.CompileIRType(code.RequireValueType()) != compiler.CompileIRType(param.Type)) return null; - } - - foreach (var param in overload.Signature.KwArgs) - { - if (!kwargs.TryGetValue(param.Name, out var arg)) return null; - - var code = compiler.CompileIRCode(arg); - - if (compiler.CompileIRType(code.RequireValueType()) != compiler.CompileIRType(param.Type)) return null; - } - - return (overload as ICTCallable).Call(compiler, arguments); // TODO: overloading protocol????? - } - - var matchingOverloads = Overloads.Select(Match).Where(c => c is not null).ToList()!; - - if (matchingOverloads.Count != 1) throw new(); - - return matchingOverloads[0]!; - } - } -} diff --git a/ZSharp.Compiler/cg objects/raw/RawCode.cs b/ZSharp.Compiler/cg objects/raw/RawCode.cs deleted file mode 100644 index 301120cd..00000000 --- a/ZSharp.Compiler/cg objects/raw/RawCode.cs +++ /dev/null @@ -1,21 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class RawCode(IRCode code) - : CompilerObject - , ICTReadable - { - private readonly IRCode code = code; - - public IRCode Code => code; - - public CompilerObject Type => code.RequireValueType(); - - public IRCode Read(Compiler.Compiler _) - => code; - - CompilerObject ITyped.GetType(Compiler.Compiler compiler) - => code.IsVoid ? compiler.TypeSystem.Void : code.RequireValueType(); - } -} diff --git a/ZSharp.Compiler/cg objects/raw/RawType.cs b/ZSharp.Compiler/cg objects/raw/RawType.cs deleted file mode 100644 index 2e60a403..00000000 --- a/ZSharp.Compiler/cg objects/raw/RawType.cs +++ /dev/null @@ -1,27 +0,0 @@ -using ZSharp.Compiler; -using ZSharp.IR; - -namespace ZSharp.Objects -{ - public sealed class RawType(IRType type, CompilerObject metaType) - : CompilerObject - , ICTReadable - , ICompileIRType - { - private IRType type = type; - - public CompilerObject Type { get; internal set; } = metaType; - - public IType CompileIRType(Compiler.Compiler compiler) - => type; - - public IRCode Read(Compiler.Compiler compiler) - => type is IRObject ir ? new([ - new IR.VM.GetObject(ir) - ]) - { - MaxStackSize = 1, - Types = [Type] - } : throw new(); - } -} diff --git a/ZSharp.Compiler/cg objects/types/Int32Type.cs b/ZSharp.Compiler/cg objects/types/Int32Type.cs deleted file mode 100644 index 7ee4d8c6..00000000 --- a/ZSharp.Compiler/cg objects/types/Int32Type.cs +++ /dev/null @@ -1,23 +0,0 @@ -using CommonZ.Utils; -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Int32Type(IR.Class ir, CompilerObject type) - : CompilerObject - , ICompileIRType - , ICTGetMember - { - public IR.Class IR { get; } = ir; - - public CompilerObject Type { get; } = type; - - public Mapping Members { get; } = []; - - public IRType CompileIRType(Compiler.Compiler compiler) - => IR; - - public CompilerObject Member(Compiler.Compiler compiler, string member) - => Members[member]; - } -} diff --git a/ZSharp.Compiler/cg objects/types/StringType.cs b/ZSharp.Compiler/cg objects/types/StringType.cs deleted file mode 100644 index 546c39d7..00000000 --- a/ZSharp.Compiler/cg objects/types/StringType.cs +++ /dev/null @@ -1,27 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class StringType(IR.Class stringType, CompilerObject type) - : CompilerObject - , ICompileIRType - , ICTCallable - { - public IR.Class IR { get; } = stringType; - - public CompilerObject Type { get; } = type; - - public new CompilerObject ToString { get; set; } = null!; - - public CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) - { - if (arguments.Length != 1) - throw new(); - - return compiler.Call(ToString, arguments); - } - - public IRType CompileIRType(Compiler.Compiler compiler) - => IR; - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/Compiler.Evaluate.cs b/ZSharp.Compiler/compiler core/compiler/Compiler.Evaluate.cs deleted file mode 100644 index f664f43b..00000000 --- a/ZSharp.Compiler/compiler core/compiler/Compiler.Evaluate.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - public List Evaluators { get; } = []; - - public CompilerObject Evaluate(CompilerObject @object) - { - CompilerObject result = @object; - - foreach (var evaluator in Evaluators) - if ((result = evaluator.Evaluate(result)) != @object) break; - - //while (@object == result) - //{ - // foreach (var evaluator in Evaluators) - // if ((result = evaluator.Evaluate(result)) != @object) goto loopAgain; - - // break; - - // loopAgain: continue; - //} - - return result; - } - - private void InitializeEvaluators() - { - Evaluators.Add(new DefaultEvaluator(this)); - } - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/Compiler.Features.cs b/ZSharp.Compiler/compiler core/compiler/Compiler.Features.cs deleted file mode 100644 index d5dc22b0..00000000 --- a/ZSharp.Compiler/compiler core/compiler/Compiler.Features.cs +++ /dev/null @@ -1,25 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - private readonly Mapping features = []; - - private void InitializeFeatures() - { - - } - - public T Feature() - where T : class - => (T)features[typeof(T)]; - - public void Feature(T feature) - where T : Feature - => features[typeof(T)] = feature; - - public void Feature(Feature feature) - => features[feature.GetType()] = feature; - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/Compiler.IR.cs b/ZSharp.Compiler/compiler core/compiler/Compiler.IR.cs deleted file mode 100644 index 75c00026..00000000 --- a/ZSharp.Compiler/compiler core/compiler/Compiler.IR.cs +++ /dev/null @@ -1,60 +0,0 @@ -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - public IR.RuntimeModule RuntimeModule { get; } - - public IRCode CompileIRCode(CompilerObject @object) - { - if (@object is ICompileIRCode irCode) - return irCode.CompileIRCode(this); - - if (@object is ICTReadable ctReadable) - return ctReadable.Read(this); - - throw new NotImplementedException(); // TODO: return null - } - - public IR.IRObject CompileIRObject(CompilerObject @object) - { - if (@object is ICompileIRObject irObject) - return irObject.CompileIRObject(this); - - return CompileIRObject(@object, null); - } - - public IR.IRObject CompileIRObject(CompilerObject @object, Owner? owner) - where Owner : IR.IRObject - { - if (@object is ICompileIRObject irObject) - return irObject.CompileIRObject(this, owner); - - throw new NotImplementedException(); // TODO: return null - } - - public T CompileIRObject(CompilerObject @object, Owner? owner) - where T : IR.IRObject - where Owner : class - { - if (@object is ICompileIRObject irObject) - return irObject.CompileIRObject(this, owner); - - throw new NotImplementedException(); // TODO: return null - } - - public IRType CompileIRType(CompilerObject @object) - { - ICompileIRType? irType; - - if ((irType = @object as ICompileIRType) is not null) - return irType.CompileIRType(this); - - @object = Evaluate(@object); - - if ((irType = @object as ICompileIRType) is not null) - return irType.CompileIRType(this); - - throw new NotImplementedException(); // TODO: return null - } - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/Compiler.cs b/ZSharp.Compiler/compiler core/compiler/Compiler.cs deleted file mode 100644 index 1cf91e3c..00000000 --- a/ZSharp.Compiler/compiler core/compiler/Compiler.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - public Compiler() - : this(IR.RuntimeModule.Standard) { } - - public Compiler(IR.RuntimeModule runtimeModule) - { - RuntimeModule = runtimeModule; - - TypeSystem = new(this); - - Initialize(); - } - - private void Initialize() - { - InitializeTypeSystem(); - InitializeLiterals(); - InitializeFeatures(); - InitializeEvaluators(); - } - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/features/Compiler.Protocols.cs b/ZSharp.Compiler/compiler core/compiler/features/Compiler.Protocols.cs deleted file mode 100644 index 084c29aa..00000000 --- a/ZSharp.Compiler/compiler core/compiler/features/Compiler.Protocols.cs +++ /dev/null @@ -1,119 +0,0 @@ -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - public CompilerObject Assign(CompilerObject target, CompilerObject value) - { - if (target is ICTAssignable ctAssignable) - return ctAssignable.Assign(this, value); - - throw new NotImplementedException(); - } - - // TODO: WTH is this? - public IRCode Assign(IRCode irCode, Assignment assignment) - => throw new NotImplementedException(); - - public CompilerObject Call(CompilerObject target, Argument[] arguments) - { - if (target is ICTCallable ctCallable) - return ctCallable.Call(this, arguments); - - if (target is ICTReadable readable) - if (readable.Type is IRTCallable rtCallable) - return rtCallable.Call(this, target, arguments); - - // implements typeclass Callable? - - // overloads call operator? - - throw new("Object of this type is not callable."); - } - - public CompilerObject Cast(CompilerObject target, CompilerObject type) - { - if (TypeSystem.IsTyped(target, out var targetType) && targetType == type) - return target; - - if (target is ICTTypeCast typeCast) - return typeCast.Cast(this, type); - - throw new NotImplementedException(); - } - - /// - /// The get index ([]) operator. - /// - /// - /// - /// - public CompilerObject Index(CompilerObject instanceTarget, Argument[] index) - { - throw new NotImplementedException(); - } - - /// - /// The set index ([]=) operator. - /// - /// - /// - /// - /// - public CompilerObject Index(CompilerObject instanceTarget, Argument[] index, CompilerObject value) - { - throw new NotImplementedException(); - } - - /// - /// The member (.) operator. - /// - /// - /// - /// - public CompilerObject Member(CompilerObject instance, MemberIndex index) - { - throw new NotImplementedException(); - } - - /// - /// The set member (.=) operator. - /// - /// - /// - /// - /// - public CompilerObject Member(CompilerObject instance, MemberIndex index, CompilerObject value) - { - throw new NotImplementedException(); - } - - /// - /// The member (.) operator. - /// - /// - /// - /// - public CompilerObject Member(CompilerObject instance, MemberName member) - { - if (instance is ICTGetMember ctGetMember) - return ctGetMember.Member(this, member); - - if (instance is ICTReadable readable && readable.Type is IRTGetMember rtGetMember) - return rtGetMember.Member(this, instance, member); - - throw new NotImplementedException(); - } - - /// - /// The set member (.=) operator. - /// - /// - /// - /// - /// - public CompilerObject Member(CompilerObject instance, MemberName member, CompilerObject value) - { - throw new NotImplementedException(); - } - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/features/Compiler.TypeSystem.cs b/ZSharp.Compiler/compiler core/compiler/features/Compiler.TypeSystem.cs deleted file mode 100644 index 69250a98..00000000 --- a/ZSharp.Compiler/compiler core/compiler/features/Compiler.TypeSystem.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - public TypeSystem TypeSystem { get; } - - private void InitializeTypeSystem() - { - - } - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/literals/Compiler.Create.cs b/ZSharp.Compiler/compiler core/compiler/literals/Compiler.Create.cs deleted file mode 100644 index e7348a34..00000000 --- a/ZSharp.Compiler/compiler core/compiler/literals/Compiler.Create.cs +++ /dev/null @@ -1,36 +0,0 @@ -using CommonZ.Utils; -using ZSharp.Objects; - -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - private readonly Mapping nullLiterals = []; - - public CompilerObject CreateTrue() - => trueObject; - - public CompilerObject CreateFalse() - => falseObject; - - public CompilerObject CreateFloat32(float value) - => new Float32Literal(value, TypeSystem.Float32); - - public CompilerObject CreateInteger(DefaultIntegerType value) - => new IntegerLiteral(value, TypeSystem.Int32); // TODO: fix type here - - public CompilerObject CreateString(string value) - => new StringLiteral(value, TypeSystem.String); - - public CompilerObject CreateNull() - => CreateNull(TypeSystem.Null); - - public CompilerObject CreateNull(CompilerObject type) - { - if (!nullLiterals.TryGetValue(type, out var nullLiteral)) - nullLiterals[type] = nullLiteral = new(type); - - return nullLiteral; - } - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/literals/Compiler.Is.cs b/ZSharp.Compiler/compiler core/compiler/literals/Compiler.Is.cs deleted file mode 100644 index 34a875e3..00000000 --- a/ZSharp.Compiler/compiler core/compiler/literals/Compiler.Is.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using ZSharp.Objects; - -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - public bool IsLiteral(CompilerObject @object) - => @object is Literal; - - public bool IsLiteral(CompilerObject @object, [NotNullWhen(true)] out Literal? result) - => (@object is Literal literal - ? (result = literal) - : (result = null) - ) is not null; - - public bool IsLiteral(CompilerObject @object, [NotNullWhen(true)] out T? value) - where T : struct - { - value = default; - - if (!IsLiteral(@object, out Literal? literal)) return false; - - if (literal.Value is not T literalValue) return false; - - value = literalValue; - - return true; - } - - public bool IsLiteral(CompilerObject @object, [NotNullWhen(true)] out T? value) - where T : class - { - if (!IsLiteral(@object, out Literal? literal)) return (value = null) is not null; - - if (literal.Value is not T literalValue) return (value = null) is not null; - - return (value = literalValue) is not null; - } - - /// - /// Checks if the given object is a literal string and unpacks it. - /// - /// - /// - /// - public bool IsString(CompilerObject @object, [NotNullWhen(true)] out string? value) - { - if (IsLiteral(@object, out value)) return true; - - throw new NotImplementedException(); - } - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/literals/Compiler.Literals.cs b/ZSharp.Compiler/compiler core/compiler/literals/Compiler.Literals.cs deleted file mode 100644 index a6491d40..00000000 --- a/ZSharp.Compiler/compiler core/compiler/literals/Compiler.Literals.cs +++ /dev/null @@ -1,15 +0,0 @@ -using ZSharp.Objects; - -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - private CompilerObject trueObject = null!, falseObject = null!; - - private void InitializeLiterals() - { - trueObject = new TrueLiteral(TypeSystem.Boolean); - falseObject = new FalseLiteral(TypeSystem.Boolean); - } - } -} diff --git a/ZSharp.Compiler/compiler core/compiler/value/Compiler.IsCT.cs b/ZSharp.Compiler/compiler core/compiler/value/Compiler.IsCT.cs deleted file mode 100644 index 2e290ad8..00000000 --- a/ZSharp.Compiler/compiler core/compiler/value/Compiler.IsCT.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace ZSharp.Compiler -{ - public sealed partial class Compiler - { - public bool IsCTValue(CompilerObject @object) - { - if (IsLiteral(@object)) return true; - - return false; // TODO: implement the CTValue protocol - } - - public bool IsCTValue(CompilerObject @object, [NotNullWhen(true)] out T? value) - where T : class - { - if (IsLiteral(@object, out value)) return true; - - return false; // TODO: implement CTValue protocol - } - - public bool IsCTValue(CompilerObject @object, [NotNullWhen(true)] out T? value) - where T : struct - { - if (IsLiteral(@object, out value)) return true; - - return false; // TODO: implement CTValue protocol - } - } -} diff --git a/ZSharp.Compiler/compiler core/core/Feature.cs b/ZSharp.Compiler/compiler core/core/Feature.cs deleted file mode 100644 index 7fb05137..00000000 --- a/ZSharp.Compiler/compiler core/core/Feature.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace ZSharp.Compiler -{ - public abstract class Feature - { - public Compiler Compiler { get; } - - public Feature(Compiler compiler) - { - Compiler = compiler; - - compiler.Feature(this); - } - } -} diff --git a/ZSharp.Compiler/compiler core/core/ObjectCache.cs b/ZSharp.Compiler/compiler core/core/ObjectCache.cs deleted file mode 100644 index d14bb329..00000000 --- a/ZSharp.Compiler/compiler core/core/ObjectCache.cs +++ /dev/null @@ -1,67 +0,0 @@ -using CommonZ.Utils; -using System.Diagnostics.CodeAnalysis; - -namespace ZSharp.Compiler -{ - internal sealed class ObjectCache() - { - private readonly Cache cgCache = []; - private readonly Cache irCache = []; - - public ObjectCache(ObjectCache parent) - : this() - { - cgCache = new() - { - Parent = parent.cgCache, - }; - irCache = new() - { - Parent = parent.irCache, - }; - } - - public CompilerObject? CG(IR.IRObject ir) - => cgCache.Cache(ir); - - public bool CG(IR.IRObject ir, [NotNullWhen(true)] out CompilerObject? cg) - => cgCache.Cache(ir, out cg); - - public bool CG(IR.IRObject ir, [NotNullWhen(true)] out T? cg) - where T : CompilerObject - => cgCache.Cache(ir, out cg); - - - public CompilerObject CG(IR.IRObject ir, CompilerObject cg) - => CG(ir, cg); - - public T CG(IR.IRObject ir, T cg) - where T : CompilerObject - { - cgCache.Cache(ir, cg); - irCache.Cache(cg, ir); - return cg; - } - - public IR.IRObject? IR(CompilerObject cg) - => irCache.Cache(cg); - - public bool IR(CompilerObject cg, [NotNullWhen(true)] out IR.IRObject? ir) - => irCache.Cache(cg, out ir); - - public bool IR(CompilerObject cg, [NotNullWhen(true)] out T? ir) - where T : IR.IRObject - => irCache.Cache(cg, out ir); - - public IR.IRObject IR(CompilerObject cg, IR.IRObject ir) - => IR(cg, ir); - - public T IR(CompilerObject cg, T ir) - where T : IR.IRObject - { - irCache.Cache(cg, ir); - cgCache.Cache(ir, cg); - return ir; - } - } -} diff --git a/ZSharp.Compiler/compiler core/core/evaluation/DefaultEvaluator.cs b/ZSharp.Compiler/compiler core/core/evaluation/DefaultEvaluator.cs deleted file mode 100644 index d93367a3..00000000 --- a/ZSharp.Compiler/compiler core/core/evaluation/DefaultEvaluator.cs +++ /dev/null @@ -1,9 +0,0 @@ - -namespace ZSharp.Compiler -{ - internal sealed class DefaultEvaluator(Compiler compiler) : Evaluator - { - public override CompilerObject Evaluate(CompilerObject @object) - => @object is IEvaluable evaluable ? evaluable.Evaluate(compiler) : @object; - } -} diff --git a/ZSharp.Compiler/compiler core/core/evaluation/Evaluator.cs b/ZSharp.Compiler/compiler core/core/evaluation/Evaluator.cs deleted file mode 100644 index 49e40b5c..00000000 --- a/ZSharp.Compiler/compiler core/core/evaluation/Evaluator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler -{ - public abstract class Evaluator - { - public abstract CompilerObject Evaluate(CompilerObject @object); - } -} diff --git a/ZSharp.Compiler/compiler core/core/type system/ITypeModifier.cs b/ZSharp.Compiler/compiler core/core/type system/ITypeModifier.cs deleted file mode 100644 index 42938a30..00000000 --- a/ZSharp.Compiler/compiler core/core/type system/ITypeModifier.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler -{ - public interface ITypeModifier - { - public CompilerObject InnerType { get; } - } -} diff --git a/ZSharp.Compiler/compiler core/core/type system/TypeSystem.cs b/ZSharp.Compiler/compiler core/core/type system/TypeSystem.cs deleted file mode 100644 index 0c8ff6a6..00000000 --- a/ZSharp.Compiler/compiler core/core/type system/TypeSystem.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using ZSharp.Objects; - -namespace ZSharp.Compiler -{ - public sealed class TypeSystem - : Feature - { - public StringType String { get; } - - public CompilerObject Type { get; } - - public CompilerObject Void { get; } - - public CompilerObject Null { get; } - - public CompilerObject Boolean { get; } - - public Int32Type Int32 { get; } - - public CompilerObject Float32 { get; } - - internal TypeSystem(Compiler compiler) - : base(compiler) - { - Type = new Objects.Type(compiler.RuntimeModule.TypeSystem.Type); - - String = new(compiler.RuntimeModule.TypeSystem.String, Type); - Void = new RawType(compiler.RuntimeModule.TypeSystem.Void, Type); - Null = new RawType(compiler.RuntimeModule.TypeSystem.Null, Type); - Boolean = new RawType(compiler.RuntimeModule.TypeSystem.Boolean, Type); - Int32 = new Int32Type(compiler.RuntimeModule.TypeSystem.Int32, Type); - Float32 = new RawType(compiler.RuntimeModule.TypeSystem.Float32, Type); - } - - public CompilerObject EvaluateType(CompilerObject @object) - => Compiler.Evaluate(@object); - - public CompilerObject Array(CompilerObject type) - => throw new NotImplementedException(); - - public CompilerObject Pointer(CompilerObject type) - => throw new NotImplementedException(); - - public CompilerObject Reference(CompilerObject type) - => throw new NotImplementedException(); - - public bool IsTyped(CompilerObject @object) - { - throw new NotImplementedException(); - } - - public bool IsTyped(CompilerObject @object, [NotNullWhen(true)] out CompilerObject? type) - { - if (@object is ITyped typed) - return (type = typed.GetType(Compiler)) is not null; - - return (type = null) is not null; - } - - public bool IsTypeModifier(CompilerObject @object) - { - throw new NotImplementedException(); - } - - public bool IsTypeModifier(CompilerObject @object, [NotNullWhen(true)] out CompilerObject? type) - { - throw new NotImplementedException(); - } - } -} diff --git a/ZSharp.Compiler/compiler/Compiler.Context.cs b/ZSharp.Compiler/compiler/Compiler.Context.cs new file mode 100644 index 00000000..7509b7dd --- /dev/null +++ b/ZSharp.Compiler/compiler/Compiler.Context.cs @@ -0,0 +1,20 @@ +using CommonZ.Utils; + +namespace ZSharp.Compiler +{ + public sealed partial class Compiler + { + public IContext CurrentContext { get; private set; } = new EmptyContext(); + + public Action UseContext(IContext context) + { + (CurrentContext, context) = (context, CurrentContext); + CurrentContext.Parent ??= context; + + return () => CurrentContext = context; + } + + public ContextManager ContextScope(IContext context) + => new(UseContext(context)); + } +} diff --git a/ZSharp.Compiler/compiler core/compiler/Compiler.Logging.cs b/ZSharp.Compiler/compiler/Compiler.Logging.cs similarity index 67% rename from ZSharp.Compiler/compiler core/compiler/Compiler.Logging.cs rename to ZSharp.Compiler/compiler/Compiler.Logging.cs index cd374302..8efe38a5 100644 --- a/ZSharp.Compiler/compiler core/compiler/Compiler.Logging.cs +++ b/ZSharp.Compiler/compiler/Compiler.Logging.cs @@ -1,4 +1,6 @@ -namespace ZSharp.Compiler +using ZSharp.Logging; + +namespace ZSharp.Compiler { public sealed partial class Compiler { diff --git a/ZSharp.Compiler/compiler/Compiler.Services.cs b/ZSharp.Compiler/compiler/Compiler.Services.cs new file mode 100644 index 00000000..2023e0c2 --- /dev/null +++ b/ZSharp.Compiler/compiler/Compiler.Services.cs @@ -0,0 +1,27 @@ +namespace ZSharp.Compiler +{ + public sealed partial class Compiler + { + private CG cg = new(); + private Evaluator evaluator = new(); + private IR ir = new(runtimeModule); + private OOP oop = new(); + private Overloading overloading = new(); + private Reflection reflection = new(); + private TS ts = new(); + + public ref CG CG => ref cg; + + public ref Evaluator Evaluator => ref evaluator; + + public ref IR IR => ref ir; + + public ref OOP OOP => ref oop; + + public ref Reflection Reflection => ref reflection; + + public ref TS TS => ref ts; + + //public TS TypeSystem { init => ts = value; } + } +} diff --git a/ZSharp.Compiler/compiler/Compiler.cs b/ZSharp.Compiler/compiler/Compiler.cs new file mode 100644 index 00000000..f81a36ed --- /dev/null +++ b/ZSharp.Compiler/compiler/Compiler.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Compiler +{ + public sealed partial class Compiler(ZSharp.IR.RuntimeModule runtimeModule) + { + public ZSharp.IR.RuntimeModule RuntimeModule { get; } = runtimeModule; + + public Compiler() + : this(ZSharp.IR.RuntimeModule.Standard) { } + } +} diff --git a/ZSharp.Compiler/core/CompilerObject.cs b/ZSharp.Compiler/core/CompilerObject.cs deleted file mode 100644 index 69be0950..00000000 --- a/ZSharp.Compiler/core/CompilerObject.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ZSharp.Objects -{ - public abstract class CompilerObject - { - } -} diff --git a/ZSharp.Compiler/core/concepts/callable/ICallable.cs b/ZSharp.Compiler/core/concepts/callable/ICallable.cs deleted file mode 100644 index e8b76dfe..00000000 --- a/ZSharp.Compiler/core/concepts/callable/ICallable.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace ZSharp.Compiler -{ - /// - /// Should be implemented by any binding that is callable. - /// - public interface ICTCallable - { - public CompilerObject Call(Compiler compiler, Argument[] arguments); - } - - /// - /// Should be implementedby any type that is callable. - /// - public interface IRTCallable - { - public CompilerObject Call(Compiler compiler, CompilerObject callable, Argument[] arguments); - } -} diff --git a/ZSharp.Compiler/core/concepts/index/IGetIndex.cs b/ZSharp.Compiler/core/concepts/index/IGetIndex.cs deleted file mode 100644 index 450ddbd7..00000000 --- a/ZSharp.Compiler/core/concepts/index/IGetIndex.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler -{ - internal interface IGetIndex - { - public CompilerObject Index(T @object, Argument[] index); - } -} diff --git a/ZSharp.Compiler/core/concepts/index/ISetIndex.cs b/ZSharp.Compiler/core/concepts/index/ISetIndex.cs deleted file mode 100644 index fc9d622b..00000000 --- a/ZSharp.Compiler/core/concepts/index/ISetIndex.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler -{ - internal interface ISetIndex - { - public CompilerObject Index(T @object, Argument[] index, CompilerObject value); - } -} diff --git a/ZSharp.Compiler/core/concepts/member/IGetMember.cs b/ZSharp.Compiler/core/concepts/member/IGetMember.cs deleted file mode 100644 index 99815eee..00000000 --- a/ZSharp.Compiler/core/concepts/member/IGetMember.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ZSharp.Compiler -{ - public interface ICTGetMember - { - public CompilerObject Member(Compiler compiler, M member); - } - - public interface IRTGetMember - { - public CompilerObject Member(Compiler compiler, CompilerObject value, M member); - } -} diff --git a/ZSharp.Compiler/core/concepts/member/ISetMember.cs b/ZSharp.Compiler/core/concepts/member/ISetMember.cs deleted file mode 100644 index 6bffcfc8..00000000 --- a/ZSharp.Compiler/core/concepts/member/ISetMember.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler -{ - internal interface ISetMember - { - public CompilerObject Member(T @object, M member, CompilerObject value); - } -} diff --git a/ZSharp.Compiler/core/concepts/value/IEvaluable.cs b/ZSharp.Compiler/core/concepts/value/IEvaluable.cs deleted file mode 100644 index 1e2d564d..00000000 --- a/ZSharp.Compiler/core/concepts/value/IEvaluable.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler -{ - public interface IEvaluable - { - public CompilerObject Evaluate(Compiler compiler); - } -} diff --git a/ZSharp.Compiler/core/concepts/value/IReadable.cs b/ZSharp.Compiler/core/concepts/value/IReadable.cs deleted file mode 100644 index cbd3fd65..00000000 --- a/ZSharp.Compiler/core/concepts/value/IReadable.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace ZSharp.Compiler -{ - public interface ICTReadable - : ITyped - { - public IRCode Cast(Compiler compiler, CompilerObject type) - => this is ICTTypeCast typeCast - && typeCast.Cast(compiler, type) is ICTReadable readable - ? readable.Read(compiler, type) - : throw new NotImplementedException(); - - public IRCode Read(Compiler compiler, CompilerObject? @as) - { - if (@as is null || @as == Type) - return Read(compiler); - return Cast(compiler, @as); - } - - public IRCode Read(Compiler compiler); - } -} diff --git a/ZSharp.Compiler/core/concepts/value/ITypeCast.cs b/ZSharp.Compiler/core/concepts/value/ITypeCast.cs deleted file mode 100644 index 21a0e9ad..00000000 --- a/ZSharp.Compiler/core/concepts/value/ITypeCast.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ZSharp.Compiler -{ - public interface ICTTypeCast - { - public CompilerObject Cast(Compiler compiler, CompilerObject targetType); - } - - public interface IRTTypeCast - { - public CompilerObject Cast(Compiler compiler, CompilerObject @object, CompilerObject targetType); - } -} diff --git a/ZSharp.Compiler/core/concepts/value/assignment/Assignment.cs b/ZSharp.Compiler/core/concepts/value/assignment/Assignment.cs deleted file mode 100644 index 06bf1cb5..00000000 --- a/ZSharp.Compiler/core/concepts/value/assignment/Assignment.cs +++ /dev/null @@ -1,92 +0,0 @@ -namespace ZSharp.Compiler -{ - public enum AssignmentType - { - Incompatible = 0, - Unspecified = 1, - Exact = 2, - Polymorphic = 3, - DirectImplementation = 4, - ExternalImplementation = 5, - ImplicitCast = 6, - ExplicitCast = 7, - Any = -1, - } - - public abstract class Assignment - { - public abstract AssignmentType AssignmentType { get; } - - public static Assignment Incompatible { get; } = new Incompatible(); - - public static Assignment Unspecified { get; } = new Unspecified(); - - public static Assignment Exact { get; } = new Polymorphic(0); - - public static Assignment Any { get; } = new Polymorphic(-1); - - public static Polymorphic Polymorphic(int distance) - => new(distance); - - public static DirectImplementation DirectImplementation(int distance) - => new(distance); - - public static ExternalImplementation ExternalImplementation(int distance) - => new(distance); - - public static ImplicitCast ImplicitCast(CompilerObject castFunction) - => new(castFunction); - - public static ExplicitCast ExplicitCast(CompilerObject castFunction) - => new(castFunction); - } - - public sealed class Incompatible : Assignment - { - public override AssignmentType AssignmentType => AssignmentType.Incompatible; - - internal Incompatible() { } - } - - public sealed class Unspecified : Assignment - { - public override AssignmentType AssignmentType => AssignmentType.Unspecified; - - internal Unspecified() { } - } - - public sealed class Polymorphic(int distance) : Assignment - { - public override AssignmentType AssignmentType - => Distance == 0 ? AssignmentType.Exact : AssignmentType.Polymorphic; - - public int Distance { get; } = distance; - } - - public sealed class DirectImplementation(int distance) : Assignment - { - public override AssignmentType AssignmentType => AssignmentType.DirectImplementation; - - public int Distance { get; } = distance; - } - - public sealed class ExternalImplementation(int distance) : Assignment - { - public override AssignmentType AssignmentType => AssignmentType.ExternalImplementation; - - public int Distance { get; } = distance; - } - - public abstract class Cast(CompilerObject castFunction, AssignmentType assignmentType) : Assignment - { - public override AssignmentType AssignmentType => assignmentType; - - public CompilerObject CastFunction { get; } = castFunction; - } - - public sealed class ImplicitCast(CompilerObject castFunction) - : Cast(castFunction, AssignmentType.ImplicitCast); - - public sealed class ExplicitCast(CompilerObject castFunction) - : Cast(castFunction, AssignmentType.ExplicitCast); -} diff --git a/ZSharp.Compiler/core/concepts/value/assignment/IAssignable.cs b/ZSharp.Compiler/core/concepts/value/assignment/IAssignable.cs deleted file mode 100644 index 4ed88c26..00000000 --- a/ZSharp.Compiler/core/concepts/value/assignment/IAssignable.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ZSharp.Compiler -{ - public interface ICTAssignable - { - public CompilerObject Assign(Compiler compiler, CompilerObject value); - } - - public interface IRTAssignable - { - public CompilerObject Assign(Compiler compiler, CompilerObject @object, CompilerObject value); - } -} diff --git a/ZSharp.Compiler/core/context/EmptyContext.cs b/ZSharp.Compiler/core/context/EmptyContext.cs new file mode 100644 index 00000000..07074fc1 --- /dev/null +++ b/ZSharp.Compiler/core/context/EmptyContext.cs @@ -0,0 +1,12 @@ +namespace ZSharp.Compiler +{ + internal sealed class EmptyContext + : IContext + { + IContext? IContext.Parent + { + get => null; + set => throw new InvalidOperationException("Empty context cannot be mounted."); + } + } +} diff --git a/ZSharp.Compiler/core/logging/LoggerExtensions.cs b/ZSharp.Compiler/core/logging/LoggerExtensions.cs new file mode 100644 index 00000000..9217bd8d --- /dev/null +++ b/ZSharp.Compiler/core/logging/LoggerExtensions.cs @@ -0,0 +1,19 @@ +using ZSharp.Logging; + +namespace ZSharp.Compiler +{ + public static class LoggerExtensions + { + public static void Info(this Logger logger, T message, CompilerObject origin) + => logger.Log(new() { Message = message, Level = LogLevel.Info, Origin = Origin(origin) }); + + public static void Warning(this Logger logger, T message, CompilerObject origin) + => logger.Log(new() { Message = message, Level = LogLevel.Warning, Origin = Origin(origin) }); + + public static void Error(this Logger logger, T message, CompilerObject origin) + => logger.Log(new() { Message = message, Level = LogLevel.Error, Origin = Origin(origin) }); + + public static LogOrigin Origin(CompilerObject @object) + => new ObjectLogOrigin(@object); + } +} diff --git a/ZSharp.Compiler/compiler core/core/logging/ObjectLogOrigin.cs b/ZSharp.Compiler/core/logging/ObjectLogOrigin.cs similarity index 79% rename from ZSharp.Compiler/compiler core/core/logging/ObjectLogOrigin.cs rename to ZSharp.Compiler/core/logging/ObjectLogOrigin.cs index 88ad73ea..fe6496f2 100644 --- a/ZSharp.Compiler/compiler core/core/logging/ObjectLogOrigin.cs +++ b/ZSharp.Compiler/core/logging/ObjectLogOrigin.cs @@ -1,4 +1,6 @@ -namespace ZSharp.Compiler +using ZSharp.Logging; + +namespace ZSharp.Compiler { internal sealed class ObjectLogOrigin(CompilerObject @object) : LogOrigin { diff --git a/ZSharp.Compiler/features/compile-time values/Array.cs b/ZSharp.Compiler/features/compile-time values/Array.cs deleted file mode 100644 index 10c40035..00000000 --- a/ZSharp.Compiler/features/compile-time values/Array.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Objects -{ - public sealed class Array - { - - } -} diff --git a/ZSharp.Compiler/features/oop/extensibility/IClass.cs b/ZSharp.Compiler/features/oop/extensibility/IClass.cs deleted file mode 100644 index d62ce67f..00000000 --- a/ZSharp.Compiler/features/oop/extensibility/IClass.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace ZSharp.Compiler -{ - internal interface IClass - { - public CompilerObject Meta { get; } - - public string Name { get; } - } -} diff --git a/ZSharp.Compiler/features/oop/extensibility/IMetaClass.cs b/ZSharp.Compiler/features/oop/extensibility/IMetaClass.cs deleted file mode 100644 index 47ec116f..00000000 --- a/ZSharp.Compiler/features/oop/extensibility/IMetaClass.cs +++ /dev/null @@ -1,39 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public interface IMetaClass : ICTCallable - { - CompilerObject ICTCallable.Call(Compiler.Compiler compiler, Argument[] arguments) - { - if (arguments.Length != 3) - throw new($"Metaclass may only be called with exactly 3 arguments"); - - foreach (var argument in arguments) - if (argument.Name is not null) - throw new($"Metaclass's arguments must not have names"); - - if (!compiler.IsCTValue(arguments[0].Object, out var name)) - throw new($"Metaclass's first argument must be a string literal"); - - if (!compiler.IsCTValue(arguments[1].Object, out var bases)) - throw new($"Metaclass's second argument must be an array of bases"); - - if (!compiler.IsCTValue(arguments[2].Object, out var content)) - throw new($"Metaclass's third argument must be an array of content"); - - return Construct(compiler, name, bases, content); - } - - public CompilerObject Construct(Compiler.Compiler compiler, string name, CompilerObject[] bases, CompilerObject[]? content); - } - - public interface IMetaClass : IMetaClass - where T : CompilerObject - { - CompilerObject IMetaClass.Construct(Compiler.Compiler compiler, string name, CompilerObject[] bases, CompilerObject[]? content) - => Construct(compiler, name, bases, content); - - public new T Construct(Compiler.Compiler compiler, string name, CompilerObject[] bases, CompilerObject[]? content); - } -} diff --git a/ZSharp.Compiler/features/oop/extensibility/IRTBoundMember.cs b/ZSharp.Compiler/features/oop/extensibility/IRTBoundMember.cs deleted file mode 100644 index 61b007ad..00000000 --- a/ZSharp.Compiler/features/oop/extensibility/IRTBoundMember.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Objects -{ - public interface IRTBoundMember - { - public CompilerObject Bind(Compiler.Compiler compiler, CompilerObject value); - } -} diff --git a/ZSharp.Compiler/features/oop/objects/class/Class.cs b/ZSharp.Compiler/features/oop/objects/class/Class.cs deleted file mode 100644 index bfb3c0bc..00000000 --- a/ZSharp.Compiler/features/oop/objects/class/Class.cs +++ /dev/null @@ -1,54 +0,0 @@ -using CommonZ.Utils; -using ZSharp.Compiler; - -namespace ZSharp.Objects -{ - public sealed class Class - : CompilerObject - , ICTGetMember - , IRTGetMember - , ICTCallable - { - public Mapping Members { get; } = []; - - public IR.Class? IR { get; set; } - - public string? Name { get; set; } - - public Class? Base { get; set; } - - //public SimpleFunctionOverloadGroup? Constructor { get; set; } - - public Constructor? Constructor { get; set; } - - public Constructor? EmptyConstructor { get; set; } - - public Method? ClassConstructor { get; set; } - - public CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) - { - if (arguments.Length == 0) - if (EmptyConstructor is null) throw new InvalidOperationException(); - else return compiler.Call(EmptyConstructor, arguments); - - return new RawCode( - new([ - new IR.VM.CreateInstance(Constructor!.IR!) - ]) - { - MaxStackSize = 1, - Types = [this] - }); - } - - //public List? Interfaces { get; set; } - - public CompilerObject Member(Compiler.Compiler compiler, MemberName member) - => Members[member]; - - public CompilerObject Member(Compiler.Compiler compiler, CompilerObject value, MemberName member) - => Member(compiler, member) is IRTBoundMember rtBoundMember - ? rtBoundMember.Bind(compiler, value) - : throw new NotImplementedException(); - } -} diff --git a/ZSharp.Compiler/features/oop/objects/class/ClassBase.cs b/ZSharp.Compiler/features/oop/objects/class/ClassBase.cs deleted file mode 100644 index 12274daf..00000000 --- a/ZSharp.Compiler/features/oop/objects/class/ClassBase.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace ZSharp.Objects -{ - public abstract class ClassBase - : CompilerObject - { - - } -} diff --git a/ZSharp.Compiler/features/oop/objects/class/ClassMeta.cs b/ZSharp.Compiler/features/oop/objects/class/ClassMeta.cs deleted file mode 100644 index d00142ce..00000000 --- a/ZSharp.Compiler/features/oop/objects/class/ClassMeta.cs +++ /dev/null @@ -1,60 +0,0 @@ -namespace ZSharp.Objects -{ - /// - /// This class's instance defines the metaclass which all regular classes are - /// instances of. - /// - public sealed class ClassMeta - : CompilerObject - , IMetaClass - { - public Class DefaultBaseClass { get; set; } = new() - { - Name = "Object" - }; - - public Class Construct(Compiler.Compiler compiler, string name, CompilerObject[] bases, CompilerObject[]? content) - { - var result = new Class() - { - Name = name - }; - - bases = bases.Select(compiler.Evaluate).ToArray(); - - int baseIndex = 0; - - if (bases.Length > 1 && bases[0] is Class @base) - { - result.Base = @base; - baseIndex = 1; - } - else result.Base = DefaultBaseClass; - - for (int i = baseIndex; i < bases.Length; i++) - { - throw new NotImplementedException(); - //if (bases[i] is Interface @interface) - // throw new NotImplementedException(); - //else if (compiler.TypeSystem.IsTypeModifier(bases[i], out Class? inlineBase)) - // throw new NotImplementedException(); - } - - // TODO: prepare the class content - - if (FindSubclassInitializer(result.Base) is CompilerObject subclassInitializer) - compiler.Evaluate(compiler.Call(subclassInitializer, [new(result)])); - - return result; - } - - private CompilerObject? FindSubclassInitializer(Class? @base) - { - //while (@base is not null) - // if (@base.SubclassInitializer is not null) return @base.SubclassInitializer; - // else @base = @base.Base; - - return null; - } - } -} diff --git a/ZSharp.Compiler/ir generator/IRCodeGenerator.cs b/ZSharp.Compiler/ir generator/IRCodeGenerator.cs deleted file mode 100644 index 6f23b14d..00000000 --- a/ZSharp.Compiler/ir generator/IRCodeGenerator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler -{ - public sealed class IRCodeGenerator - { - // TODO: implement this class - } -} diff --git a/ZSharp.Compiler/ir generator/protocols/ICompileIRCode.cs b/ZSharp.Compiler/ir generator/protocols/ICompileIRCode.cs deleted file mode 100644 index fe879117..00000000 --- a/ZSharp.Compiler/ir generator/protocols/ICompileIRCode.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler -{ - public interface ICompileIRCode - { - public IRCode CompileIRCode(Compiler compiler); - } -} diff --git a/ZSharp.Compiler/ir generator/protocols/ICompileIRObject.cs b/ZSharp.Compiler/ir generator/protocols/ICompileIRObject.cs deleted file mode 100644 index a7fe7cde..00000000 --- a/ZSharp.Compiler/ir generator/protocols/ICompileIRObject.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace ZSharp.Compiler -{ - public interface ICompileIRObject - { - public IR.IRObject CompileIRObject(Compiler compiler); - } - - public interface ICompileIRObject : ICompileIRObject - where Owner : class - { - public IR.IRObject CompileIRObject(Compiler compiler, Owner? owner); - - IR.IRObject ICompileIRObject.CompileIRObject(Compiler compiler) - => CompileIRObject(compiler, null); - } - - public interface ICompileIRObject : ICompileIRObject - where T : IR.IRObject - where Owner : class - { - public new T CompileIRObject(Compiler compiler, Owner? owner); - - IR.IRObject ICompileIRObject.CompileIRObject(Compiler compiler, Owner? owner) - => CompileIRObject(compiler, owner); - } -} diff --git a/ZSharp.Compiler/ir generator/protocols/ICompileIRType.cs b/ZSharp.Compiler/ir generator/protocols/ICompileIRType.cs deleted file mode 100644 index 7e19a6fe..00000000 --- a/ZSharp.Compiler/ir generator/protocols/ICompileIRType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Compiler -{ - public interface ICompileIRType - { - public IRType CompileIRType(Compiler compiler); - } -} diff --git a/ZSharp.IR/ZSharp.IR.csproj b/ZSharp.IR/ZSharp.IR.csproj index 055aa435..1884a869 100644 --- a/ZSharp.IR/ZSharp.IR.csproj +++ b/ZSharp.IR/ZSharp.IR.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable diff --git a/ZSharp.IR/core/IModuleMember.cs b/ZSharp.IR/core/IModuleMember.cs new file mode 100644 index 00000000..e84b1bea --- /dev/null +++ b/ZSharp.IR/core/IModuleMember.cs @@ -0,0 +1,7 @@ +namespace ZSharp.IR +{ + public interface IModuleMember + { + public Module? Module { get; } + } +} diff --git a/ZSharp.IR/core/IRDefinition.cs b/ZSharp.IR/core/IRDefinition.cs new file mode 100644 index 00000000..4c51f85f --- /dev/null +++ b/ZSharp.IR/core/IRDefinition.cs @@ -0,0 +1,7 @@ +namespace ZSharp.IR +{ + public abstract class IRDefinition + { + + } +} diff --git a/ZSharp.IR/core/IRObject.cs b/ZSharp.IR/core/IRObject.cs deleted file mode 100644 index d4310c1d..00000000 --- a/ZSharp.IR/core/IRObject.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.IR -{ - public abstract class IRObject - { - public abstract Module? Module { get; } - } -} diff --git a/ZSharp.IR/ir/GenericParameter.cs b/ZSharp.IR/ir/GenericParameter.cs deleted file mode 100644 index dbf30386..00000000 --- a/ZSharp.IR/ir/GenericParameter.cs +++ /dev/null @@ -1,13 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.IR -{ - public class GenericParameter - { - public string Name { get; set; } - - public GenericParameterAttributes Attributes { get; set; } = GenericParameterAttributes.None; - - //public Collection Constraints { get; set; } - } -} diff --git a/ZSharp.IR/ir/custom metadata/CustomMetadata.cs b/ZSharp.IR/ir/custom metadata/CustomMetadata.cs new file mode 100644 index 00000000..28438ff8 --- /dev/null +++ b/ZSharp.IR/ir/custom metadata/CustomMetadata.cs @@ -0,0 +1,9 @@ +namespace ZSharp.IR +{ + public sealed class CustomMetadata + { + public ICallable Constructor { get; set; } + + public object[] Arguments { get; set; } + } +} diff --git a/ZSharp.IR/ir/custom metadata/ICustomMetadataProvider.cs b/ZSharp.IR/ir/custom metadata/ICustomMetadataProvider.cs new file mode 100644 index 00000000..440f682c --- /dev/null +++ b/ZSharp.IR/ir/custom metadata/ICustomMetadataProvider.cs @@ -0,0 +1,11 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + public interface ICustomMetadataProvider + { + public Collection CustomMetadata { get; } + + public bool HasCustomMetadata => CustomMetadata.Count > 0; + } +} diff --git a/ZSharp.IR/ir/functional/ConstructedFunction.cs b/ZSharp.IR/ir/functional/ConstructedFunction.cs new file mode 100644 index 00000000..715dff19 --- /dev/null +++ b/ZSharp.IR/ir/functional/ConstructedFunction.cs @@ -0,0 +1,18 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + public sealed class ConstructedFunction(Function function) + : ICallable + { + public Function Function { get; set; } = function; + + public Collection Arguments { get; set; } = function.HasGenericParameters ? [] : Collection.Empty; + + public Signature Signature { get; init; } = function.Signature; + + public bool HasBody => Function.HasBody; + + public ICallableBody? Body => Function.HasBody ? Function.Body : null; + } +} diff --git a/ZSharp.IR/ir/functional/Function.cs b/ZSharp.IR/ir/functional/Function.cs index f50292f1..23010600 100644 --- a/ZSharp.IR/ir/functional/Function.cs +++ b/ZSharp.IR/ir/functional/Function.cs @@ -1,4 +1,6 @@ -namespace ZSharp.IR +using CommonZ.Utils; + +namespace ZSharp.IR { public class Function : ModuleMember @@ -7,6 +9,8 @@ public class Function private Signature _signature; private VM.FunctionBody? _body; + private Collection? _genericParameters; + public string? Name { get; set; } public FunctionAttributes Attributes { get; set; } = FunctionAttributes.None; @@ -45,6 +49,20 @@ public VM.FunctionBody Body public bool HasBody => _body is not null; + public Collection GenericParameters + { + get + { + if (_genericParameters is not null) + return _genericParameters; + + Interlocked.CompareExchange(ref _genericParameters, [], null); + return _genericParameters; + } + } + + public bool HasGenericParameters => !_genericParameters.IsNullOrEmpty(); + //public Collection Clauses { get; } public Function(IType returnType) diff --git a/ZSharp.IR/vm/code/FunctionBody.cs b/ZSharp.IR/ir/functional/FunctionBody.cs similarity index 100% rename from ZSharp.IR/vm/code/FunctionBody.cs rename to ZSharp.IR/ir/functional/FunctionBody.cs diff --git a/ZSharp.IR/ir/modular/module/Module.cs b/ZSharp.IR/ir/modular/module/Module.cs index 5d2a5e38..95a00867 100644 --- a/ZSharp.IR/ir/modular/module/Module.cs +++ b/ZSharp.IR/ir/modular/module/Module.cs @@ -1,19 +1,37 @@ using CommonZ.Utils; +using System.Diagnostics.CodeAnalysis; namespace ZSharp.IR { - public sealed class Module(string? name) : ModuleMember + public sealed class Module(string? name) : IRDefinition { + private Function? _initializer; + private Function? _entryPoint; private ModuleCollection? _importedModules; private ModuleCollection? _functions; private GlobalCollection? _globals; - private ModuleCollection? _submodules; - private ModuleCollection? _types; + private ModuleCollection? _types; public string? Name { get; set; } = name; public ModuleAttributes Attributes { get; set; } = ModuleAttributes.None; + public Function? Initializer + { + get => _initializer; + set + { + if (value is not null) + { + if (value.Module is null) + Functions.Add(value); + else if (value.Module != this) + throw new InvalidOperationException("Module initializer cannot reside in a different module."); + _initializer = value; + } + } + } + public Collection ImportedModules { get @@ -28,6 +46,24 @@ public Collection ImportedModules public bool HasImportedModules => !_importedModules.IsNullOrEmpty(); + public Function? EntryPoint + { + get => _entryPoint; + set + { + if (value is not null && value.Module != this) + throw new InvalidOperationException( + "Module entry point must be a strict member of the" + + "module." + ); + + _entryPoint = value; + } + } + + [MemberNotNullWhen(true, nameof(EntryPoint))] + public bool HasEntryPoint => _entryPoint is not null; + public Collection Functions { get @@ -56,21 +92,7 @@ public Collection Globals public bool HasGlobals => !_globals.IsNullOrEmpty(); - public Collection Submodules - { - get - { - if (_submodules is not null) - return _submodules; - - Interlocked.CompareExchange(ref _submodules, new(this), null); - return _submodules; - } - } - - public bool HasSubmodules => !_submodules.IsNullOrEmpty(); - - public Collection Types + public Collection Types { get { diff --git a/ZSharp.IR/ir/modular/module/ModuleCollection.cs b/ZSharp.IR/ir/modular/module/ModuleCollection.cs index 1114346d..efe26b63 100644 --- a/ZSharp.IR/ir/modular/module/ModuleCollection.cs +++ b/ZSharp.IR/ir/modular/module/ModuleCollection.cs @@ -11,24 +11,24 @@ public override void OnAdd(T item) { AssertUnOwned(item); - item.Owner = Module; + item.Module = Module; } public override void OnInsert(int index, T item) { AssertUnOwned(item); - item.Owner = Module; + item.Module = Module; } public override void OnRemove(T item) { - item.Owner = null; + item.Module = null; } public override void OnRemoveAt(int index) { - this[index].Owner = null; + this[index].Module = null; } private void AssertUnOwned(T item) diff --git a/ZSharp.IR/ir/modular/module/ModuleMember.cs b/ZSharp.IR/ir/modular/module/ModuleMember.cs index 2b5f4f2c..af376a20 100644 --- a/ZSharp.IR/ir/modular/module/ModuleMember.cs +++ b/ZSharp.IR/ir/modular/module/ModuleMember.cs @@ -1,22 +1,9 @@ namespace ZSharp.IR { - public abstract class ModuleMember : IRObject + public abstract class ModuleMember + : IRDefinition + , IModuleMember { - private Module? _module; - - public override Module? Module => _module; - - public Module? Owner - { - get => _module; - internal set => _module = value; - } - - public ModuleMember() { } - - public ModuleMember(Module module) - { - _module = module; - } + public Module? Module { get; internal set; } } } diff --git a/ZSharp.IR/ir/oop/Class.cs b/ZSharp.IR/ir/oop/Class.cs deleted file mode 100644 index 0f954792..00000000 --- a/ZSharp.IR/ir/oop/Class.cs +++ /dev/null @@ -1,47 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.IR -{ - public sealed class Class(string? name) : OOPType - { - private FieldCollection? _fields; - - public string? Name { get; set; } = name; - - public ClassAttributes Attributes { get; set; } = ClassAttributes.None; - - public Class? Base { get; set; } - - public Class(string? name, Class? @base) - : this(name) - { - Base = @base; - } - - public Collection InterfacesImplementations { get; } = []; - - public Collection Fields - { - get - { - if (_fields is not null) - return _fields; - - Interlocked.CompareExchange(ref _fields, new(this), null); - return _fields; - } - } - - public bool HasFields => !_fields.IsNullOrEmpty(); - - public Collection Methods { get; } = []; - - public Collection Properties { get; } = []; - - //public Collection NestedTypes { get; } = new(); - - //public Collection Events { get; } - - public Collection Constructors { get; } = []; - } -} diff --git a/ZSharp.IR/ir/oop/Constructor.cs b/ZSharp.IR/ir/oop/Constructor.cs deleted file mode 100644 index 2becbdb2..00000000 --- a/ZSharp.IR/ir/oop/Constructor.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace ZSharp.IR -{ - public sealed class Constructor(string? name) - { - public string? Name { get; set; } = name; - - public Method Method { get; set; } - } -} diff --git a/ZSharp.IR/ir/oop/Dataclass.cs b/ZSharp.IR/ir/oop/Dataclass.cs index e82de4ba..a3efe174 100644 --- a/ZSharp.IR/ir/oop/Dataclass.cs +++ b/ZSharp.IR/ir/oop/Dataclass.cs @@ -2,15 +2,15 @@ namespace ZSharp.IR { - public sealed class Dataclass + public sealed class Dataclass : TypeDefinition { public string? Name { get; set; } public DataclassAttributes Attributes { get; set; } = DataclassAttributes.None; - public Dataclass? Base { get; set; } + public TypeReference? Base { get; set; } - public Collection TypeClasses { get; } + public Collection> TypeClasses { get; } public Collection Constructors { get; } } diff --git a/ZSharp.IR/ir/oop/Enumclass.cs b/ZSharp.IR/ir/oop/Enumclass.cs deleted file mode 100644 index e74c8c95..00000000 --- a/ZSharp.IR/ir/oop/Enumclass.cs +++ /dev/null @@ -1,15 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.IR -{ - public sealed class Enumclass : OOPType - { - public string? Name { get; set; } - - public EnumclassAttributes Attributes { get; set; } = EnumclassAttributes.None; - - public IType Type { get; set; } - - //public Collection Values { get; } - } -} diff --git a/ZSharp.IR/ir/oop/Structure.cs b/ZSharp.IR/ir/oop/Structure.cs index 49c14d11..331f20a9 100644 --- a/ZSharp.IR/ir/oop/Structure.cs +++ b/ZSharp.IR/ir/oop/Structure.cs @@ -2,13 +2,13 @@ namespace ZSharp.IR { - public sealed class Structure + public sealed class Structure : TypeDefinition { public string? Name { get; set; } public StructureAttributes Attributes { get; set; } = StructureAttributes.None; - public Collection Bases { get; set; } + public Collection> Bases { get; set; } public Collection Methods { get; } diff --git a/ZSharp.IR/ir/oop/ValueType.cs b/ZSharp.IR/ir/oop/ValueType.cs deleted file mode 100644 index f11f0ee0..00000000 --- a/ZSharp.IR/ir/oop/ValueType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.IR -{ - public sealed class ValueType : OOPType - { - - } -} diff --git a/ZSharp.IR/ir/oop/class/Class.cs b/ZSharp.IR/ir/oop/class/Class.cs new file mode 100644 index 00000000..7fd4bc33 --- /dev/null +++ b/ZSharp.IR/ir/oop/class/Class.cs @@ -0,0 +1,108 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + public sealed class Class(string? name) + : TypeDefinition + , ICustomMetadataProvider + { + private Collection? _customMetadata; + private Collection? _genericParameters; + + private Collection? _constructors; + private FieldCollection? _fields; + private Collection? _methods; + + public string? Name { get; set; } = name; + + public ClassAttributes Attributes { get; set; } = ClassAttributes.None; + + public TypeReference? Base { get; set; } + + public Class(string? name, TypeReference? @base) + : this(name) + { + Base = @base; + } + + public Collection CustomMetadata + { + get + { + if (_customMetadata is not null) + return _customMetadata; + + Interlocked.CompareExchange(ref _customMetadata, [], null); + return _customMetadata; + } + } + + public bool HasCustomMetadata => !_customMetadata.IsNullOrEmpty(); + + public Collection InterfacesImplementations { get; } = []; + + public Collection GenericParameters + { + get + { + if (_genericParameters is not null) + return _genericParameters; + + Interlocked.CompareExchange(ref _genericParameters, [], null); + return _genericParameters; + } + } + + public bool HasGenericParameters => !_genericParameters.IsNullOrEmpty(); + + public Collection Constructors + { + get + { + if (_constructors is not null) + return _constructors; + + Interlocked.CompareExchange(ref _constructors, [], null); + + return _constructors; + } + } + + public bool HasConstructors => !_constructors.IsNullOrEmpty(); + + public Collection Fields + { + get + { + if (_fields is not null) + return _fields; + + Interlocked.CompareExchange(ref _fields, new(this), null); + return _fields; + } + } + + public bool HasFields => !_fields.IsNullOrEmpty(); + + public Collection Methods + { + get + { + if (_methods is not null) + return _methods; + + Interlocked.CompareExchange(ref _methods, [], null); + + return _methods; + } + } + + public bool HasMethods => !_methods.IsNullOrEmpty(); + + public Collection Properties { get; } = []; + + public Collection NestedTypes { get; } = []; + + //public Collection Events { get; } + } +} diff --git a/ZSharp.IR/ir/oop/attributes/ClassAttributes.cs b/ZSharp.IR/ir/oop/class/ClassAttributes.cs similarity index 100% rename from ZSharp.IR/ir/oop/attributes/ClassAttributes.cs rename to ZSharp.IR/ir/oop/class/ClassAttributes.cs diff --git a/ZSharp.IR/ir/oop/class/ClassReference.cs b/ZSharp.IR/ir/oop/class/ClassReference.cs new file mode 100644 index 00000000..715a5245 --- /dev/null +++ b/ZSharp.IR/ir/oop/class/ClassReference.cs @@ -0,0 +1,10 @@ +namespace ZSharp.IR +{ + public sealed class ClassReference(Class @class) + : TypeReference + { + public Class Definition { get; } = @class; + + public TypeReference? OwningType { get; set; } + } +} diff --git a/ZSharp.IR/ir/oop/class/ConstructedClass.cs b/ZSharp.IR/ir/oop/class/ConstructedClass.cs new file mode 100644 index 00000000..cb7a936b --- /dev/null +++ b/ZSharp.IR/ir/oop/class/ConstructedClass.cs @@ -0,0 +1,16 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + public sealed class ConstructedClass(Class @class) + : ConstructedType + { + public Class Class { get; set; } = @class; + + Class TypeReference.Definition => Class; + + public TypeReference? OwningType { get; set; } + + public Collection Arguments { get; set; } = @class.HasGenericParameters ? [] : Collection.Empty; + } +} diff --git a/ZSharp.IR/ir/oop/constructor/Constructor.cs b/ZSharp.IR/ir/oop/constructor/Constructor.cs new file mode 100644 index 00000000..7c9891d9 --- /dev/null +++ b/ZSharp.IR/ir/oop/constructor/Constructor.cs @@ -0,0 +1,13 @@ +namespace ZSharp.IR +{ + public sealed class Constructor(string? name) + : IRDefinition + , IModuleMember + { + public Module? Module => Method.Module; + + public string? Name { get; set; } = name; + + public required Method Method { get; set; } + } +} diff --git a/ZSharp.IR/ir/oop/constructor/ConstructorReference.cs b/ZSharp.IR/ir/oop/constructor/ConstructorReference.cs new file mode 100644 index 00000000..cde680bb --- /dev/null +++ b/ZSharp.IR/ir/oop/constructor/ConstructorReference.cs @@ -0,0 +1,16 @@ +namespace ZSharp.IR +{ + public sealed class ConstructorReference(Constructor constructor) + : ICallable + { + public Constructor Constructor { get; set; } = constructor; + + public required TypeReference OwningType { get; set; } + + public Signature Signature => Constructor.Method.Signature; + + public bool HasBody => Constructor.Method.HasBody; + + public ICallableBody? Body => Constructor.Method.HasBody ? Constructor.Method.Body : null; + } +} diff --git a/ZSharp.IR/ir/oop/enum/EnumClass.cs b/ZSharp.IR/ir/oop/enum/EnumClass.cs new file mode 100644 index 00000000..03162d15 --- /dev/null +++ b/ZSharp.IR/ir/oop/enum/EnumClass.cs @@ -0,0 +1,29 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + public sealed class EnumClass + : TypeDefinition + , IType + { + public string? Name { get; set; } + + public EnumclassAttributes Attributes { get; set; } = EnumclassAttributes.None; + + public IType Type { get; set; } = null!; + + public Collection Values { get; } + + public EnumClass(string? name) + { + Name = name; + Values = new EnumValueCollection(this); + } + + public EnumClass(string? name, IType type) + : this(name) + { + Type = type; + } + } +} diff --git a/ZSharp.IR/ir/oop/enum/EnumValue.cs b/ZSharp.IR/ir/oop/enum/EnumValue.cs new file mode 100644 index 00000000..d24f8a19 --- /dev/null +++ b/ZSharp.IR/ir/oop/enum/EnumValue.cs @@ -0,0 +1,14 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + public sealed class EnumValue(string name, Collection valueCode) + : ModuleMember + { + internal EnumClass? _enumClass; + + public string Name { get; set; } = name; + + public Collection Value { get; set; } = valueCode; + } +} diff --git a/ZSharp.IR/ir/oop/enum/EnumValueCollection.cs b/ZSharp.IR/ir/oop/enum/EnumValueCollection.cs new file mode 100644 index 00000000..02c556e8 --- /dev/null +++ b/ZSharp.IR/ir/oop/enum/EnumValueCollection.cs @@ -0,0 +1,55 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + internal sealed class EnumValueCollection(EnumClass owner) + : Collection + { + private readonly EnumClass enumClass = owner; + + public override void OnAdd(EnumValue item) + { + AssertUnonwed(item); + SetOwner(item); + } + + public override void OnInsert(int index, EnumValue item) + { + AssertUnonwed(item); + SetOwner(item); + } + + public override void OnRemove(EnumValue item) + { + AssertOwned(item); + UnsetOwner(item); + } + + public override void OnRemoveAt(int index) + { + OnRemove(this[index]); + } + + private void SetOwner(EnumValue item) + { + item._enumClass = enumClass; + } + + private void UnsetOwner(EnumValue item) + { + item._enumClass = null; + } + + private void AssertUnonwed(EnumValue item) + { + if (item.Module is not null) + throw new InvalidOperationException(); + } + + private void AssertOwned(EnumValue item) + { + if (item.Module is null) + throw new InvalidOperationException(); + } + } +} diff --git a/ZSharp.IR/ir/oop/attributes/EnumclassAttributes.cs b/ZSharp.IR/ir/oop/enum/EnumclassAttributes.cs similarity index 100% rename from ZSharp.IR/ir/oop/attributes/EnumclassAttributes.cs rename to ZSharp.IR/ir/oop/enum/EnumclassAttributes.cs diff --git a/ZSharp.IR/ir/oop/field/Field.cs b/ZSharp.IR/ir/oop/field/Field.cs index fa319365..83bde576 100644 --- a/ZSharp.IR/ir/oop/field/Field.cs +++ b/ZSharp.IR/ir/oop/field/Field.cs @@ -1,6 +1,8 @@ namespace ZSharp.IR { - public sealed class Field(string name, IType type) : IRObject + public sealed class Field(string name, IType type) + : IRDefinition + , IModuleMember { internal FieldAttributes _attributes = FieldAttributes.None; @@ -70,7 +72,7 @@ public bool IsReadOnly public Class? Owner { get; internal set; } - public override Module? Module => Owner?.Module; + public Module? Module => Owner?.Module; public IType Type { get; set; } = type; diff --git a/ZSharp.IR/ir/oop/field/FieldReference.cs b/ZSharp.IR/ir/oop/field/FieldReference.cs new file mode 100644 index 00000000..d8c05ddc --- /dev/null +++ b/ZSharp.IR/ir/oop/field/FieldReference.cs @@ -0,0 +1,9 @@ +namespace ZSharp.IR +{ + public sealed class FieldReference(Field field) + { + public Field Field { get; set; } = field; + + public required TypeReference OwningType { get; set; } + } +} diff --git a/ZSharp.IR/ir/oop/interface/ConstructedInterface.cs b/ZSharp.IR/ir/oop/interface/ConstructedInterface.cs new file mode 100644 index 00000000..6ca74d81 --- /dev/null +++ b/ZSharp.IR/ir/oop/interface/ConstructedInterface.cs @@ -0,0 +1,16 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + public sealed class ConstructedInterface(Interface @interface) + : ConstructedType + { + public Interface Interface { get; set; } = @interface; + + Interface TypeReference.Definition => Interface; + + public TypeReference? OwningType { get; set; } + + public Collection Arguments { get; set; } = @interface.HasGenericParameters ? [] : Collection.Empty; + } +} diff --git a/ZSharp.IR/ir/oop/interface/Interface.cs b/ZSharp.IR/ir/oop/interface/Interface.cs index 6579def4..0de0c4c6 100644 --- a/ZSharp.IR/ir/oop/interface/Interface.cs +++ b/ZSharp.IR/ir/oop/interface/Interface.cs @@ -2,17 +2,57 @@ namespace ZSharp.IR { - public sealed class Interface : OOPType + public sealed class Interface(string? name) : TypeDefinition { - public string? Name { get; set; } + private Collection? _genericParameters; + private Collection>? _bases; + private Collection? _methods; + + public string? Name { get; set; } = name; public InterfaceAttributes Attributes { get; set; } = InterfaceAttributes.None; - public Collection Bases { get; set; } + public Collection GenericParameters + { + get + { + if (_genericParameters is not null) + return _genericParameters; + + Interlocked.CompareExchange(ref _genericParameters, [], null); + return _genericParameters; + } + } + + public bool HasGenericParameters => !_genericParameters.IsNullOrEmpty(); + + public Collection> Bases + { + get + { + if (_bases is not null) + return _bases; + + Interlocked.CompareExchange(ref _bases, [], null); + return _bases; + } + } + + public bool HasBases => !_bases.IsNullOrEmpty(); + + public Collection Methods + { + get + { + if (_methods is not null) + return _methods; - public Collection Methods { get; } + Interlocked.CompareExchange(ref _methods, [], null); + return _methods; + } + } - public Collection Properties { get; } + public bool HasMethods => !_methods.IsNullOrEmpty(); //public Collection Events { get; } diff --git a/ZSharp.IR/ir/oop/interface/InterfaceImplementation.cs b/ZSharp.IR/ir/oop/interface/InterfaceImplementation.cs index 2a78f3d2..67707302 100644 --- a/ZSharp.IR/ir/oop/interface/InterfaceImplementation.cs +++ b/ZSharp.IR/ir/oop/interface/InterfaceImplementation.cs @@ -2,13 +2,13 @@ namespace ZSharp.IR { - public sealed class InterfaceImplementation(Interface @interface) + public sealed class InterfaceImplementation(TypeReference @interface) { - public Interface Interface { get; set; } = @interface; + public TypeReference Interface { get; set; } = @interface; /// /// Mapping from interface method to implementation method. /// - public Mapping Implementations { get; } = []; + public Mapping Implementations { get; } = []; } } diff --git a/ZSharp.IR/ir/oop/interface/InterfaceReference.cs b/ZSharp.IR/ir/oop/interface/InterfaceReference.cs new file mode 100644 index 00000000..d9273798 --- /dev/null +++ b/ZSharp.IR/ir/oop/interface/InterfaceReference.cs @@ -0,0 +1,10 @@ +namespace ZSharp.IR +{ + public sealed class InterfaceReference(Interface @interface) + : TypeReference + { + public Interface Definition { get; } = @interface; + + public TypeReference? OwningType { get; set; } + } +} diff --git a/ZSharp.IR/ir/oop/method/ConstructedMethod.cs b/ZSharp.IR/ir/oop/method/ConstructedMethod.cs new file mode 100644 index 00000000..af6c7644 --- /dev/null +++ b/ZSharp.IR/ir/oop/method/ConstructedMethod.cs @@ -0,0 +1,14 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + public sealed class ConstructedMethod(Method method) + : MethodReference(method) + , ICallable + { + public Collection Arguments { get; } = + method.HasGenericParameters + ? [] + : throw new InvalidOperationException($"Can not create generic instance from a non-generic method"); + } +} diff --git a/ZSharp.IR/ir/oop/method/Method.cs b/ZSharp.IR/ir/oop/method/Method.cs index 91cd38e8..01967d5e 100644 --- a/ZSharp.IR/ir/oop/method/Method.cs +++ b/ZSharp.IR/ir/oop/method/Method.cs @@ -1,53 +1,46 @@ -namespace ZSharp.IR +using CommonZ.Utils; + +namespace ZSharp.IR { public sealed class Method - : IRObject + : IRDefinition , ICallable + , IModuleMember { - private Signature _signature; - private VM.MethodBody? _body; + public Function UnderlyingFunction { get; set; } - public string? Name { get; set; } + public string? Name { + get => UnderlyingFunction.Name; + set => UnderlyingFunction.Name = value; + } public MethodAttributes Attributes { get; set; } = MethodAttributes.None; + public Collection GenericParameters => UnderlyingFunction.GenericParameters; + + public bool HasGenericParameters => UnderlyingFunction.HasGenericParameters; + public IType ReturnType { - get => _signature.ReturnType; - set => _signature.ReturnType = value; + get => UnderlyingFunction.ReturnType; + set => UnderlyingFunction.ReturnType = value; } public Signature Signature { - get => _signature; - set - { - if (value.Owner is not null) - throw new InvalidOperationException(); - _signature.Owner = null; - (_signature = value).Owner = this; - } + get => UnderlyingFunction.Signature; + set => UnderlyingFunction.Signature = value; } - ICallableBody? ICallable.Body => _body; + ICallableBody? ICallable.Body => UnderlyingFunction.Body; - public VM.MethodBody Body - { - get - { - if (_body is not null) - return _body; - - Interlocked.CompareExchange(ref _body, new(this), null); - return _body; - } - } + public VM.FunctionBody Body => UnderlyingFunction.Body; - public bool HasBody => _body is not null; + public bool HasBody => UnderlyingFunction.HasBody; - public OOPType? Owner { get; set; } + public TypeDefinition? Owner { get; set; } - public override Module? Module => Owner?.Module; + public Module? Module => Owner?.Module; public bool IsClass { @@ -92,14 +85,20 @@ public bool IsAbstract } public Method(IType returnType) + : this(new Signature(returnType)) { - _signature = new(returnType) { Owner = this }; + } public Method(Signature signature) - : this((null as IType)!) + : this(new Function(signature)) + { + + } + + public Method(Function function) { - Signature = signature; + UnderlyingFunction = function; } } } diff --git a/ZSharp.IR/ir/oop/method/MethodBody.cs b/ZSharp.IR/ir/oop/method/MethodBody.cs deleted file mode 100644 index 3c685d14..00000000 --- a/ZSharp.IR/ir/oop/method/MethodBody.cs +++ /dev/null @@ -1,53 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.IR.VM -{ - public sealed class MethodBody : ICallableBody - { - private InstructionCollection? _instructions; - private LocalCollection? _locals; - - public Method Method { get; } - - public Collection Instructions - { - get - { - if (_instructions is not null) - return _instructions; - - Interlocked.CompareExchange(ref _instructions, [], null); - return _instructions; - } - } - - public bool HasInstructions => !_instructions.IsNullOrEmpty(); - - public Collection Locals - { - get - { - if (_locals is not null) - return _locals; - - Interlocked.CompareExchange(ref _locals, new(Method), null); - return _locals; - } - } - - public bool HasLocals => !_locals.IsNullOrEmpty(); - - public int StackSize { get; set; } - - public MethodBody(Method method, IEnumerable code) - { - Method = method; - _instructions = new(code); - } - - public MethodBody(Method method) - { - Method = method; - } - } -} diff --git a/ZSharp.IR/ir/oop/method/MethodReference.cs b/ZSharp.IR/ir/oop/method/MethodReference.cs new file mode 100644 index 00000000..204e27b6 --- /dev/null +++ b/ZSharp.IR/ir/oop/method/MethodReference.cs @@ -0,0 +1,16 @@ +namespace ZSharp.IR +{ + public class MethodReference(Method method) + : ICallable + { + public Method Method { get; set; } = method; + + public required TypeReference OwningType { get; set; } + + public Signature Signature { get; init; } = method.Signature; + + public bool HasBody => Method.HasBody; + + public ICallableBody? Body => Method.HasBody ? Method.Body : null; + } +} diff --git a/ZSharp.IR/ir/oop/value type/ConstructedValueType.cs b/ZSharp.IR/ir/oop/value type/ConstructedValueType.cs new file mode 100644 index 00000000..1a62a3ca --- /dev/null +++ b/ZSharp.IR/ir/oop/value type/ConstructedValueType.cs @@ -0,0 +1,16 @@ +using CommonZ.Utils; + +namespace ZSharp.IR +{ + public sealed class ConstructedValueType(ValueType @class) + : ConstructedType + { + public ValueType ValueType { get; set; } = @class; + + ValueType TypeReference.Definition => ValueType; + + public TypeReference? OwningType { get; set; } + + public Collection Arguments { get; set; } = false ? [] : Collection.Empty; + } +} diff --git a/ZSharp.IR/ir/oop/value type/ValueType.cs b/ZSharp.IR/ir/oop/value type/ValueType.cs new file mode 100644 index 00000000..f0fc9992 --- /dev/null +++ b/ZSharp.IR/ir/oop/value type/ValueType.cs @@ -0,0 +1,7 @@ +namespace ZSharp.IR +{ + public sealed class ValueType(string? name) : TypeDefinition + { + public string? Name { get; set; } = name; + } +} diff --git a/ZSharp.IR/ir/oop/value type/ValueTypeReference.cs b/ZSharp.IR/ir/oop/value type/ValueTypeReference.cs new file mode 100644 index 00000000..679dfc18 --- /dev/null +++ b/ZSharp.IR/ir/oop/value type/ValueTypeReference.cs @@ -0,0 +1,10 @@ +namespace ZSharp.IR +{ + public sealed class ValueTypeReference(ValueType valueType) + : TypeReference + { + public ValueType Definition { get; } = valueType; + + public TypeReference? OwningType { get; set; } + } +} diff --git a/ZSharp.IR/ir/signature/Parameter.cs b/ZSharp.IR/ir/signature/Parameter.cs index d1c6f5e8..d078aa99 100644 --- a/ZSharp.IR/ir/signature/Parameter.cs +++ b/ZSharp.IR/ir/signature/Parameter.cs @@ -2,11 +2,13 @@ namespace ZSharp.IR { - public class Parameter(string name, IType type) : IRObject + public class Parameter(string name, IType type) + : IRDefinition + , IModuleMember { private Signature? _signature; - public override Module? Module => _signature?.Module; + public Module? Module => _signature?.Module; public string Name { get; } = name; diff --git a/ZSharp.IR/ir/signature/Signature.cs b/ZSharp.IR/ir/signature/Signature.cs index 32e31a93..35b4dc17 100644 --- a/ZSharp.IR/ir/signature/Signature.cs +++ b/ZSharp.IR/ir/signature/Signature.cs @@ -1,13 +1,15 @@ namespace ZSharp.IR { - public sealed class Signature(IType returnType) : IRObject + public sealed class Signature(IType returnType) + : IRDefinition + , IModuleMember { - private IRObject? _owner; + private Function? _owner; private Args? _args; private KwArgs? _kwArgs; - public override Module? Module => _owner?.Module; + public Module? Module => _owner?.Module; public Args Args { @@ -53,7 +55,7 @@ public KwArgs KwArgs public IType ReturnType { get; set; } = returnType; - public IRObject? Owner + public Function? Owner { get => _owner; set => _owner = value; diff --git a/ZSharp.IR/ir/templates/ITemplate.cs b/ZSharp.IR/ir/templates/ITemplate.cs deleted file mode 100644 index c92c0321..00000000 --- a/ZSharp.IR/ir/templates/ITemplate.cs +++ /dev/null @@ -1,9 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.IR -{ - public interface ITemplate - { - public IRObject Construct(Mapping args); - } -} diff --git a/ZSharp.IR/ir/templates/TemplateParameter.cs b/ZSharp.IR/ir/templates/TemplateParameter.cs deleted file mode 100644 index 4c84d3a6..00000000 --- a/ZSharp.IR/ir/templates/TemplateParameter.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ZSharp.IR -{ - public sealed class TemplateParameter - { - public string Name { get; set; } - - public TemplateParameter(string name) - { - Name = name; - } - } -} diff --git a/ZSharp.IR/ir/typeclass/Typeclass.cs b/ZSharp.IR/ir/typeclass/Typeclass.cs index 7a586b1e..5660f86c 100644 --- a/ZSharp.IR/ir/typeclass/Typeclass.cs +++ b/ZSharp.IR/ir/typeclass/Typeclass.cs @@ -2,15 +2,15 @@ namespace ZSharp.IR { - public sealed class Typeclass : OOPType + public sealed class Typeclass : TypeDefinition { public string? Name { get; set; } public TypeclassAttributes Attributes { get; set; } = TypeclassAttributes.None; - public Collection Bases { get; } + public Collection> Bases { get; } - public TemplateParameter Parameter { get; } + public GenericParameter Parameter { get; } public Collection Methods { get; } diff --git a/ZSharp.IR/ir/typeclass/TypeclassImplementation.cs b/ZSharp.IR/ir/typeclass/TypeclassImplementation.cs index 0960e80f..03c9b45e 100644 --- a/ZSharp.IR/ir/typeclass/TypeclassImplementation.cs +++ b/ZSharp.IR/ir/typeclass/TypeclassImplementation.cs @@ -2,7 +2,7 @@ namespace ZSharp.IR { - public sealed class TypeclassImplementation(Typeclass typeclass) : OOPType + public sealed class TypeclassImplementation(Typeclass typeclass) : TypeDefinition { public Typeclass Typeclass { get; } = typeclass; diff --git a/ZSharp.IR/ir/types/GenericParameter.cs b/ZSharp.IR/ir/types/GenericParameter.cs new file mode 100644 index 00000000..b1fdfcbc --- /dev/null +++ b/ZSharp.IR/ir/types/GenericParameter.cs @@ -0,0 +1,8 @@ +namespace ZSharp.IR +{ + public sealed class GenericParameter(string name) + : IType + { + public string Name { get; set; } = name; + } +} diff --git a/ZSharp.IR/ir/types/OOPType.cs b/ZSharp.IR/ir/types/OOPType.cs deleted file mode 100644 index 7a9de826..00000000 --- a/ZSharp.IR/ir/types/OOPType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.IR -{ - public abstract class OOPType : ModuleMember, IType - { - - } -} diff --git a/ZSharp.IR/ir/types/TypeDefinition.cs b/ZSharp.IR/ir/types/TypeDefinition.cs new file mode 100644 index 00000000..d8de97d7 --- /dev/null +++ b/ZSharp.IR/ir/types/TypeDefinition.cs @@ -0,0 +1,7 @@ +namespace ZSharp.IR +{ + public abstract class TypeDefinition : ModuleMember + { + + } +} diff --git a/ZSharp.IR/type system/RuntimeModule.cs b/ZSharp.IR/type system/RuntimeModule.cs index e529e5e7..235c31cd 100644 --- a/ZSharp.IR/type system/RuntimeModule.cs +++ b/ZSharp.IR/type system/RuntimeModule.cs @@ -15,30 +15,38 @@ private static RuntimeModule CreateStandardRuntimeModule() { Module module = new("Runtime"); - Class @object; - Class @string; - Class type; - Class @void; - Class @null; + ClassReference @object; + ClassReference @string; + ClassReference type; + ClassReference @void; + ClassReference @null; - Class boolean; + ClassReference boolean; - Class int32; + ClassReference int32; - Class float32; + ClassReference float32; + + Class array; + Class reference; + Class pointer; { - module.Types.Add(type = new("Type")); - module.Types.Add(@object = new("Object")); - module.Types.Add(@string = new("String")); - module.Types.Add(@void = new("Void")); - module.Types.Add(@null = new("Null")); + module.Types.Add((type = new(new("Type"))).Definition); + module.Types.Add((@object = new(new("Object"))).Definition); + module.Types.Add((@string = new(new("String"))).Definition); + module.Types.Add((@void = new(new("Void"))).Definition); + module.Types.Add((@null = new(new("Null"))).Definition); + + module.Types.Add((boolean = new(new("Boolean"))).Definition); - module.Types.Add(boolean = new("Boolean")); + module.Types.Add((int32 = new(new("Int32"))).Definition); - module.Types.Add(int32 = new("Int32")); + module.Types.Add((float32 = new(new("Float32"))).Definition); - module.Types.Add(float32 = new("Float32")); + module.Types.Add(array = new("Array")); + module.Types.Add(reference = new("Reference")); + module.Types.Add(pointer = new("Pointer")); } return new(module, new() @@ -54,6 +62,10 @@ private static RuntimeModule CreateStandardRuntimeModule() Int32 = int32, Float32 = float32, + + Array = array, + Reference = reference, + Pointer = pointer, }); } } diff --git a/ZSharp.IR/type system/TypeSystem.cs b/ZSharp.IR/type system/TypeSystem.cs index 46f5fa4a..3435eaf7 100644 --- a/ZSharp.IR/type system/TypeSystem.cs +++ b/ZSharp.IR/type system/TypeSystem.cs @@ -2,20 +2,26 @@ { public sealed class TypeSystem { - public Class Object { get; init; } = null!; + public ClassReference Object { get; init; } = null!; - public Class String { get; init; } = null!; + public ClassReference String { get; init; } = null!; - public Class Type { get; init; } = null!; + public ClassReference Type { get; init; } = null!; - public Class Void { get; init; } = null!; + public ClassReference Void { get; init; } = null!; - public Class Null { get; init; } = null!; + public ClassReference Null { get; init; } = null!; - public Class Boolean { get; init; } = null!; + public ClassReference Boolean { get; init; } = null!; - public Class Int32 { get; init; } = null!; + public ClassReference Int32 { get; init; } = null!; - public Class Float32 { get; init; } = null!; + public ClassReference Float32 { get; init; } = null!; + + public Class Array { get; init; } = null!; + + public Class Reference { get; init; } = null!; + + public Class Pointer { get; init; } = null!; } } diff --git a/ZSharp.IR/type system/types/ConstructedType.cs b/ZSharp.IR/type system/types/ConstructedType.cs index 6ca18645..372b7c8d 100644 --- a/ZSharp.IR/type system/types/ConstructedType.cs +++ b/ZSharp.IR/type system/types/ConstructedType.cs @@ -1,7 +1,18 @@ -namespace ZSharp.IR +using CommonZ.Utils; + +namespace ZSharp.IR { - public sealed class ConstructedType : IType + public interface ConstructedType + : TypeReference { + public abstract Collection Arguments { get; } + } + public interface ConstructedType + : ConstructedType + , TypeReference + where T : TypeDefinition + { + } } diff --git a/ZSharp.IR/type system/types/TypeReference.cs b/ZSharp.IR/type system/types/TypeReference.cs new file mode 100644 index 00000000..3e17c65e --- /dev/null +++ b/ZSharp.IR/type system/types/TypeReference.cs @@ -0,0 +1,19 @@ +namespace ZSharp.IR +{ + public interface TypeReference : IType + { + public TypeReference? OwningType { get; set; } + + public TypeDefinition Definition { get; } + } + + public interface TypeReference : TypeReference + where T : TypeDefinition + { + public new T Definition { get; } + + TypeDefinition TypeReference.Definition { + get => Definition; + } + } +} diff --git a/ZSharp.IR/vm/code/local/Local.cs b/ZSharp.IR/vm/code/local/Local.cs index 4b7b4036..facf54e5 100644 --- a/ZSharp.IR/vm/code/local/Local.cs +++ b/ZSharp.IR/vm/code/local/Local.cs @@ -1,10 +1,12 @@ namespace ZSharp.IR.VM { - public sealed class Local(string name, IType type) : IRObject + public sealed class Local(string name, IType type) + : IRDefinition + , IModuleMember { - public override Module? Module => Owner?.Module; + public Module? Module => Owner?.Module; - public IRObject? Owner { get; internal set; } + public Function? Owner { get; internal set; } public LocalAttributes Attributes { get; set; } diff --git a/ZSharp.IR/vm/code/local/LocalCollection.cs b/ZSharp.IR/vm/code/local/LocalCollection.cs index 29df4169..ab31236c 100644 --- a/ZSharp.IR/vm/code/local/LocalCollection.cs +++ b/ZSharp.IR/vm/code/local/LocalCollection.cs @@ -2,9 +2,9 @@ namespace ZSharp.IR.VM { - internal sealed class LocalCollection(IRObject owner) : Collection + internal sealed class LocalCollection(Function owner) : Collection { - private readonly IRObject owner = owner; + private readonly Function owner = owner; public override void OnAdd(Local item) { diff --git a/ZSharp.IR/vm/instructions/flow/CallVirtual.cs b/ZSharp.IR/vm/instructions/flow/CallVirtual.cs index 2ba4df1f..e944b2bd 100644 --- a/ZSharp.IR/vm/instructions/flow/CallVirtual.cs +++ b/ZSharp.IR/vm/instructions/flow/CallVirtual.cs @@ -1,11 +1,11 @@ namespace ZSharp.IR.VM { - public sealed class CallVirtual(Method method) + public sealed class CallVirtual(MethodReference method) : Instruction - , IHasOperand + , IHasOperand { - public Method Method { get; set; } = method; + public MethodReference Method { get; set; } = method; - Method IHasOperand.Operand => Method; + MethodReference IHasOperand.Operand => Method; } } diff --git a/ZSharp.IR/vm/instructions/flow/CreateInstance.cs b/ZSharp.IR/vm/instructions/flow/CreateInstance.cs deleted file mode 100644 index 9570a9c2..00000000 --- a/ZSharp.IR/vm/instructions/flow/CreateInstance.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace ZSharp.IR.VM -{ - public sealed class CreateInstance(Constructor constructor) - : Instruction - , IHasOperand - { - public Constructor Constructor { get; set; } = constructor; - - Constructor IHasOperand.Operand => Constructor; - } -} diff --git a/ZSharp.IR/vm/instructions/misc/GetClass.cs b/ZSharp.IR/vm/instructions/misc/GetClass.cs new file mode 100644 index 00000000..c683a627 --- /dev/null +++ b/ZSharp.IR/vm/instructions/misc/GetClass.cs @@ -0,0 +1,11 @@ +namespace ZSharp.IR.VM +{ + public sealed class GetClass(TypeReference @class) + : Instruction + , IHasOperand> + { + public TypeReference Class { get; set; } = @class; + + TypeReference IHasOperand>.Operand => Class; + } +} diff --git a/ZSharp.IR/vm/instructions/misc/GetObject.cs b/ZSharp.IR/vm/instructions/misc/GetObject.cs index e7a4137b..67bde8e6 100644 --- a/ZSharp.IR/vm/instructions/misc/GetObject.cs +++ b/ZSharp.IR/vm/instructions/misc/GetObject.cs @@ -1,11 +1,11 @@ namespace ZSharp.IR.VM { - public sealed class GetObject(IRObject ir) + public sealed class GetObject(IRDefinition ir) : Instruction - , IHasOperand + , IHasOperand { - public IRObject IR { get; set; } = ir; + public IRDefinition IR { get; set; } = ir; - IRObject IHasOperand.Operand => IR; + IRDefinition IHasOperand.Operand => IR; } } diff --git a/ZSharp.IR/vm/instructions/object/CastReference.cs b/ZSharp.IR/vm/instructions/object/CastReference.cs new file mode 100644 index 00000000..43a15bb7 --- /dev/null +++ b/ZSharp.IR/vm/instructions/object/CastReference.cs @@ -0,0 +1,7 @@ +namespace ZSharp.IR.VM +{ + public sealed class CastReference(TypeReference targetType) : Instruction + { + public TypeReference Type { get; set; } = targetType; + } +} diff --git a/ZSharp.IR/vm/instructions/object/CreateInstance.cs b/ZSharp.IR/vm/instructions/object/CreateInstance.cs new file mode 100644 index 00000000..2dafe3e5 --- /dev/null +++ b/ZSharp.IR/vm/instructions/object/CreateInstance.cs @@ -0,0 +1,11 @@ +namespace ZSharp.IR.VM +{ + public sealed class CreateInstance(ConstructorReference constructor) + : Instruction + , IHasOperand + { + public ConstructorReference Constructor { get; set; } = constructor; + + ConstructorReference IHasOperand.Operand => Constructor; + } +} diff --git a/ZSharp.IR/vm/instructions/object/IsNotNull.cs b/ZSharp.IR/vm/instructions/object/IsNotNull.cs new file mode 100644 index 00000000..78db6ca3 --- /dev/null +++ b/ZSharp.IR/vm/instructions/object/IsNotNull.cs @@ -0,0 +1,7 @@ +namespace ZSharp.IR.VM +{ + public sealed class IsNotNull : Instruction + { + + } +} diff --git a/ZSharp.IR/vm/instructions/object/IsNull.cs b/ZSharp.IR/vm/instructions/object/IsNull.cs new file mode 100644 index 00000000..e1996936 --- /dev/null +++ b/ZSharp.IR/vm/instructions/object/IsNull.cs @@ -0,0 +1,7 @@ +namespace ZSharp.IR.VM +{ + public sealed class IsNull : Instruction + { + + } +} diff --git a/ZSharp.IR/vm/instructions/stack/GetField.cs b/ZSharp.IR/vm/instructions/stack/GetField.cs index f74c3408..8649850b 100644 --- a/ZSharp.IR/vm/instructions/stack/GetField.cs +++ b/ZSharp.IR/vm/instructions/stack/GetField.cs @@ -1,11 +1,11 @@ namespace ZSharp.IR.VM { - public sealed class GetField(Field field) + public sealed class GetField(FieldReference field) : Instruction - , IHasOperand + , IHasOperand { - public Field Field { get; set; } = field; + public FieldReference Field { get; set; } = field; - Field IHasOperand.Operand => Field; + FieldReference IHasOperand.Operand => Field; } } diff --git a/ZSharp.IR/vm/instructions/stack/SetField.cs b/ZSharp.IR/vm/instructions/stack/SetField.cs index 14b4a801..f23fa198 100644 --- a/ZSharp.IR/vm/instructions/stack/SetField.cs +++ b/ZSharp.IR/vm/instructions/stack/SetField.cs @@ -1,11 +1,11 @@ namespace ZSharp.IR.VM { - public sealed class SetField(Field field) + public sealed class SetField(FieldReference field) : Instruction - , IHasOperand + , IHasOperand { - public Field Field { get; set; } = field; + public FieldReference Field { get; set; } = field; - Field IHasOperand.Operand => Field; + FieldReference IHasOperand.Operand => Field; } } diff --git a/ZSharp.Importer.ILLoader.Attributes/AliasAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/AliasAttribute.cs new file mode 100644 index 00000000..1749f0b2 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/AliasAttribute.cs @@ -0,0 +1,21 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Constructor | + AttributeTargets.Enum | + AttributeTargets.Field | + AttributeTargets.GenericParameter | + AttributeTargets.Interface | + AttributeTargets.Method | + AttributeTargets.Module | + AttributeTargets.Parameter | + AttributeTargets.Property | + AttributeTargets.Struct, + AllowMultiple = false + )] + public sealed class AliasAttribute(string name) : Attribute + { + public string Name { get; } = name; + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/HideImportAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/HideImportAttribute.cs new file mode 100644 index 00000000..1c1380bd --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/HideImportAttribute.cs @@ -0,0 +1,18 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Constructor | + AttributeTargets.Enum | + AttributeTargets.Field | + AttributeTargets.Interface | + AttributeTargets.Method | + AttributeTargets.Property | + AttributeTargets.Struct, + AllowMultiple = false + )] + public sealed class HideImportAttribute : Attribute + { + + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/ImportTypeAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/ImportTypeAttribute.cs new file mode 100644 index 00000000..caaee836 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/ImportTypeAttribute.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Module | AttributeTargets.Class, + AllowMultiple = true + )] + public sealed class ImportTypeAttribute(Type type) : Attribute + { + public Type Type { get; } = type; + + public string? Alias { get; init; } = null; + + public string? Namespace { get; init; } = null; + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/ModuleScopeAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/ModuleScopeAttribute.cs new file mode 100644 index 00000000..856958e0 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/ModuleScopeAttribute.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Class, + AllowMultiple = false + )] + public sealed class ModuleScopeAttribute : Attribute + { + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/ZSharp.Importer.ILLoader.Attributes.csproj b/ZSharp.Importer.ILLoader.Attributes/ZSharp.Importer.ILLoader.Attributes.csproj new file mode 100644 index 00000000..e2374d98 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/ZSharp.Importer.ILLoader.Attributes.csproj @@ -0,0 +1,10 @@ + + + + net9.0 + enable + enable + ZSharp.Importer.ILLoader + + + diff --git a/ZSharp.Importer.ILLoader.Attributes/namespace/AddNamespaceAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/namespace/AddNamespaceAttribute.cs new file mode 100644 index 00000000..6c609620 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/namespace/AddNamespaceAttribute.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Struct | + AttributeTargets.Interface | + AttributeTargets.Enum, + AllowMultiple = false, + Inherited = false + )] + public sealed class AddNamespaceAttribute(string @namespace) : Attribute + { + public string Name { get; } = @namespace; + + public bool IsGlobalNamespace => string.IsNullOrEmpty(Name); + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/namespace/MapNamespaceAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/namespace/MapNamespaceAttribute.cs new file mode 100644 index 00000000..9c54dd06 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/namespace/MapNamespaceAttribute.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Module, + AllowMultiple = true + )] + public sealed class MapNamespaceAttribute : Attribute + { + public required string OldName { get; init; } + + public required string NewName { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/namespace/SetNamespaceAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/namespace/SetNamespaceAttribute.cs new file mode 100644 index 00000000..5e1c84a1 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/namespace/SetNamespaceAttribute.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Struct | + AttributeTargets.Interface | + AttributeTargets.Enum, + AllowMultiple = false, + Inherited = false + )] + public sealed class SetNamespaceAttribute(string @namespace) : Attribute + { + public string Name { get; } = @namespace; + + public bool IsGlobalNamespace => string.IsNullOrEmpty(Name); + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/operator/OperatorAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/operator/OperatorAttribute.cs new file mode 100644 index 00000000..0d8cc251 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/operator/OperatorAttribute.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Method, + AllowMultiple = false + )] + public sealed class OperatorAttribute(string @operator) : Attribute + { + public string Operator { get; } = @operator; + + public required OperatorKind Kind { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/operator/OperatorKind.cs b/ZSharp.Importer.ILLoader.Attributes/operator/OperatorKind.cs new file mode 100644 index 00000000..42be7b25 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/operator/OperatorKind.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Importer.ILLoader +{ + public enum OperatorKind + { + Prefix, + Infix, + Postfix, + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/parameter/NamedParameterAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/parameter/NamedParameterAttribute.cs new file mode 100644 index 00000000..c199dfc1 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/parameter/NamedParameterAttribute.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Parameter, + AllowMultiple = false + )] + public sealed class NamedParameterAttribute : Attribute + { + + } +} diff --git a/ZSharp.Importer.ILLoader.Attributes/parameter/VarParameterAttribute.cs b/ZSharp.Importer.ILLoader.Attributes/parameter/VarParameterAttribute.cs new file mode 100644 index 00000000..7c065993 --- /dev/null +++ b/ZSharp.Importer.ILLoader.Attributes/parameter/VarParameterAttribute.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Importer.ILLoader +{ + [AttributeUsage( + AttributeTargets.Parameter, + AllowMultiple = false + )] + public sealed class VarParameterAttribute : Attribute + { + + } +} diff --git a/ZSharp.Importer.ILLoader/GlobalUsings.cs b/ZSharp.Importer.ILLoader/GlobalUsings.cs new file mode 100644 index 00000000..a24d1fcb --- /dev/null +++ b/ZSharp.Importer.ILLoader/GlobalUsings.cs @@ -0,0 +1,10 @@ +global using ZSharp.Objects; + +global using IL = System.Reflection; + +global using MemberName = string; +global using MemberIndex = int; + +global using CompilerObject = ZSharp.Compiler.CompilerObject; +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.Importer.ILLoader/ZSharp.Importer.ILLoader.csproj b/ZSharp.Importer.ILLoader/ZSharp.Importer.ILLoader.csproj new file mode 100644 index 00000000..64381719 --- /dev/null +++ b/ZSharp.Importer.ILLoader/ZSharp.Importer.ILLoader.csproj @@ -0,0 +1,25 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + + + + + + + + + diff --git a/ZSharp.Importer.ILLoader/capabilities/ITypeModifier.cs b/ZSharp.Importer.ILLoader/capabilities/ITypeModifier.cs new file mode 100644 index 00000000..842add77 --- /dev/null +++ b/ZSharp.Importer.ILLoader/capabilities/ITypeModifier.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + public interface ITypeModifier + { + public CompilerObject Modify(CompilerObject type); + } +} diff --git a/ZSharp.Importer.ILLoader/capabilities/internal/IAddMember.cs b/ZSharp.Importer.ILLoader/capabilities/internal/IAddMember.cs new file mode 100644 index 00000000..62ef9b67 --- /dev/null +++ b/ZSharp.Importer.ILLoader/capabilities/internal/IAddMember.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + internal interface IAddMember + { + public CompilerObject AddMember(string name, CompilerObject member); + } +} diff --git a/ZSharp.Importer.ILLoader/capabilities/internal/IBindable.cs b/ZSharp.Importer.ILLoader/capabilities/internal/IBindable.cs new file mode 100644 index 00000000..4d0deca0 --- /dev/null +++ b/ZSharp.Importer.ILLoader/capabilities/internal/IBindable.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + internal interface IBindable + { + public IResult Bind(Compiler.Compiler compiler, CompilerObject target); + } +} diff --git a/ZSharp.Importer.ILLoader/capabilities/internal/IILType.cs b/ZSharp.Importer.ILLoader/capabilities/internal/IILType.cs new file mode 100644 index 00000000..c3323a6d --- /dev/null +++ b/ZSharp.Importer.ILLoader/capabilities/internal/IILType.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + internal interface IILType + { + public Type GetILType(); + } +} diff --git a/ZSharp.Importer.ILLoader/capabilities/internal/ILazyMemberLoader.cs b/ZSharp.Importer.ILLoader/capabilities/internal/ILazyMemberLoader.cs new file mode 100644 index 00000000..e9f58a9f --- /dev/null +++ b/ZSharp.Importer.ILLoader/capabilities/internal/ILazyMemberLoader.cs @@ -0,0 +1,14 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Importer.ILLoader +{ + internal interface ILazyMemberLoader + { + public void AddLazyMember(MemberName name, IL.MemberInfo member); + + public CompilerObject? GetLazyMember(MemberName name); + + public bool GetLazyMember(MemberName name, [NotNullWhen(true)] out CompilerObject? member) + => (member = GetLazyMember(name)) is not null; + } +} diff --git a/ZSharp.Importer.ILLoader/capabilities/internal/ILoader.cs b/ZSharp.Importer.ILLoader/capabilities/internal/ILoader.cs new file mode 100644 index 00000000..a009956f --- /dev/null +++ b/ZSharp.Importer.ILLoader/capabilities/internal/ILoader.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + internal interface ILoader + { + public CompilerObject LoadMember(T member); + } +} diff --git a/ZSharp.Importer.ILLoader/capabilities/on add/IOnAddTo.cs b/ZSharp.Importer.ILLoader/capabilities/on add/IOnAddTo.cs new file mode 100644 index 00000000..89792d0d --- /dev/null +++ b/ZSharp.Importer.ILLoader/capabilities/on add/IOnAddTo.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Objects +{ + public interface IOnAddTo + where T : class, CompilerObject + { + public OnAddResult OnAddTo(T @object); + } +} diff --git a/ZSharp.Importer.ILLoader/capabilities/on add/OnAddResult.cs b/ZSharp.Importer.ILLoader/capabilities/on add/OnAddResult.cs new file mode 100644 index 00000000..0cd86886 --- /dev/null +++ b/ZSharp.Importer.ILLoader/capabilities/on add/OnAddResult.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Objects +{ + public enum OnAddResult + { + None, + Error, + Remove + } +} diff --git a/ZSharp.Importer.ILLoader/extensions/ILLoaderExtensions.cs b/ZSharp.Importer.ILLoader/extensions/ILLoaderExtensions.cs new file mode 100644 index 00000000..2a64f787 --- /dev/null +++ b/ZSharp.Importer.ILLoader/extensions/ILLoaderExtensions.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Importer.ILLoader +{ + public static class ILLoaderExtensions + { + public static CompilerObject LoadTypeAsModule(this ILLoader loader, Type type) + => new Objects.TypeAsModule(type, loader); + } +} diff --git a/ZSharp.Importer.ILLoader/extensions/InternalILMemberExtensions.cs b/ZSharp.Importer.ILLoader/extensions/InternalILMemberExtensions.cs new file mode 100644 index 00000000..39a01fb0 --- /dev/null +++ b/ZSharp.Importer.ILLoader/extensions/InternalILMemberExtensions.cs @@ -0,0 +1,51 @@ +using System.Diagnostics.CodeAnalysis; +using System.Reflection; + +namespace ZSharp.Importer.ILLoader +{ + internal static class InternalILMemberExtensions + { + public static string AliasOrName(this MemberInfo member) + => member.GetCustomAttribute() is AliasAttribute alias + ? alias.Name + : member.Name; + + public static string AliasOrName(this ParameterInfo parameter) + => parameter.GetCustomAttribute() is AliasAttribute alias + ? alias.Name + : parameter.Name ?? throw new InvalidOperationException("Parameter name cannot be null."); + + public static bool IsModuleScope(this Type type) + => type.GetCustomAttribute() is not null; + + public static bool IsOperator(this MethodInfo method) + => method.GetCustomAttribute() is not null; + + public static bool IsOperator(this MethodInfo method, [NotNullWhen(true)] out OperatorAttribute? @operator) + => (@operator = method.GetCustomAttribute()) is not null; + + public static string GetNamespaceOverride(this MemberInfo member, string rootNamespace) + { + if (member.GetCustomAttribute() is SetNamespaceAttribute setNamespace) + return setNamespace.Name; + + if (member.GetCustomAttribute() is AddNamespaceAttribute addNamespace) + { + if (addNamespace.IsGlobalNamespace) + return rootNamespace; + return $"{rootNamespace}.{addNamespace.Name}"; + } + + return rootNamespace; + } + + public static bool OverridesNamespace(this MemberInfo member, string rootNamespace, [NotNullWhen(true)] out string? @namespace) + => (@namespace = member.GetNamespaceOverride(rootNamespace)) != rootNamespace; + + public static ImportTypeAttribute[] GetImportedTypes(this Module module) + => [.. module.GetCustomAttributes()]; + + public static ImportTypeAttribute[] GetImportedTypes(this Type type) + => [.. type.GetCustomAttributes()]; + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/Prepare.cs b/ZSharp.Importer.ILLoader/helpers/Prepare.cs new file mode 100644 index 00000000..a6847f81 --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/Prepare.cs @@ -0,0 +1,129 @@ +using System.Reflection; + +namespace ZSharp.Importer.ILLoader +{ + internal static class Prepare + { + public static void PrepareModule(Objects.Module module, ILLoader loader) + { + var il = module.IL; + + Dictionary mappedNamespaces = []; + foreach (var mapping in il.GetCustomAttributes()) + mappedNamespaces[mapping.OldName] = mapping.NewName; + + List moduleScopes = []; + + foreach (var type in il.GetTypes()) + if (!type.IsPublic) continue; + else + { + if (type.Namespace is string ns) + ns = mappedNamespaces.GetValueOrDefault(ns, ns); + else ns = string.Empty; + + if (type.IsModuleScope()) + { + moduleScopes.Add(type); + continue; + } + + ILazyMemberLoader lazyLoader = ns == string.Empty + ? module.LazyLoader + : loader.Namespace(ns); + + lazyLoader.AddLazyMember(type.AliasOrName(), type); + } + + foreach (var importedType in il.GetImportedTypes()) + PrepareImportedType(importedType, module.LazyLoader, loader); + foreach (var scope in moduleScopes) + PrepareModuleScope(scope, module.LazyLoader, loader); + } + + public static void PrepareTypeAsModule(Objects.TypeAsModule module, ILLoader loader) + { + var il = module.IL; + + Dictionary mappedNamespaces = []; + foreach (var mapping in il.GetCustomAttributes()) + mappedNamespaces[mapping.OldName] = mapping.NewName; + + List moduleScopes = []; + + foreach (var type in il.GetNestedTypes()) + if (!type.IsPublic) continue; + else + { + if (type.Namespace is string ns) + ns = mappedNamespaces.GetValueOrDefault(ns, ns); + else ns = string.Empty; + + if (type.IsModuleScope()) + { + moduleScopes.Add(type); + continue; + } + + ILazyMemberLoader lazyLoader = ns == string.Empty + ? module.LazyLoader + : loader.Namespace(ns); + + lazyLoader.AddLazyMember(type.AliasOrName(), type); + } + + foreach (var importedType in il.GetImportedTypes()) + PrepareImportedType(importedType, module.LazyLoader, loader); + + PrepareModuleScope(module.IL, module.LazyLoader, loader); + } + + private static void PrepareModuleScope(Type scope, ILazyMemberLoader lazyLoader, ILLoader loader) + { + foreach (var member in scope.GetMembers()) + { + if (member.DeclaringType != scope) continue; + + if (member is MethodInfo method && method.IsOperator(out var op)) + { + loader.OnLoadOperator?.Invoke(op, method); + continue; + } + + lazyLoader.AddLazyMember(member.AliasOrName(), member); + } + } + + private static void PrepareImportedType(ImportTypeAttribute importedType, ILazyMemberLoader lazyLoader, ILLoader loader) + { + var type = importedType.Type; + if (!type.IsPublic) throw new($"Cannot use {nameof(ImportTypeAttribute)} on non-public type {type.Name}"); + string ns = importedType.Namespace ?? type.Namespace ?? string.Empty; + lazyLoader = ns == string.Empty + ? lazyLoader + : loader.Namespace(ns); + lazyLoader.AddLazyMember(importedType.Alias ?? type.Name, type); + } + + public static void PrepareType(Objects.Class @class, ILLoader loader) + { + var il = @class.IL; + + foreach (var member in il.GetMembers()) + { + if (member is ConstructorInfo constructor) + { + continue; + } + + if (member is MethodInfo method && method.IsOperator(out var op)) + { + loader.OnLoadOperator?.Invoke(op, method); + continue; + } + + @class.LazyLoader.AddLazyMember(member.AliasOrName(), member); + } + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.Container.cs b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.Container.cs new file mode 100644 index 00000000..ac62011e --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.Container.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class LazyMemberLoader + { + public required IAddMember Container { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.LazyLoad.cs b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.LazyLoad.cs new file mode 100644 index 00000000..96725d52 --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.LazyLoad.cs @@ -0,0 +1,29 @@ +using System.Reflection; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class LazyMemberLoader + : ILazyMemberLoader + { + void ILazyMemberLoader.AddLazyMember(string name, MemberInfo member) + { + if (!lazyMembers.TryGetValue(name, out var members)) + lazyMembers[name] = members = []; + + members.Add(member); + } + + CompilerObject? ILazyMemberLoader.GetLazyMember(string name) + { + if (!lazyMembers.TryGetValue(name, out var members)) + return null; + + CompilerObject? result = null; + + foreach (var member in members) + result = Container.AddMember(name, Loader.LoadMember(member)); + + return result; + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.LazyMembers.cs b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.LazyMembers.cs new file mode 100644 index 00000000..8503705d --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.LazyMembers.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class LazyMemberLoader + { + private readonly Dictionary> lazyMembers = []; + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.Loader.cs b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.Loader.cs new file mode 100644 index 00000000..fa1d9f6e --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.Loader.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class LazyMemberLoader + { + public required ILoader Loader { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.cs b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.cs new file mode 100644 index 00000000..4e8226d7 --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/lazy member loader/LazyMemberLoader.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + internal sealed partial class LazyMemberLoader + : CompilerObject + { + + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/module body loader/ModuleBodyLoader.cs b/ZSharp.Importer.ILLoader/helpers/module body loader/ModuleBodyLoader.cs new file mode 100644 index 00000000..ee0f1392 --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/module body loader/ModuleBodyLoader.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + internal sealed partial class ModuleBodyLoader(ILLoader loader) + { + public ILLoader Loader { get; } = loader; + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Field.cs b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Field.cs new file mode 100644 index 00000000..c234b3cb --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Field.cs @@ -0,0 +1,12 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ModuleBodyLoader + { + private CompilerObject LoadField(IL.FieldInfo field) + { + if (!field.IsStatic) throw new ArgumentException("Only static fields are supported.", nameof(field)); + + return new Objects.Global(field, Loader); + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Method.Generic.cs b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Method.Generic.cs new file mode 100644 index 00000000..5f8ba89c --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Method.Generic.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ModuleBodyLoader + { + private CompilerObject LoadGenericMethod(IL.MethodInfo method) + { + return new Objects.GenericFunction(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Method.cs b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Method.cs new file mode 100644 index 00000000..6a6d0ecb --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Method.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ModuleBodyLoader + { + private CompilerObject LoadMethod(IL.MethodInfo method) + { + if (!method.IsStatic) throw new ArgumentException("Only static methods are supported.", nameof(method)); + + if (method.IsGenericMethodDefinition) + return LoadGenericMethod(method); + + return new Objects.Function(method, Loader); + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Property.cs b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Property.cs new file mode 100644 index 00000000..489a9aca --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.Property.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ModuleBodyLoader + { + private CompilerObject LoadProperty(IL.PropertyInfo property) + { + return new Objects.GlobalProperty(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.cs b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.cs new file mode 100644 index 00000000..60c9aa32 --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/module body loader/load/ModuleBodyLoader.Load.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ModuleBodyLoader + : ILoader + { + public CompilerObject LoadMember(IL.MemberInfo member) + => member switch + { + IL.FieldInfo field => LoadField(field), + IL.MethodInfo method => LoadMethod(method), + IL.PropertyInfo property => LoadProperty(property), + Type type => Loader.LoadType(type), + _ => throw new NotSupportedException(), + }; + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/type body loader/TypeBodyLoader.cs b/ZSharp.Importer.ILLoader/helpers/type body loader/TypeBodyLoader.cs new file mode 100644 index 00000000..42a6714e --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/type body loader/TypeBodyLoader.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + internal sealed partial class TypeBodyLoader(ILLoader loader) + { + public ILLoader Loader { get; } = loader; + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Field.cs b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Field.cs new file mode 100644 index 00000000..f662194e --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Field.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeBodyLoader + { + private CompilerObject LoadField(IL.FieldInfo field) + { + return new Objects.Field(field, Loader); + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Method.Generic.cs b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Method.Generic.cs new file mode 100644 index 00000000..ae59e25c --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Method.Generic.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeBodyLoader + { + private CompilerObject LoadGenericMethod(IL.MethodInfo method) + { + return new Objects.GenericMethod(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Method.cs b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Method.cs new file mode 100644 index 00000000..99848680 --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Method.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeBodyLoader + { + private CompilerObject LoadMethod(IL.MethodInfo method) + { + if (method.IsGenericMethodDefinition) + return LoadGenericMethod(method); + + return new Objects.Method(method, Loader); + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Property.cs b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Property.cs new file mode 100644 index 00000000..d867900d --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.Property.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeBodyLoader + { + private CompilerObject LoadProperty(IL.PropertyInfo property) + { + return new Objects.Property(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.cs b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.cs new file mode 100644 index 00000000..92690dfb --- /dev/null +++ b/ZSharp.Importer.ILLoader/helpers/type body loader/load/TypeBodyLoader.Load.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeBodyLoader + : ILoader + { + public CompilerObject LoadMember(IL.MemberInfo member) + => member switch + { + IL.FieldInfo field => LoadField(field), + IL.MethodInfo method => LoadMethod(method), + IL.PropertyInfo property => LoadProperty(property), + Type type => Loader.LoadType(type), + _ => throw new NotSupportedException(), + }; + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/ExposedObjectWrapper.cs b/ZSharp.Importer.ILLoader/il loader/ExposedObjectWrapper.cs new file mode 100644 index 00000000..4c3f9371 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/ExposedObjectWrapper.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Importer.ILLoader +{ + public sealed class ExposedObjectWrapper(object? target, IL.MethodInfo method) + { + private readonly object? target = target; + private readonly IL.MethodInfo method = method; + + public object? Invoke(object? args) + => method.Invoke(target, [args]); + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/ILLoader.Compiler.cs b/ZSharp.Importer.ILLoader/il loader/ILLoader.Compiler.cs new file mode 100644 index 00000000..1cc55c66 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/ILLoader.Compiler.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public Compiler.Compiler Compiler { get; } + + public ref Compiler.IR IR => ref Compiler.IR; + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/ILLoader.Events.cs b/ZSharp.Importer.ILLoader/il loader/ILLoader.Events.cs new file mode 100644 index 00000000..83404a8b --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/ILLoader.Events.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public Action? OnLoadOperator; + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/ILLoader.Expose.cs b/ZSharp.Importer.ILLoader/il loader/ILLoader.Expose.cs new file mode 100644 index 00000000..fef011a0 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/ILLoader.Expose.cs @@ -0,0 +1,84 @@ +using CommonZ.Utils; +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Importer.ILLoader +{ + public sealed partial class ILLoader + { + [MaybeNull] + private IR.Function castFunction; + + public Collection ExposeAsIR(T? obj) + => ExposeAsIR(obj, typeof(T)); + + public Collection ExposeAsIR(object? obj) + => ExposeAsIR(obj, obj?.GetType() ?? typeof(object)); + + public Collection ExposeAsIR(object? obj, Type type) + { + var rt = RequireRuntime(); + + if (obj is null) return rt.Expose(null); + + var coType = LoadType(type); + var irType = IR.CompileType(coType).Unwrap(); + + var code = rt.Expose(obj); + + var function = new IR.ConstructedFunction(castFunction!); + function.Arguments.Add(irType); + + code.Add(new IR.VM.Call(function)); + return code; + } + + public CompilerObject Expose(T? obj) + => Expose(obj, typeof(T)); + + public CompilerObject Expose(object? obj) + => Expose(obj, obj?.GetType() ?? typeof(object)); + + public CompilerObject Expose(object? obj, Type type) + => new RawIRCode(new([.. ExposeAsIR(obj, type)]) + { + Types = [IR.CompileType(LoadType(type)).Unwrap()] + }); + + public CompilerObject Expose(Delegate @delegate) + { + //var wrapped = new ExposedObjectWrapper(@delegate.Target, @delegate.Method); + // TODO: Cache this method info + // TODO: Add support for array. Currently not supported because there's no make-array instruction in IR + //var methodCO = LoadMethod(typeof(ExposedObjectWrapper).GetMethod("Invoke", [typeof(object)]) ?? throw new()); + //var @object = ExposeAsIR(wrapped); + if (@delegate.Target is null) + return LoadMethod(@delegate.Method); + + var @object = ExposeAsIR(@delegate.Target); + var methodCO = LoadMethod(@delegate.Method); + var objectCode = RawIRCode.From(@object, LoadType(@delegate.Target.GetType())); + + return new Objects.BoundMethod() + { + Method = methodCO, + Object = objectCode + }; + } + + [MemberNotNull(nameof(castFunction))] + private void SetupExposeSystem() + { + var rt = RequireRuntime(); + + var castFunctionReturnType = new IR.GenericParameter("T"); + castFunction = new(castFunctionReturnType); + castFunction.GenericParameters.Add(castFunctionReturnType); + castFunction.Signature.Args.Parameters.Add(new("obj", rt.TypeSystem.Object)); + + rt.AddFunction(castFunction, ((Delegate)Cast).Method.GetGenericMethodDefinition()); + } + + public static T Cast(object obj) + => (T)obj; + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/ILLoader.Namespaces.cs b/ZSharp.Importer.ILLoader/il loader/ILLoader.Namespaces.cs new file mode 100644 index 00000000..c518b068 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/ILLoader.Namespaces.cs @@ -0,0 +1,35 @@ +using CommonZ.Utils; +using ZSharp.Importer.ILLoader.Objects; + +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public Mapping Namespaces { get; } = []; + + public Namespace Namespace(string fullName) + { + var parts = fullName.Split('.'); + + if (parts.Length == 0) + throw new ArgumentException( + "Namespace name must contain at least 1 identifier", + nameof(fullName) + ); + + if (!Namespaces.TryGetValue(parts[0], out var @namespace)) + @namespace = Namespaces[parts[0]] = new(parts[0], this); + + foreach (var part in parts.Skip(1)) + if (!@namespace.Members.TryGetValue(part, out var member)) + @namespace.AddMember(part, member = new Namespace(part, this)); + else if (member is not Namespace ns) + throw new ArgumentException( + $"{part} in {@namespace.FullName} is not a namespace" + ); + else @namespace = ns; + + return @namespace; + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/ILLoader.Runtime.cs b/ZSharp.Importer.ILLoader/il loader/ILLoader.Runtime.cs new file mode 100644 index 00000000..da5be176 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/ILLoader.Runtime.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public Platform.Runtime.Runtime? Runtime { get; } + + public Platform.Runtime.Runtime RequireRuntime() + => Runtime ?? throw new InvalidOperationException("ILLoader was not initialized with a Runtime"); + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/ILLoader.TypeSystem.cs b/ZSharp.Importer.ILLoader/il loader/ILLoader.TypeSystem.cs new file mode 100644 index 00000000..18c4ae68 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/ILLoader.TypeSystem.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public TypeSystem TypeSystem { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/ILLoader.cs b/ZSharp.Importer.ILLoader/il loader/ILLoader.cs new file mode 100644 index 00000000..20e9caa3 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/ILLoader.cs @@ -0,0 +1,65 @@ +namespace ZSharp.Importer.ILLoader +{ + public sealed partial class ILLoader + { + public ILLoader(Compiler.Compiler compiler, Platform.Runtime.Runtime runtime) + { + Compiler = compiler; + Runtime = runtime; + + TypeSystem = new() + { + Array = new Objects.ArrayType(Runtime.TypeSystem.Array), + Boolean = new Objects.BooleanType(Runtime.TypeSystem.Boolean), + Char = new Objects.CharType(Runtime.TypeSystem.Char), + Float16 = new Objects.Float16Type(Runtime.TypeSystem.Float16), + Float32 = new Objects.Float32Type(Runtime.TypeSystem.Float32), + Float64 = new Objects.Float64Type(Runtime.TypeSystem.Float64), + Float128 = new Objects.Float128Type(Runtime.TypeSystem.Float128), + Object = new Objects.ObjectType(Runtime.TypeSystem.Object), + Pointer = new Objects.PointerType(Runtime.TypeSystem.Pointer), + Reference = new Objects.ReferenceType(Runtime.TypeSystem.Reference), + SInt8 = new Objects.SInt8Type(Runtime.TypeSystem.SInt8), + SInt16 = new Objects.SInt16Type(Runtime.TypeSystem.SInt16), + SInt32 = new Objects.SInt32Type(Runtime.TypeSystem.SInt32), + SInt64 = new Objects.SInt64Type(Runtime.TypeSystem.SInt64), + SIntNative = new Objects.SIntNativeType(Runtime.TypeSystem.SIntNative), + String = new Objects.StringType(Runtime.TypeSystem.String), + UInt8 = new Objects.UInt8Type(Runtime.TypeSystem.UInt8), + UInt16 = new Objects.UInt16Type(Runtime.TypeSystem.UInt16), + UInt32 = new Objects.UInt32Type(Runtime.TypeSystem.UInt32), + UInt64 = new Objects.UInt64Type(Runtime.TypeSystem.UInt64), + UIntNative = new Objects.UIntNativeType(Runtime.TypeSystem.UIntNative), + Void = new Objects.VoidType(Runtime.TypeSystem.Void), + }; + + foreach (var (il, co) in (IEnumerable<(Type, CompilerObject)>)[ + (typeof(bool), TypeSystem.Boolean), + (typeof(char), TypeSystem.Char), + (typeof(Half), TypeSystem.Float16), + (typeof(float), TypeSystem.Float32), + (typeof(double), TypeSystem.Float64), + (typeof(decimal), TypeSystem.Float128), + (typeof(object), TypeSystem.Object), + (typeof(sbyte), TypeSystem.SInt8), + (typeof(short), TypeSystem.SInt16), + (typeof(int), TypeSystem.SInt32), + (typeof(long), TypeSystem.SInt64), + (typeof(nint), TypeSystem.SIntNative), + (typeof(string), TypeSystem.String), + (typeof(byte), TypeSystem.UInt8), + (typeof(ushort), TypeSystem.UInt16), + (typeof(uint), TypeSystem.UInt32), + (typeof(ulong), TypeSystem.UInt64), + (typeof(nuint), TypeSystem.UIntNative), + (typeof(void), TypeSystem.Void), + ]) + { + typeCache[il] = co; + } + + if (runtime is not null) + SetupExposeSystem(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Constructor.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Constructor.cs new file mode 100644 index 00000000..25c677ed --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Constructor.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadConstructor(IL.ConstructorInfo constructor) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Event.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Event.cs new file mode 100644 index 00000000..cb502e7f --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Event.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadEvent(IL.EventInfo @event) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Field.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Field.cs new file mode 100644 index 00000000..9982820e --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Field.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadField(IL.FieldInfo field) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Method.Generic.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Method.Generic.cs new file mode 100644 index 00000000..a42de207 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Method.Generic.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadGenericMethod(IL.MethodInfo method) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Method.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Method.cs new file mode 100644 index 00000000..f4b0cf93 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Method.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadMethod(IL.MethodInfo method) + { + if (method.IsGenericMethodDefinition) + return LoadGenericMethod(method); + + var result = new Objects.Method(method, this); + + return result; + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Property.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Property.cs new file mode 100644 index 00000000..4ac45447 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.Property.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadProperty(IL.PropertyInfo property) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.cs new file mode 100644 index 00000000..4f519a0f --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Member.cs @@ -0,0 +1,24 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + private readonly Dictionary memberCache = []; + + public CompilerObject LoadMember(IL.MemberInfo member) + { + if (!memberCache.TryGetValue(member, out var @object)) + @object = memberCache[member] = member switch + { + IL.ConstructorInfo constructor => LoadConstructor(constructor), + IL.EventInfo @event => LoadEvent(@event), + IL.FieldInfo field => LoadField(field), + IL.MethodInfo method => LoadMethod(method), + IL.PropertyInfo property => LoadProperty(property), + Type type => LoadType(type), + _ => throw new NotSupportedException() + }; + + return @object; + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Module.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Module.cs new file mode 100644 index 00000000..84573ff6 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Module.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + private readonly Dictionary moduleCache = []; + + public CompilerObject LoadModule(IL.Module module) + { + if (!moduleCache.TryGetValue(module, out var @object)) + @object = moduleCache[module] = DispatchLoadModule(module); + + return @object; + } + + private CompilerObject DispatchLoadModule(IL.Module module) + { + return new Objects.Module(module, this); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Class.Generic.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Class.Generic.cs new file mode 100644 index 00000000..5dfb70c5 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Class.Generic.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadGenericClass(Type @class) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Class.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Class.cs new file mode 100644 index 00000000..dbbbc95a --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Class.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadClass(Type @class) + { + if (@class.IsGenericTypeDefinition) + return LoadGenericClass(@class); + + return new Objects.Class(@class, this); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Enum.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Enum.cs new file mode 100644 index 00000000..22aadad3 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Enum.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadEnum(Type @enum) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Generic.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Generic.cs new file mode 100644 index 00000000..4a1d047f --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Generic.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadConstructedGenericType(Type type) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Interface.Generic.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Interface.Generic.cs new file mode 100644 index 00000000..f6fddbc6 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Interface.Generic.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadGenericInterface(Type @enum) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Interface.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Interface.cs new file mode 100644 index 00000000..967efaf0 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Interface.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadInterface(Type @interface) + { + if (@interface.IsGenericTypeDefinition) + return LoadGenericInterface(@interface); + + return new Objects.Interface(@interface, this); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Modified.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Modified.cs new file mode 100644 index 00000000..f92ce484 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Modified.cs @@ -0,0 +1,42 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadModifiedType(Type type) + { + if (type.IsArray) return LoadArrayType(type); + if (type.IsPointer) return LoadPointerType(type); + if (type.IsByRef) return LoadReferenceType(type); + + throw new NotSupportedException(); + } + + public CompilerObject LoadArrayType(Type array) + => LoadModifiedType( + TypeSystem.Array, + array.GetElementType() ?? throw new ArgumentException("Type must have an element type", nameof(array)) + ); + + public CompilerObject LoadPointerType(Type pointer) + => LoadModifiedType( + TypeSystem.Array, + pointer.GetElementType() ?? throw new ArgumentException("Type must have an element type", nameof(pointer)) + ); + + public CompilerObject LoadReferenceType(Type reference) + => LoadModifiedType( + TypeSystem.Array, + reference.GetElementType() ?? throw new ArgumentException("Type must have an element type", nameof(reference)) + ); + + private CompilerObject LoadModifiedType(CompilerObject modifier, Type inner) + { + if (!modifier.Is(out var typeModifier)) + throw new NotSupportedException(); + + var typeCO = LoadType(inner); + + return typeModifier.Modify(typeCO); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Struct.Generic.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Struct.Generic.cs new file mode 100644 index 00000000..f55e75e1 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Struct.Generic.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadGenericStruct(Type @enum) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Struct.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Struct.cs new file mode 100644 index 00000000..0e0c5796 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.Struct.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + public CompilerObject LoadStruct(Type @struct) + { + if (@struct.IsGenericTypeDefinition) + return LoadGenericStruct(@struct); + + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.cs b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.cs new file mode 100644 index 00000000..d6b90235 --- /dev/null +++ b/ZSharp.Importer.ILLoader/il loader/load/ILLoader.Load.Type.cs @@ -0,0 +1,31 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class ILLoader + { + private readonly Dictionary typeCache = []; + + public CompilerObject LoadType(Type type) + { + if (!typeCache.TryGetValue(type, out var @object)) + @object = typeCache[type] = DispatchLoadType(type); + + return @object; + } + + private CompilerObject DispatchLoadType(Type type) + { + if (type.IsConstructedGenericType) + return LoadConstructedGenericType(type); + + if (type.IsClass) return LoadClass(type); + if (type.IsInterface) return LoadInterface(type); + if (type.IsEnum) return LoadEnum(type); + if (type.IsValueType) return LoadStruct(type); + + if (type.HasElementType) + return LoadModifiedType(type); + + throw new NotSupportedException(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/callable/argument stream/ArgumentStream.cs b/ZSharp.Importer.ILLoader/objects/callable/argument stream/ArgumentStream.cs new file mode 100644 index 00000000..a221e71f --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/callable/argument stream/ArgumentStream.cs @@ -0,0 +1,38 @@ +using ZSharp.Compiler; +using ZSharp.Compiler.Features.Callable; + +namespace ZSharp.Importer.ILLoader.Objects +{ + internal sealed class ArgumentStream + : IArgumentStream + { + internal readonly List args = []; + private readonly Dictionary kwArgs = []; + + public ArgumentStream(Argument[] arguments) + { + foreach (var argument in arguments) + if (argument.Name is null) args.Add(argument.Object); + else kwArgs[argument.Name] = argument.Object; + } + + bool IArgumentStream.HasArguments => args.Count > 0 || kwArgs.Count > 0; + + CompilerObject? IArgumentStream.PopArgument() + { + if (args.Count == 0) return null; + var arg = args[0]; + args.RemoveAt(0); + return arg; + } + + CompilerObject? IArgumentStream.PopArgument(string name) + { + if (!kwArgs.Remove(name, out var arg)) return null; + return arg; + } + + public bool HasArgument(string name) + => kwArgs.ContainsKey(name); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/callable/parameter/Parameter.IL.cs b/ZSharp.Importer.ILLoader/objects/callable/parameter/Parameter.IL.cs new file mode 100644 index 00000000..b0f86b67 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/callable/parameter/Parameter.IL.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Parameter + { + public IL.ParameterInfo IL { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/callable/parameter/Parameter.cs b/ZSharp.Importer.ILLoader/objects/callable/parameter/Parameter.cs new file mode 100644 index 00000000..fd473f93 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/callable/parameter/Parameter.cs @@ -0,0 +1,34 @@ +using System.Net.WebSockets; +using ZSharp.Compiler; +using ZSharp.Compiler.Features.Callable; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Parameter + : CompilerObject + , IParameter + { + public string Name { get; } + + public CompilerObject Type { get; } + + public Parameter(IL.ParameterInfo il, ILLoader loader) + { + IL = il; + + Name = IL.AliasOrName(); + Type = loader.LoadType(IL.ParameterType); + } + + IResult IParameter.Match(Compiler.Compiler compiler, IArgumentStream arguments) + { + if (!arguments.PopArgument(Name, out var argument) && + !arguments.PopArgument(out argument) + ) + if (IL.HasDefaultValue) return Result.Error("Default values are not supported yet."); + else return Result.Error($"No argument provided for parameter '{this}'."); + + return compiler.CG.ImplicitCast(argument, Type); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/callable/signature/Signature.cs b/ZSharp.Importer.ILLoader/objects/callable/signature/Signature.cs new file mode 100644 index 00000000..2c5a261b --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/callable/signature/Signature.cs @@ -0,0 +1,15 @@ +using CommonZ.Utils; +using ZSharp.Compiler.Features.Callable; + +namespace ZSharp.Importer.ILLoader.Objects +{ + internal sealed partial class Signature + : CompilerObject + , ISignature + { + internal readonly Collection parameters = []; + + IEnumerable ISignature.Parameters(Compiler.Compiler compiler) + => parameters.Cast(); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.Call.cs b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.Call.cs new file mode 100644 index 00000000..bd894a77 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.Call.cs @@ -0,0 +1,37 @@ +using ZSharp.Compiler; +using ZSharp.Compiler.Features.Callable; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Function + : ICTCallable + { + IResult ICTCallable.Call(Compiler.Compiler compiler, Argument[] arguments) + { + if ( + BoundSignature.Create(compiler, signature, new ArgumentStream(arguments)) + .When(out var boundSignature) + .Error(out var error) + ) return Result.Error(error); + + IRCode result = new(); + + foreach (var boundParameter in boundSignature!.Parameters) + { + if ( + compiler.IR.CompileCode(boundParameter.ArgumentObject, null) + .When(out var argumentCode) + .Error(out error) + ) + return Result.Error(error); + + result.Instructions.AddRange(argumentCode!.Instructions); + } + + result.Instructions.Add(new IR.VM.Call(GetIR())); + result.Types.Add(GetIR().ReturnType); + + return Result.Ok(RawIRCode.From(result.Instructions, ReturnType)); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.IL.cs b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.IL.cs new file mode 100644 index 00000000..c7437dde --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.IL.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Function + { + public ILLoader Loader { get; } + + public IL.MethodInfo IL { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.IR.cs b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.IR.cs new file mode 100644 index 00000000..63a203f4 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.IR.cs @@ -0,0 +1,21 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Function + { + private IR.Function? IR { get; set; } + + private IR.Function GetIR() + { + if (IR is null) + { + var returnTypeCO = Loader.LoadType(IL.ReturnType); + if (Loader.IR.CompileType(returnTypeCO).When(out var returnTypeIR).Error(out var error)) + throw new InvalidOperationException($"Failed to load return type for method {IL.Name}: {error}"); + IR = new(returnTypeIR!); + Loader.RequireRuntime().AddFunction(IR, IL); + } + + return IR; + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.Signature.cs b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.Signature.cs new file mode 100644 index 00000000..67f29537 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.Signature.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Function + { + private readonly Signature signature = new(); + + public CompilerObject Signature => signature; + + public CompilerObject ReturnType { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.cs b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.cs new file mode 100644 index 00000000..ea430d70 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/function/concrete/Function.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Function + : CompilerObject + { + public Function(IL.MethodInfo il, ILLoader loader) + { + IL = il; + Loader = loader; + + ReturnType = loader.LoadType(IL.ReturnType); + + foreach (var parameter in IL.GetParameters()) + signature.parameters.Add(new Parameter(parameter, loader)); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/function/generic/GenericFunction.IL.cs b/ZSharp.Importer.ILLoader/objects/modular/function/generic/GenericFunction.IL.cs new file mode 100644 index 00000000..80a87127 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/function/generic/GenericFunction.IL.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class GenericFunction + { + public IL.MethodInfo IL { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/function/generic/GenericFunction.cs b/ZSharp.Importer.ILLoader/objects/modular/function/generic/GenericFunction.cs new file mode 100644 index 00000000..a5111105 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/function/generic/GenericFunction.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class GenericFunction + : CompilerObject + { + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/global/Global.CG.Get.cs b/ZSharp.Importer.ILLoader/objects/modular/global/Global.CG.Get.cs new file mode 100644 index 00000000..60c39eed --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/global/Global.CG.Get.cs @@ -0,0 +1,16 @@ +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Global + : ICTGet + { + IResult ICTGet.Get(Compiler.Compiler compiler) + => Result.Ok(new RawIRCode(new([ + new IR.VM.GetGlobal(IR) + ]) + { + Types = [ compiler.IR.CompileType(Type).Unwrap() ] + })); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/global/Global.IL.cs b/ZSharp.Importer.ILLoader/objects/modular/global/Global.IL.cs new file mode 100644 index 00000000..46f542a7 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/global/Global.IL.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Global + { + public IL.FieldInfo IL { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/global/Global.IR.cs b/ZSharp.Importer.ILLoader/objects/modular/global/Global.IR.cs new file mode 100644 index 00000000..4d822aac --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/global/Global.IR.cs @@ -0,0 +1,30 @@ +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Global + : ICompileIRDefinitionAs + { + public IR.Global? IR { get; private set; } + + IResult ICompileIRDefinitionAs.CompileIRDefinition(Compiler.Compiler compiler, object? target) + { + if (IR is not null) return Result.Ok(IR); + + if (target is not Platform.Runtime.Runtime rt) + return Result.Error("Invalid target platform"); + + if ( + compiler.IR.CompileType(Type) + .When(out var type) + .Error(out var error) + ) return Result.Error(error); + + IR = new(Name, type!); + + rt.AddGlobal(IR, IL); + + return Result.Ok(IR); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/global/Global.Type.cs b/ZSharp.Importer.ILLoader/objects/modular/global/Global.Type.cs new file mode 100644 index 00000000..a97632ff --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/global/Global.Type.cs @@ -0,0 +1,10 @@ +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Global + : ITyped + { + public CompilerObject Type { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/global/Global.cs b/ZSharp.Importer.ILLoader/objects/modular/global/Global.cs new file mode 100644 index 00000000..427c03da --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/global/Global.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Global + : CompilerObject + { + public string Name => IL.Name; + + public Global(IL.FieldInfo il, ILLoader loader) + { + IL = il; + Type = loader.LoadType(il.FieldType); + IR = loader.Compiler.IR.CompileDefinition(this, loader.Runtime).Unwrap(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/module/Module.IL.cs b/ZSharp.Importer.ILLoader/objects/modular/module/Module.IL.cs new file mode 100644 index 00000000..37e56a84 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/module/Module.IL.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Module + { + public IL.Module IL { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/module/Module.LazyLoad.cs b/ZSharp.Importer.ILLoader/objects/modular/module/Module.LazyLoad.cs new file mode 100644 index 00000000..2723e61c --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/module/Module.LazyLoad.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Module + { + public ILLoader Loader { get; } + + internal ILazyMemberLoader LazyLoader { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/module/Module.Member.cs b/ZSharp.Importer.ILLoader/objects/modular/module/Module.Member.cs new file mode 100644 index 00000000..da7e6a16 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/module/Module.Member.cs @@ -0,0 +1,34 @@ +using CommonZ.Utils; +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Module + : IAddMember + , ICTGetMember + { + public Mapping Members { get; } = []; + + CompilerObject IAddMember.AddMember(string name, CompilerObject member) + { + var result = OnAddResult.None; + if (member is IOnAddTo onAdd) + result = onAdd.OnAddTo(this); + + if (result == OnAddResult.None) + Members.Add(name, member); + + return member; + } + + IResult ICTGetMember.Member(Compiler.Compiler compiler, MemberName name) + { + if (!Members.TryGetValue(name, out var member) && !LazyLoader.GetLazyMember(name, out member)) + return Result.Error( + $"Could not find member {name} in module {IL.Name}" + ); + + return Result.Ok(member); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/module/Module.cs b/ZSharp.Importer.ILLoader/objects/modular/module/Module.cs new file mode 100644 index 00000000..1e45a73a --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/module/Module.cs @@ -0,0 +1,24 @@ +using System.Reflection; + +namespace ZSharp.Importer.ILLoader.Objects +{ + internal sealed partial class Module + : CompilerObject + { + public string Name => IL.Name; + + public Module(IL.Module il, ILLoader loader) + { + IL = il; + Loader = loader; + + LazyLoader = new LazyMemberLoader() + { + Container = this, + Loader = new ModuleBodyLoader(loader) + }; + + Prepare.PrepareModule(this, loader); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/property/GlobalProperty.cs b/ZSharp.Importer.ILLoader/objects/modular/property/GlobalProperty.cs new file mode 100644 index 00000000..84a78379 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/property/GlobalProperty.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class GlobalProperty + : CompilerObject + { + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.IL.cs b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.IL.cs new file mode 100644 index 00000000..4dd1cb7d --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.IL.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class TypeAsModule + { + public Type IL { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.LazyLoad.cs b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.LazyLoad.cs new file mode 100644 index 00000000..97ea2a80 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.LazyLoad.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class TypeAsModule + { + public ILLoader Loader { get; } + + internal ModuleBodyLoader BodyLoader { get; } + + internal ILazyMemberLoader LazyLoader { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.Member.cs b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.Member.cs new file mode 100644 index 00000000..cf372c9d --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.Member.cs @@ -0,0 +1,34 @@ +using CommonZ.Utils; +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class TypeAsModule + : IAddMember + , ICTGetMember + { + public Mapping Members { get; } = []; + + CompilerObject IAddMember.AddMember(string name, CompilerObject member) + { + var result = OnAddResult.None; + if (member is IOnAddTo onAdd) + result = onAdd.OnAddTo(this); + + if (result == OnAddResult.None) + Members.Add(name, member); + + return member; + } + + IResult ICTGetMember.Member(Compiler.Compiler compiler, MemberName name) + { + if (!Members.TryGetValue(name, out var result) && !LazyLoader.GetLazyMember(name, out result)) + return Result.Error( + $"Could not find member {name} in module {IL.Name}" + ); + + return Result.Ok(result); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.Namespace.cs b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.Namespace.cs new file mode 100644 index 00000000..a7a6e291 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.Namespace.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class TypeAsModule + { + public string RootNamespace { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.cs b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.cs new file mode 100644 index 00000000..654cd678 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/modular/type as module/TypeAsModule.cs @@ -0,0 +1,27 @@ +using System.Reflection; + +namespace ZSharp.Importer.ILLoader.Objects +{ + internal sealed partial class TypeAsModule + : CompilerObject + { + public string Name => IL.Name; + + public TypeAsModule(Type il, ILLoader loader) + { + IL = il; + Loader = loader; + LazyLoader = new LazyMemberLoader() + { + Container = this, + Loader = new ModuleBodyLoader(loader) + }; + + if (il.GetCustomAttribute() is SetNamespaceAttribute setNamespace) + RootNamespace = setNamespace.Name; + else RootNamespace = string.Empty; + + Prepare.PrepareTypeAsModule(this, loader); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/namespace/Namespace.LazyLoad.cs b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.LazyLoad.cs new file mode 100644 index 00000000..04bcc851 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.LazyLoad.cs @@ -0,0 +1,21 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Namespace + : ILazyMemberLoader + { + private readonly Dictionary lazyLoadedMembers = []; + + public ILLoader Loader { get; } = loader; + + public void AddLazyMember(MemberName member, IL.MemberInfo lazyLoadedMember) + => lazyLoadedMembers.Add(member, lazyLoadedMember); + + public CompilerObject? GetLazyMember(string name) + { + if (!lazyLoadedMembers.TryGetValue(name, out var member)) + return null; + + return Loader.LoadMember(member); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/namespace/Namespace.Member.cs b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.Member.cs new file mode 100644 index 00000000..cb581917 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.Member.cs @@ -0,0 +1,33 @@ +using CommonZ.Utils; +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Namespace + : ICTGetMember + { + public Mapping Members { get; } = []; + + public void AddMember(string name, CompilerObject member) + { + var result = OnAddResult.None; + if (member is IOnAddTo onAdd) + result = onAdd.OnAddTo(this); + + if (result == OnAddResult.None) + Members.Add(name, member); + } + + IResult ICTGetMember.Member(Compiler.Compiler compiler, MemberName member) + { + if (!Members.TryGetValue(member, out var result)) + if ((result = GetLazyMember(member)) is not null) + AddMember(member, result); + else return Result.Error( + $"Could not find member {member} in namespace {FullName}" + ); + + return Result.Ok(result); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/namespace/Namespace.OnAddTo.cs b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.OnAddTo.cs new file mode 100644 index 00000000..f9f6809c --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.OnAddTo.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Namespace + : IOnAddTo + { + OnAddResult IOnAddTo.OnAddTo(Namespace @object) + { + if (HasParent) return OnAddResult.Error; + + Parent = @object; + + return OnAddResult.None; + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/namespace/Namespace.Parent.cs b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.Parent.cs new file mode 100644 index 00000000..2fa160cc --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.Parent.cs @@ -0,0 +1,15 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Namespace + { + public Namespace? Parent { get; private set; } + + [MemberNotNullWhen(true, nameof(Parent))] + public bool HasParent => Parent is not null; + + public string FullName => + Parent is null ? Name : $"{Parent.FullName}.{Name}"; + } +} diff --git a/ZSharp.Importer.ILLoader/objects/namespace/Namespace.cs b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.cs new file mode 100644 index 00000000..1df1501f --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/namespace/Namespace.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Namespace(string name, ILLoader loader) + : CompilerObject + { + public string Name { get; set; } = name; + + public bool IsAnonymous => Name == string.Empty; + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Call.cs b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Call.cs new file mode 100644 index 00000000..1d73c231 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Call.cs @@ -0,0 +1,16 @@ +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Class + : ICTCallable + { + IResult ICTCallable.Call(Compiler.Compiler compiler, Argument[] arguments) + { + if (Constructor is null) + return Result.Error("Class doesn't have a constructor and cannot be instantiated."); + + return compiler.CG.Call(Constructor, arguments); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Constructor.cs b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Constructor.cs new file mode 100644 index 00000000..c217f123 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Constructor.cs @@ -0,0 +1,29 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Class + { + private CompilerObject? constructor; + + public CompilerObject? Constructor + { + get + { + if (constructor is null) + { + var constructors = IL.GetConstructors(); + + if (constructors.Length > 1) + throw new NotImplementedException("Overloaded constructors are not supported."); + + if (constructors.Length == 0) + return null; + + constructor = new Constructor(constructors[0], Loader); + (constructor as IOnAddTo)?.OnAddTo(this); + } + + return constructor; + } + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.IL.cs b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.IL.cs new file mode 100644 index 00000000..1107cd66 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.IL.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Class + { + public Type IL { get; } + + public ILLoader Loader { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.IR.cs b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.IR.cs new file mode 100644 index 00000000..9e475017 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.IR.cs @@ -0,0 +1,33 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Class + : ICompileIRDefinitionAs + , ICompileIRType> + , ICompileIRReference> + { + private IR.Class? IR { get; set; } + + IResult ICompileIRDefinitionAs.CompileIRDefinition(Compiler.Compiler compiler, object? target) + => Result.Ok(GetIR()); + + IResult, Error> ICompileIRReference>.CompileIRReference(Compiler.Compiler compiler) + => Result>.Ok(new ClassReference(GetIR())); + + IResult, Error> ICompileIRType>.CompileIRType(Compiler.Compiler compiler) + => Result>.Ok(new ClassReference(GetIR())); + + private IR.Class GetIR() + { + if (IR is null) + { + IR = new(IL.Name); + Loader.RequireRuntime().AddTypeDefinition(IR, IL); + } + + return IR; + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.LazyLoad.cs b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.LazyLoad.cs new file mode 100644 index 00000000..2283a28e --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.LazyLoad.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Class + { + public ILazyMemberLoader LazyLoader { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Member.cs b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Member.cs new file mode 100644 index 00000000..f36d65eb --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Member.cs @@ -0,0 +1,49 @@ +using CommonZ.Utils; +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Class + : IAddMember + , ICTGetMember + , IRTGetMember + { + public Mapping Members { get; } = []; + + CompilerObject IAddMember.AddMember(string name, CompilerObject member) + { + var result = OnAddResult.None; + if (member is IOnAddTo onAdd) + result = onAdd.OnAddTo(this); + + if (result == OnAddResult.None) + Members.Add(name, member); + + return member; + } + + IResult ICTGetMember.Member(Compiler.Compiler compiler, MemberName name) + { + if (!Members.TryGetValue(name, out var member) && !LazyLoader.GetLazyMember(name, out member)) + return Result.Error( + $"Could not find member {name} in type {IL.Name}" + ); + + return Result.Ok(member); + } + + IResult IRTGetMember.Member(Compiler.Compiler compiler, CompilerObject @object, MemberName name) + { + if ( + compiler.CG.Member(this, name) + .When(out var member) + .Error(out var error) + ) return Result.Error(error); + + if (member!.Is(out var bindable)) + return bindable.Bind(compiler, @object); + + return Result.Ok(member); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Type.cs b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Type.cs new file mode 100644 index 00000000..ce639b17 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.Type.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Class + : IReferenceType + , IILType + { + Type IILType.GetILType() + => IL; + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.cs b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.cs new file mode 100644 index 00000000..920ef3fd --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/concrete/Class.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + internal sealed partial class Class + : CompilerObject + { + public Class(Type il, ILLoader loader) + { + IL = il; + Loader = loader; + + LazyLoader = new LazyMemberLoader() + { + Container = this, + Loader = new TypeBodyLoader(loader) + }; + + Prepare.PrepareType(this, loader); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/generic/GenericClass.T.cs b/ZSharp.Importer.ILLoader/objects/oop/class/generic/GenericClass.T.cs new file mode 100644 index 00000000..c3d7431d --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/generic/GenericClass.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class GenericClass + { + + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/class/generic/GenericClass.cs b/ZSharp.Importer.ILLoader/objects/oop/class/generic/GenericClass.cs new file mode 100644 index 00000000..bd040795 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/class/generic/GenericClass.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class GenericClass + : CompilerObject + { + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.Call.cs b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.Call.cs new file mode 100644 index 00000000..eaa1875b --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.Call.cs @@ -0,0 +1,66 @@ +using ZSharp.Compiler; +using ZSharp.Compiler.Features.Callable; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Constructor + : ICTCallable + { + IResult ICTCallable.Call(Compiler.Compiler compiler, Argument[] arguments) + { + if (Owner is null) + return Result.Error("Constructor doesn't yet have an owner and cannot be used."); + + if ( + compiler.IR.CompileReference(Owner) + .When(out var owner) + .Error(out var error) + ) return Result.Error(error); + + var stream = new ArgumentStream(arguments); + + IR.VM.Instruction callInstruction; + CompilerObject returnType; + + var constructor = new IR.ConstructorReference(GetIR()) + { + OwningType = owner! + }; + + if (stream.HasArgument(thisParameter.Name)) + { + returnType = compiler.TS.Void; + callInstruction = new IR.VM.Call(constructor); + } else + { + stream.args.Insert(0, RawIRCode.From([], Owner)); + returnType = Owner; + callInstruction = new IR.VM.CreateInstance(constructor); + } + + if ( + BoundSignature.Create(compiler, signature, stream) + .When(out var boundSignature) + .Error(out error) + ) return Result.Error(error); + + IRCode result = new(); + + foreach (var boundParameter in boundSignature!.Parameters) + { + if ( + compiler.IR.CompileCode(boundParameter.ArgumentObject, null) + .When(out var argumentCode) + .Error(out error) + ) + return Result.Error(error); + + result.Instructions.AddRange(argumentCode!.Instructions); + } + + result.Instructions.Add(callInstruction); + + return Result.Ok(RawIRCode.From(result.Instructions, returnType)); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.IL.cs b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.IL.cs new file mode 100644 index 00000000..5f394bc7 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.IL.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Constructor + { + public IL.ConstructorInfo IL { get; } + + public ILLoader Loader { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.IR.cs b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.IR.cs new file mode 100644 index 00000000..faed2d7f --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.IR.cs @@ -0,0 +1,24 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Constructor + { + private IR.Constructor? IR { get; set; } + + private IR.Constructor GetIR() + { + if (IR is null) + { + var returnTypeCO = Loader.LoadType(typeof(void)); + if (Loader.IR.CompileType(returnTypeCO).When(out var returnTypeIR).Error(out var error)) + throw new InvalidOperationException($"Failed to load return type for method {IL.Name}: {error}"); + IR = new(string.Empty) + { + Method = new(returnTypeIR!) + }; + Loader.RequireRuntime().AddFunction(IR.Method.UnderlyingFunction, IL); + } + + return IR; + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.Owner.cs b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.Owner.cs new file mode 100644 index 00000000..057b8e6f --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.Owner.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Constructor + : IOnAddTo + { + public CompilerObject? Owner { get; private set; } + + OnAddResult IOnAddTo.OnAddTo(CompilerObject @object) + { + if (@object is null || Owner is not null && @object != Owner) + return OnAddResult.Error; + + Owner = @object; + return OnAddResult.None; + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.Signature.cs b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.Signature.cs new file mode 100644 index 00000000..009ef70c --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.Signature.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Constructor + { + public readonly ThisParameter thisParameter; + + public readonly Signature signature = new(); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.T.cs b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.T.cs new file mode 100644 index 00000000..bb763919 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Constructor + { + + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.cs b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.cs new file mode 100644 index 00000000..f7e976b0 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/constructor/Constructor.cs @@ -0,0 +1,19 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + internal sealed partial class Constructor + : CompilerObject + { + public Constructor(IL.ConstructorInfo il, ILLoader loader) + { + IL = il; + Loader = loader; + + thisParameter = new(il, loader); + + signature.parameters.Add(thisParameter); + + foreach (var parameter in il.GetParameters()) + signature.parameters.Add(new Parameter(parameter, loader)); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/enum/Enum.cs b/ZSharp.Importer.ILLoader/objects/oop/enum/Enum.cs new file mode 100644 index 00000000..d6b186b3 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/enum/Enum.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Enum + : CompilerObject + { + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/field/Field.cs b/ZSharp.Importer.ILLoader/objects/oop/field/Field.cs new file mode 100644 index 00000000..8848b892 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/field/Field.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Field + : CompilerObject + { + public Field(IL.FieldInfo il, ILLoader loader) + { + + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/interface/concrete/Interface.IL.cs b/ZSharp.Importer.ILLoader/objects/oop/interface/concrete/Interface.IL.cs new file mode 100644 index 00000000..e5d6a909 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/interface/concrete/Interface.IL.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Interface + { + public Type IL { get; } + + public ILLoader Loader { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/interface/concrete/Interface.IR.cs b/ZSharp.Importer.ILLoader/objects/oop/interface/concrete/Interface.IR.cs new file mode 100644 index 00000000..66cfaeeb --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/interface/concrete/Interface.IR.cs @@ -0,0 +1,37 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Interface + : ICompileIRDefinitionAs + , ICompileIRType> + { + public IR.Interface? IR { get; private set; } + + IResult ICompileIRDefinitionAs.CompileIRDefinition(Compiler.Compiler compiler, object? target) + { + if (IR is not null) return Result.Ok(IR); + + if (target is not Platform.Runtime.Runtime rt) + return Result.Error("Invalid target platform"); + + IR = new(Name); + + rt.AddTypeDefinition(IR, IL); + + return Result.Ok(IR); + } + + IResult, Error> ICompileIRType>.CompileIRType(Compiler.Compiler compiler) + { + if ( + compiler.IR.CompileDefinition(this, null) + .When(out var definition) + .Error(out var error) + ) return Result>.Error(error); + + return Result>.Ok(new InterfaceReference(definition!)); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/interface/concrete/Interface.cs b/ZSharp.Importer.ILLoader/objects/oop/interface/concrete/Interface.cs new file mode 100644 index 00000000..d3960904 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/interface/concrete/Interface.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Interface + : CompilerObject + { + public string Name => IL.Name; + + public Interface(Type @interface, ILLoader loader) + { + IL = @interface; + Loader = loader; + + IR = loader.Compiler.IR.CompileDefinition(this, loader.Runtime).Unwrap(); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/interface/generic/GenericInterface.T.cs b/ZSharp.Importer.ILLoader/objects/oop/interface/generic/GenericInterface.T.cs new file mode 100644 index 00000000..ebf3403a --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/interface/generic/GenericInterface.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class GenericInterface + { + + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/interface/generic/GenericInterface.cs b/ZSharp.Importer.ILLoader/objects/oop/interface/generic/GenericInterface.cs new file mode 100644 index 00000000..d531a16e --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/interface/generic/GenericInterface.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class GenericInterface + : CompilerObject + { + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/bound/BoundMethod.Call.cs b/ZSharp.Importer.ILLoader/objects/oop/method/bound/BoundMethod.Call.cs new file mode 100644 index 00000000..45f7d4f1 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/bound/BoundMethod.Call.cs @@ -0,0 +1,19 @@ +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class BoundMethod + : ICTCallable + { + IResult ICTCallable.Call(Compiler.Compiler compiler, Argument[] arguments) + { + if (Object is not null) + arguments = [ + new(Object), + .. arguments + ]; + + return compiler.CG.Call(Method, arguments); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/bound/BoundMethod.T.cs b/ZSharp.Importer.ILLoader/objects/oop/method/bound/BoundMethod.T.cs new file mode 100644 index 00000000..3faaa4dc --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/bound/BoundMethod.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class BoundMethod + { + + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/bound/BoundMethod.cs b/ZSharp.Importer.ILLoader/objects/oop/method/bound/BoundMethod.cs new file mode 100644 index 00000000..25b27ebe --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/bound/BoundMethod.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class BoundMethod + : CompilerObject + { + public required CompilerObject Method { get; set; } + + public required CompilerObject? Object { get; set; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.Bind.cs b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.Bind.cs new file mode 100644 index 00000000..33333325 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.Bind.cs @@ -0,0 +1,22 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Method + : IBindable + { + IResult IBindable.Bind(Compiler.Compiler compiler, CompilerObject target) + { + if (IL.IsStatic) return Result.Ok(this); + + if (!compiler.TS.IsTyped(target, out var targetType)) + return Result.Error( + $"Cannot bind method {IL.Name} to untyped object {target}" + ); + + return Result.Ok(new BoundMethod() + { + Method = this, + Object = target + }); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.Call.cs b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.Call.cs new file mode 100644 index 00000000..d1e3fb50 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.Call.cs @@ -0,0 +1,38 @@ + +using ZSharp.Compiler; +using ZSharp.Compiler.Features.Callable; + +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Method + : ICTCallable + { + IResult ICTCallable.Call(Compiler.Compiler compiler, Argument[] arguments) + { + if ( + BoundSignature.Create(compiler, signature, new ArgumentStream(arguments)) + .When(out var boundSignature) + .Error(out var error) + ) return Result.Error(error); + + IRCode result = new(); + + foreach (var boundParameter in boundSignature!.Parameters) + { + if ( + compiler.IR.CompileCode(boundParameter.ArgumentObject, null) + .When(out var argumentCode) + .Error(out error) + ) + return Result.Error(error); + + result.Instructions.AddRange(argumentCode!.Instructions); + } + + result.Instructions.Add(new IR.VM.Call(GetIR())); + result.Types.Add(GetIR().ReturnType); + + return Result.Ok(RawIRCode.From(result.Instructions, ReturnType)); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.IL.cs b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.IL.cs new file mode 100644 index 00000000..82bb99a3 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.IL.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Method + { + public IL.MethodInfo IL { get; } + + private ILLoader Loader { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.IR.cs b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.IR.cs new file mode 100644 index 00000000..63b6ceec --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.IR.cs @@ -0,0 +1,21 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Method + { + private IR.Method? IR { get; set; } + + private IR.Method GetIR() + { + if (IR is null) + { + var returnTypeCO = Loader.LoadType(IL.ReturnType); + if (Loader.IR.CompileType(returnTypeCO).When(out var returnTypeIR).Error(out var error)) + throw new InvalidOperationException($"Failed to load return type for method {IL.Name}: {error}"); + IR = new(returnTypeIR!); + Loader.RequireRuntime().AddFunction(IR.UnderlyingFunction, IL); + } + + return IR; + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.Signature.cs b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.Signature.cs new file mode 100644 index 00000000..fb05d4bc --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.Signature.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class Method + { + private readonly Signature signature = new(); + + public CompilerObject Signature => signature; + + public CompilerObject ReturnType { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.cs b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.cs new file mode 100644 index 00000000..0c03afbd --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/concrete/Method.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Method + : CompilerObject + { + public Method(IL.MethodInfo il, ILLoader loader) + { + IL = il; + Loader = loader; + + ReturnType = loader.LoadType(IL.ReturnType); + + if (!IL.IsStatic) + signature.parameters.Add(new ThisParameter(IL, loader)); + + foreach (var parameter in IL.GetParameters()) + signature.parameters.Add(new Parameter(parameter, loader)); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/generic/GenericMethod.T.cs b/ZSharp.Importer.ILLoader/objects/oop/method/generic/GenericMethod.T.cs new file mode 100644 index 00000000..b009d8ff --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/generic/GenericMethod.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class GenericMethod + { + + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/method/generic/GenericMethod.cs b/ZSharp.Importer.ILLoader/objects/oop/method/generic/GenericMethod.cs new file mode 100644 index 00000000..ce413669 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/method/generic/GenericMethod.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class GenericMethod + : CompilerObject + { + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/property/Property.cs b/ZSharp.Importer.ILLoader/objects/oop/property/Property.cs new file mode 100644 index 00000000..9f61bbb4 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/property/Property.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Property + : CompilerObject + { + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/struct/concrete/Struct.cs b/ZSharp.Importer.ILLoader/objects/oop/struct/concrete/Struct.cs new file mode 100644 index 00000000..e0f1de9e --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/struct/concrete/Struct.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class Struct + : CompilerObject + { + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/struct/generic/GenericStruct.T.cs b/ZSharp.Importer.ILLoader/objects/oop/struct/generic/GenericStruct.T.cs new file mode 100644 index 00000000..8fee7d18 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/struct/generic/GenericStruct.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class GenericStruct + { + + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/struct/generic/GenericStruct.cs b/ZSharp.Importer.ILLoader/objects/oop/struct/generic/GenericStruct.cs new file mode 100644 index 00000000..299ba4e2 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/struct/generic/GenericStruct.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed partial class GenericStruct + : CompilerObject + { + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/this parameter/ThisParameter.IL.cs b/ZSharp.Importer.ILLoader/objects/oop/this parameter/ThisParameter.IL.cs new file mode 100644 index 00000000..a27872f5 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/this parameter/ThisParameter.IL.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader.Objects +{ + partial class ThisParameter + { + public IL.MethodBase IL { get; } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/oop/this parameter/ThisParameter.cs b/ZSharp.Importer.ILLoader/objects/oop/this parameter/ThisParameter.cs new file mode 100644 index 00000000..4e800dff --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/oop/this parameter/ThisParameter.cs @@ -0,0 +1,30 @@ +using ZSharp.Compiler.Features.Callable; + +namespace ZSharp.Importer.ILLoader.Objects +{ + internal sealed partial class ThisParameter + : CompilerObject + , IParameter + { + public string Name => "this"; + + public CompilerObject Type { get; } + + public ThisParameter(IL.MethodBase il, ILLoader loader) + { + IL = il; + + Type = loader.LoadType(IL.DeclaringType ?? throw new()); + } + + IResult IParameter.Match(Compiler.Compiler compiler, IArgumentStream arguments) + { + if (!arguments.PopArgument(Name, out var argument) && + !arguments.PopArgument(out argument) + ) + return Result.Error($"No argument provided for parameter '{Name}'."); + + return compiler.CG.ImplicitCast(argument, Type); + } + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/array/ArrayType.cs b/ZSharp.Importer.ILLoader/objects/types/array/ArrayType.cs new file mode 100644 index 00000000..4f617c99 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/array/ArrayType.cs @@ -0,0 +1,10 @@ +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class ArrayType(TypeDefinition type) + : CompilerObject + { + private readonly TypeDefinition type = type; + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/boolean/BooleanType.cs b/ZSharp.Importer.ILLoader/objects/types/boolean/BooleanType.cs new file mode 100644 index 00000000..956b6f71 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/boolean/BooleanType.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class BooleanType(TypeReference type) + : CompilerObject + , ICompileIRType + { + private readonly TypeReference type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/char/CharType.cs b/ZSharp.Importer.ILLoader/objects/types/char/CharType.cs new file mode 100644 index 00000000..19ab38b9 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/char/CharType.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class CharType(TypeReference type) + : CompilerObject + , ICompileIRType + { + private readonly TypeReference type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/float/Float128Type.cs b/ZSharp.Importer.ILLoader/objects/types/float/Float128Type.cs new file mode 100644 index 00000000..3374276a --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/float/Float128Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class Float128Type(TypeReference type) + : CompilerObject + , ICompileIRType + { + private readonly TypeReference type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/float/Float16Type.cs b/ZSharp.Importer.ILLoader/objects/types/float/Float16Type.cs new file mode 100644 index 00000000..5df97797 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/float/Float16Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class Float16Type(TypeReference type) + : CompilerObject + , ICompileIRType + { + private readonly TypeReference type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/float/Float32Type.cs b/ZSharp.Importer.ILLoader/objects/types/float/Float32Type.cs new file mode 100644 index 00000000..3001cbc6 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/float/Float32Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class Float32Type(TypeReference type) + : CompilerObject + , ICompileIRType + { + private readonly TypeReference type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/float/Float64Type.cs b/ZSharp.Importer.ILLoader/objects/types/float/Float64Type.cs new file mode 100644 index 00000000..774d86a1 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/float/Float64Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class Float64Type(TypeReference type) + : CompilerObject + , ICompileIRType + { + private readonly TypeReference type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/SInt16Type.cs b/ZSharp.Importer.ILLoader/objects/types/int/SInt16Type.cs new file mode 100644 index 00000000..6354465c --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/SInt16Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class SInt16Type(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/SInt32Type.cs b/ZSharp.Importer.ILLoader/objects/types/int/SInt32Type.cs new file mode 100644 index 00000000..21a7eca4 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/SInt32Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class SInt32Type(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/SInt64Type.cs b/ZSharp.Importer.ILLoader/objects/types/int/SInt64Type.cs new file mode 100644 index 00000000..45422627 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/SInt64Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class SInt64Type(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/SInt8Type.cs b/ZSharp.Importer.ILLoader/objects/types/int/SInt8Type.cs new file mode 100644 index 00000000..e7754e24 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/SInt8Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class SInt8Type(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/SIntNativeType.cs b/ZSharp.Importer.ILLoader/objects/types/int/SIntNativeType.cs new file mode 100644 index 00000000..d24c5304 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/SIntNativeType.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class SIntNativeType(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/UInt16Type.cs b/ZSharp.Importer.ILLoader/objects/types/int/UInt16Type.cs new file mode 100644 index 00000000..13db4dbd --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/UInt16Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class UInt16Type(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/UInt32Type.cs b/ZSharp.Importer.ILLoader/objects/types/int/UInt32Type.cs new file mode 100644 index 00000000..cd2ee659 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/UInt32Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class UInt32Type(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/UInt64Type.cs b/ZSharp.Importer.ILLoader/objects/types/int/UInt64Type.cs new file mode 100644 index 00000000..c2df94b4 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/UInt64Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class UInt64Type(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/UInt8Type.cs b/ZSharp.Importer.ILLoader/objects/types/int/UInt8Type.cs new file mode 100644 index 00000000..f7b4aeab --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/UInt8Type.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class UInt8Type(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/int/UIntNativeType.cs b/ZSharp.Importer.ILLoader/objects/types/int/UIntNativeType.cs new file mode 100644 index 00000000..5cc9f29c --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/int/UIntNativeType.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class UIntNativeType(IType type) + : CompilerObject + , ICompileIRType + { + private readonly IType type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/object/ObjectType.cs b/ZSharp.Importer.ILLoader/objects/types/object/ObjectType.cs new file mode 100644 index 00000000..ce8b5a0d --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/object/ObjectType.cs @@ -0,0 +1,19 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class ObjectType(TypeReference type) + : CompilerObject + , ICompileIRType + , IILType + { + private readonly TypeReference type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + + Type IILType.GetILType() + => typeof(object); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/pointer/PointerType.cs b/ZSharp.Importer.ILLoader/objects/types/pointer/PointerType.cs new file mode 100644 index 00000000..0f645f48 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/pointer/PointerType.cs @@ -0,0 +1,10 @@ +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class PointerType(TypeDefinition type) + : CompilerObject + { + private readonly TypeDefinition type = type; + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/reference/ReferenceType.cs b/ZSharp.Importer.ILLoader/objects/types/reference/ReferenceType.cs new file mode 100644 index 00000000..5080fafb --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/reference/ReferenceType.cs @@ -0,0 +1,10 @@ +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class ReferenceType(TypeDefinition type) + : CompilerObject + { + private readonly TypeDefinition type = type; + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/string/StringType.cs b/ZSharp.Importer.ILLoader/objects/types/string/StringType.cs new file mode 100644 index 00000000..b6058322 --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/string/StringType.cs @@ -0,0 +1,20 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + internal sealed class StringType(TypeReference type) + : CompilerObject + , ICompileIRType + , IILType + , IReferenceType + { + private readonly TypeReference type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + + Type IILType.GetILType() + => typeof(string); + } +} diff --git a/ZSharp.Importer.ILLoader/objects/types/void/VoidType.cs b/ZSharp.Importer.ILLoader/objects/types/void/VoidType.cs new file mode 100644 index 00000000..647f13ab --- /dev/null +++ b/ZSharp.Importer.ILLoader/objects/types/void/VoidType.cs @@ -0,0 +1,15 @@ +using ZSharp.Compiler; +using ZSharp.IR; + +namespace ZSharp.Importer.ILLoader.Objects +{ + public sealed class VoidType(TypeReference type) + : CompilerObject + , ICompileIRType + { + private readonly TypeReference type = type; + + IResult ICompileIRType.CompileIRType(Compiler.Compiler compiler) + => Result.Ok(type); + } +} diff --git a/ZSharp.Importer.ILLoader/semantics/IReferenceType.cs b/ZSharp.Importer.ILLoader/semantics/IReferenceType.cs new file mode 100644 index 00000000..297e1369 --- /dev/null +++ b/ZSharp.Importer.ILLoader/semantics/IReferenceType.cs @@ -0,0 +1,28 @@ +using ZSharp.Compiler; + +namespace ZSharp.Importer.ILLoader +{ + internal interface IReferenceType + : IILType + , IRTImplicitCastTo + { + IResult IRTImplicitCastTo.ImplicitCast(Compiler.Compiler compiler, CompilerObject @object, CompilerObject type) + { + var thisIL = GetILType(); + + if (!type.Is(out var ilTypeProvider)) + return Result.Error( + $"Cannot implicitly cast type {thisIL.Name} to non-IL type {type}" + ); + + var thatIL = ilTypeProvider.GetILType(); + + if (!thisIL.IsAssignableTo(thatIL)) + return Result.Error( + $"Cannot implicitly cast type {thisIL.Name} to incompatible type {thatIL.Name}" + ); + + return Result.Ok(@object); + } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.Array.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.Array.cs new file mode 100644 index 00000000..9d3592a1 --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.Array.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject Array { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.Boolean.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.Boolean.cs new file mode 100644 index 00000000..dbe478e8 --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.Boolean.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject Boolean { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.Char.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.Char.cs new file mode 100644 index 00000000..33ac997e --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.Char.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject Char { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.Float.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.Float.cs new file mode 100644 index 00000000..e0d2e4d4 --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.Float.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject Float16 { get; init; } + + public required CompilerObject Float32 { get; init; } + + public required CompilerObject Float64 { get; init; } + + public required CompilerObject Float128 { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.Object.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.Object.cs new file mode 100644 index 00000000..043f5fdf --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.Object.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject Object { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.Pointer.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.Pointer.cs new file mode 100644 index 00000000..e82250fa --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.Pointer.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject Pointer { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.Reference.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.Reference.cs new file mode 100644 index 00000000..204d5f44 --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.Reference.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject Reference { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.SInt.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.SInt.cs new file mode 100644 index 00000000..c293befa --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.SInt.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject SInt8 { get; init; } + + public required CompilerObject SInt16 { get; init; } + + public required CompilerObject SInt32 { get; init; } + + public required CompilerObject SInt64 { get; init; } + + public required CompilerObject SIntNative { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.String.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.String.cs new file mode 100644 index 00000000..8ed543c0 --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.String.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject String { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.UInt.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.UInt.cs new file mode 100644 index 00000000..12a1b14e --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.UInt.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject UInt8 { get; init; } + + public required CompilerObject UInt16 { get; init; } + + public required CompilerObject UInt32 { get; init; } + + public required CompilerObject UInt64 { get; init; } + + public required CompilerObject UIntNative { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.Void.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.Void.cs new file mode 100644 index 00000000..1437fd39 --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.Void.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + partial class TypeSystem + { + public required CompilerObject Void { get; init; } + } +} diff --git a/ZSharp.Importer.ILLoader/type system/TypeSystem.cs b/ZSharp.Importer.ILLoader/type system/TypeSystem.cs new file mode 100644 index 00000000..33d36bfb --- /dev/null +++ b/ZSharp.Importer.ILLoader/type system/TypeSystem.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.ILLoader +{ + public sealed partial class TypeSystem() + { + + } +} diff --git a/ZSharp.Importer.RT/GlobalUsings.cs b/ZSharp.Importer.RT/GlobalUsings.cs new file mode 100644 index 00000000..f45b91d8 --- /dev/null +++ b/ZSharp.Importer.RT/GlobalUsings.cs @@ -0,0 +1,7 @@ +global using RTObject = object; + +global using CompilerObject = ZSharp.Compiler.CompilerObject; +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; + +global using TargetPlatform = object; diff --git a/ZSharp.Importer.RT/ZSharp.Importer.RT.csproj b/ZSharp.Importer.RT/ZSharp.Importer.RT.csproj new file mode 100644 index 00000000..1295c92b --- /dev/null +++ b/ZSharp.Importer.RT/ZSharp.Importer.RT.csproj @@ -0,0 +1,16 @@ + + + + net9.0 + enable + enable + + + + + + + + + + diff --git a/ZSharp.Importer.RT/objects/string/StringLiteral.IR.cs b/ZSharp.Importer.RT/objects/string/StringLiteral.IR.cs new file mode 100644 index 00000000..1f82e907 --- /dev/null +++ b/ZSharp.Importer.RT/objects/string/StringLiteral.IR.cs @@ -0,0 +1,21 @@ +using ZSharp.Compiler; + +namespace ZSharp.Importer.RT.Objects +{ + partial class StringLiteral + : ICompileIRCode + { + IResult ICompileIRCode.CompileIRCode(Compiler.Compiler compiler, TargetPlatform? target) + => Result.Ok(new([ + new IR.VM.PutString(value) + ]) + { + Types = [ + compiler.IR.CompileType(type) + .Else(e => new ErrorMessage($"WTF string can't compile to IR type?? {e}")) + .Unwrap() + ], + MaxStackSize = 1 + }); + } +} diff --git a/ZSharp.Importer.RT/objects/string/StringLiteral.Type.cs b/ZSharp.Importer.RT/objects/string/StringLiteral.Type.cs new file mode 100644 index 00000000..0f17e734 --- /dev/null +++ b/ZSharp.Importer.RT/objects/string/StringLiteral.Type.cs @@ -0,0 +1,10 @@ +using ZSharp.Compiler; + +namespace ZSharp.Importer.RT.Objects +{ + partial class StringLiteral + : ITyped + { + CompilerObject ITyped.Type => type; + } +} diff --git a/ZSharp.Importer.RT/objects/string/StringLiteral.cs b/ZSharp.Importer.RT/objects/string/StringLiteral.cs new file mode 100644 index 00000000..b5ff0c6e --- /dev/null +++ b/ZSharp.Importer.RT/objects/string/StringLiteral.cs @@ -0,0 +1,11 @@ +using Value = string; + +namespace ZSharp.Importer.RT.Objects +{ + internal sealed partial class StringLiteral(Value value, CompilerObject type) + : CompilerObject + { + private readonly Value value = value; + private readonly CompilerObject type = type; + } +} diff --git a/ZSharp.Importer.RT/rt loader/Loader.ILLoader.cs b/ZSharp.Importer.RT/rt loader/Loader.ILLoader.cs new file mode 100644 index 00000000..28fa5d75 --- /dev/null +++ b/ZSharp.Importer.RT/rt loader/Loader.ILLoader.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.RT +{ + partial class Loader + { + public ILLoader.ILLoader ILLoader { get; } + } +} diff --git a/ZSharp.Importer.RT/rt loader/Loader.Load.Primitives.cs b/ZSharp.Importer.RT/rt loader/Loader.Load.Primitives.cs new file mode 100644 index 00000000..2e455a30 --- /dev/null +++ b/ZSharp.Importer.RT/rt loader/Loader.Load.Primitives.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Importer.RT +{ + partial class Loader + { + private Objects.StringLiteral Load(string value) + => new(value, ILLoader.LoadType(typeof(string))); + } +} diff --git a/ZSharp.Importer.RT/rt loader/Loader.Load.cs b/ZSharp.Importer.RT/rt loader/Loader.Load.cs new file mode 100644 index 00000000..ee6542db --- /dev/null +++ b/ZSharp.Importer.RT/rt loader/Loader.Load.cs @@ -0,0 +1,21 @@ +namespace ZSharp.Importer.RT +{ + public delegate IResult LoadObject(RTObject? @object); + + partial class Loader + { + public LoadObject LoadObject; + + public IResult Load(RTObject? @object) + => LoadObject(@object); + + private IResult DefaultLoader(RTObject? @object) + => @object switch + { + CompilerObject co => Result.Ok(co), + string value => Result.Ok(Load(value)), + null => Result.Error("Cannot directly load null object because it is untyped."), + _ => Result.Error($"Cannot load {@object.GetType().Name} object: {@object}."), + }; + } +} diff --git a/ZSharp.Importer.RT/rt loader/Loader.TypeSystem.cs b/ZSharp.Importer.RT/rt loader/Loader.TypeSystem.cs new file mode 100644 index 00000000..c2e2a9d2 --- /dev/null +++ b/ZSharp.Importer.RT/rt loader/Loader.TypeSystem.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Importer.RT +{ + partial class Loader + { + public required Platform.Runtime.TypeSystem TypeSystem { get; init; } + } +} diff --git a/ZSharp.Importer.RT/rt loader/Loader.cs b/ZSharp.Importer.RT/rt loader/Loader.cs new file mode 100644 index 00000000..5d847410 --- /dev/null +++ b/ZSharp.Importer.RT/rt loader/Loader.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Importer.RT +{ + public sealed partial class Loader + { + public Loader(ILLoader.ILLoader ilLoader) + { + ILLoader = ilLoader; + LoadObject = DefaultLoader; + } + } +} diff --git a/ZSharp.Interpreter/GlobalUsings.cs b/ZSharp.Interpreter/GlobalUsings.cs new file mode 100644 index 00000000..3511d075 --- /dev/null +++ b/ZSharp.Interpreter/GlobalUsings.cs @@ -0,0 +1 @@ +global using CompilerObject = ZSharp.Compiler.CompilerObject; diff --git a/ZSharp.Interpreter/IHostLoader.cs b/ZSharp.Interpreter/IHostLoader.cs deleted file mode 100644 index 174a2af3..00000000 --- a/ZSharp.Interpreter/IHostLoader.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Interpreter -{ - public interface IHostLoader - { - public IR.Module Import(System.Reflection.Module module); - } -} diff --git a/ZSharp.Interpreter/Interpreter.cs b/ZSharp.Interpreter/Interpreter.cs deleted file mode 100644 index fef22b37..00000000 --- a/ZSharp.Interpreter/Interpreter.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace ZSharp.Interpreter -{ - public class Interpreter - { - public IHostLoader HostLoader { get; set; } = null!; - - public IRuntime Runtime { get; set; } = null!; - - public IR.RuntimeModule RuntimeModule { get; } - - public Compiler.Compiler Compiler { get; init; } - - public Compiler.IRLoader.IRLoader CompilerIRLoader { get; } - - public ZSSourceCompiler.ZSSourceCompiler SourceCompiler { get; init; } - - public Parser.ZSharpParser Parser { get; init; } - - public Interpreter(IR.RuntimeModule? runtimeModule = null) - { - RuntimeModule = runtimeModule ?? IR.RuntimeModule.Standard; - - Compiler = new(RuntimeModule); - - CompilerIRLoader = new(Compiler); - SourceCompiler = new(Compiler); - - Parser = new(); - - Compiler.Evaluators.Add(new ZSSourceEvaluator(SourceCompiler)); - } - - public ZSSourceCompiler.Document CompileFile(string path) - { - AST.Document document; - - using (var reader = new StreamReader(path)) - document = Parser.Parse(new(Tokenizer.Tokenizer.Tokenize(new(reader)))); - - return CompileDocument(document, path); - } - - public ZSSourceCompiler.Document CompileDocument(AST.Document document, string path) - { - return SourceCompiler.CreateDocumentCompiler(document, path).Compile(); - } - } -} diff --git a/ZSharp.Interpreter/ZSSourceEvaluator.cs b/ZSharp.Interpreter/ZSSourceEvaluator.cs deleted file mode 100644 index 8f243562..00000000 --- a/ZSharp.Interpreter/ZSSourceEvaluator.cs +++ /dev/null @@ -1,21 +0,0 @@ -using ZSharp.Objects; - -namespace ZSharp.Interpreter -{ - internal sealed class ZSSourceEvaluator(ZSSourceCompiler.ZSSourceCompiler sourceCompiler) : Compiler.Evaluator - { - private readonly ZSSourceCompiler.ZSSourceCompiler sourceCompiler = sourceCompiler; - - public override CompilerObject Evaluate(CompilerObject @object) - { - if (@object is not ZSSourceCompiler.NodeObject nodeObject) return @object; - - if (nodeObject.Node is AST.Expression expression) - return sourceCompiler.CompileNode(expression); - if (nodeObject.Node is AST.Statement statement) - return sourceCompiler.CompileNode(statement); - - return @object; - } - } -} diff --git a/ZSharp.Interpreter/ZSharp.Interpreter.csproj b/ZSharp.Interpreter/ZSharp.Interpreter.csproj index ad7155bd..20c44119 100644 --- a/ZSharp.Interpreter/ZSharp.Interpreter.csproj +++ b/ZSharp.Interpreter/ZSharp.Interpreter.csproj @@ -1,20 +1,19 @@  - net8.0 + net9.0 enable enable - - + + + + - - - - + diff --git a/ZSharp.Interpreter/interpreter/Interpreter.Evaluate.cs b/ZSharp.Interpreter/interpreter/Interpreter.Evaluate.cs new file mode 100644 index 00000000..09872504 --- /dev/null +++ b/ZSharp.Interpreter/interpreter/Interpreter.Evaluate.cs @@ -0,0 +1,37 @@ +using ZSharp.Compiler; + +namespace ZSharp.Interpreter +{ + partial class Interpreter + { + public IResult Evaluate( + CompilerObject @object, + Platform.Runtime.IEvaluationContext? evaluationContext = null + ) + { + if ( + Compiler.IR.CompileCode(@object, Runtime) + .When(out var irCode) + .Error(out var error) + ) + return Result.Ok(@object); + + var type = irCode!.IsVoid ? RuntimeModule.TypeSystem.Void : irCode.RequireValueType(); + + var result = Runtime.Evaluate(irCode.Instructions, type, evaluationContext); + + if (irCode.IsVoid) + return Result + .Ok(new Objects.RawIRCode(new())); + + if (result is null) + return Result + .Ok(@object); + // TODO: should actually be an error! + //return Result + // .Error("Non-void expression evaluated to nothing"); + + return Result.Ok(result); + } + } +} diff --git a/ZSharp.Interpreter/interpreter/Interpreter.IL.cs b/ZSharp.Interpreter/interpreter/Interpreter.IL.cs new file mode 100644 index 00000000..f164a2d7 --- /dev/null +++ b/ZSharp.Interpreter/interpreter/Interpreter.IL.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Interpreter +{ + partial class Interpreter + { + public Importer.ILLoader.ILLoader ILLoader { get; } + + public CompilerObject ImportILModule(System.Reflection.Module module) + => ILLoader.LoadModule(module); + } +} diff --git a/ZSharp.Interpreter/interpreter/Interpreter.Logging.cs b/ZSharp.Interpreter/interpreter/Interpreter.Logging.cs new file mode 100644 index 00000000..c461aa45 --- /dev/null +++ b/ZSharp.Interpreter/interpreter/Interpreter.Logging.cs @@ -0,0 +1,9 @@ +using ZSharp.Logging; + +namespace ZSharp.Interpreter +{ + partial class Interpreter + { + public Logger Log => Compiler.Log; + } +} diff --git a/ZSharp.Interpreter/interpreter/Interpreter.Operators.cs b/ZSharp.Interpreter/interpreter/Interpreter.Operators.cs new file mode 100644 index 00000000..6fc9f7b4 --- /dev/null +++ b/ZSharp.Interpreter/interpreter/Interpreter.Operators.cs @@ -0,0 +1,19 @@ +using CommonZ.Utils; + +namespace ZSharp.Interpreter +{ + partial class Interpreter + { + public OperatorTable Operators { get; private set; } = new(); + + public ContextManager OperatorScope(out OperatorTable scopedTable) + { + scopedTable = Operators.CreateChild(); + + var previous = Operators; + Operators = scopedTable; + + return new ContextManager(() => Operators = previous); + } + } +} diff --git a/ZSharp.Interpreter/interpreter/Interpreter.Runtime.cs b/ZSharp.Interpreter/interpreter/Interpreter.Runtime.cs new file mode 100644 index 00000000..64080e19 --- /dev/null +++ b/ZSharp.Interpreter/interpreter/Interpreter.Runtime.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Interpreter +{ + partial class Interpreter + { + public Platform.Runtime.Runtime Runtime { get; } + + public Importer.RT.Loader RTLoader { get; } + } +} diff --git a/ZSharp.Interpreter/interpreter/Interpreter.T.cs b/ZSharp.Interpreter/interpreter/Interpreter.T.cs new file mode 100644 index 00000000..3389a954 --- /dev/null +++ b/ZSharp.Interpreter/interpreter/Interpreter.T.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Interpreter +{ + partial class Interpreter + { + } +} diff --git a/ZSharp.Interpreter/interpreter/Interpreter.cs b/ZSharp.Interpreter/interpreter/Interpreter.cs new file mode 100644 index 00000000..e4c86548 --- /dev/null +++ b/ZSharp.Interpreter/interpreter/Interpreter.cs @@ -0,0 +1,49 @@ +using System.Runtime.Intrinsics.Arm; +using ZSharp.Compiler; + +namespace ZSharp.Interpreter +{ + public sealed partial class Interpreter + { + public IR.RuntimeModule RuntimeModule { get; } + + public Compiler.Compiler Compiler { get; } + + public Interpreter(IR.RuntimeModule? runtimeModule = null) + { + RuntimeModule = runtimeModule ?? IR.RuntimeModule.Standard; + + Compiler = new(RuntimeModule); + Runtime = new(new() + { + Array = RuntimeModule.TypeSystem.Array, + Boolean = RuntimeModule.TypeSystem.Boolean, + Char = null!, + Float16 = null!, + Float32 = RuntimeModule.TypeSystem.Float32, + Float64 = null!, + Float128 = null!, + Object = RuntimeModule.TypeSystem.Object, + Pointer = RuntimeModule.TypeSystem.Pointer, + Reference = RuntimeModule.TypeSystem.Reference, + SInt8 = null!, + SInt16 = null!, + SInt32 = RuntimeModule.TypeSystem.Int32, + SInt64 = null!, + SIntNative = null!, + String = RuntimeModule.TypeSystem.String, + UInt8 = null!, + UInt16 = null!, + UInt32 = null!, + UInt64 = null!, + UIntNative = null!, + Void = RuntimeModule.TypeSystem.Void + }); + ILLoader = new(Compiler, Runtime); + RTLoader = new(ILLoader) + { + TypeSystem = Runtime.TypeSystem + }; + } + } +} diff --git a/ZSharp.Interpreter/operator table/OperatorTable.cs b/ZSharp.Interpreter/operator table/OperatorTable.cs new file mode 100644 index 00000000..2c86c247 --- /dev/null +++ b/ZSharp.Interpreter/operator table/OperatorTable.cs @@ -0,0 +1,32 @@ +global using Operator = string; + +using CommonZ.Utils; +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Interpreter +{ + public sealed class OperatorTable() + { + private readonly Cache operators = new(); + + internal OperatorTable(OperatorTable? parent = null) + : this() + { + operators = new() + { + Parent = parent?.operators + }; + } + + public void Op(Operator op, CompilerObject obj) + => operators.Cache(op, obj); // TODO: on add + + public CompilerObject? Op(Operator op) + => operators.Cache(op); + + public bool Op(Operator op, [NotNullWhen(true)] out CompilerObject? obj) + => (obj = Op(op)) is not null; + + public OperatorTable CreateChild() => new(this); + } +} diff --git a/ZSharp.Interpreter/rt/IRuntime.cs b/ZSharp.Interpreter/rt/IRuntime.cs deleted file mode 100644 index 20317574..00000000 --- a/ZSharp.Interpreter/rt/IRuntime.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Interpreter -{ - public interface IRuntime - { - public void Import(IR.Module module); - } -} diff --git a/ZSharp.Library.Core.Compiler/GlobalUsings.cs b/ZSharp.Library.Core.Compiler/GlobalUsings.cs new file mode 100644 index 00000000..aaaf8106 --- /dev/null +++ b/ZSharp.Library.Core.Compiler/GlobalUsings.cs @@ -0,0 +1 @@ +global using ZSharp.Importer.ILLoader; diff --git a/ZSharp.Library.Core.Compiler/ModuleAttributes.cs b/ZSharp.Library.Core.Compiler/ModuleAttributes.cs new file mode 100644 index 00000000..ab18bbc6 --- /dev/null +++ b/ZSharp.Library.Core.Compiler/ModuleAttributes.cs @@ -0,0 +1,3 @@ +[module: MapNamespace(OldName = "Core.Compiler", NewName = "")] + +[module: ImportType(typeof(ZSharp.Compiler.CompilerObject), Namespace = "")] diff --git a/ZSharp.Library.Core.Compiler/ZSharp.Library.Core.Compiler.csproj b/ZSharp.Library.Core.Compiler/ZSharp.Library.Core.Compiler.csproj new file mode 100644 index 00000000..4a0a6673 --- /dev/null +++ b/ZSharp.Library.Core.Compiler/ZSharp.Library.Core.Compiler.csproj @@ -0,0 +1,15 @@ + + + + net9.0 + enable + enable + + + + + + + + + diff --git a/ZSharp.Library.Core.Compiler/module scope/ModuleScope.cs b/ZSharp.Library.Core.Compiler/module scope/ModuleScope.cs new file mode 100644 index 00000000..031cdbba --- /dev/null +++ b/ZSharp.Library.Core.Compiler/module scope/ModuleScope.cs @@ -0,0 +1,7 @@ +namespace Core.Compiler +{ + [ModuleScope] + public static partial class ModuleScope + { + } +} diff --git a/ZSharp.Library.Standard.FileSystem/GlobalUsings.cs b/ZSharp.Library.Standard.FileSystem/GlobalUsings.cs new file mode 100644 index 00000000..aaaf8106 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/GlobalUsings.cs @@ -0,0 +1 @@ +global using ZSharp.Importer.ILLoader; diff --git a/ZSharp.Library.Standard.FileSystem/ModuleAttributes.cs b/ZSharp.Library.Standard.FileSystem/ModuleAttributes.cs new file mode 100644 index 00000000..69830613 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/ModuleAttributes.cs @@ -0,0 +1 @@ +[module: MapNamespace(OldName = "Standard.FileSystem", NewName = "")] diff --git a/ZSharp.Library.Standard.FileSystem/ZSharp.Library.Standard.FileSystem.csproj b/ZSharp.Library.Standard.FileSystem/ZSharp.Library.Standard.FileSystem.csproj new file mode 100644 index 00000000..cb3df907 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/ZSharp.Library.Standard.FileSystem.csproj @@ -0,0 +1,14 @@ + + + + net9.0 + enable + enable + Standard.FileSystem + + + + + + + diff --git a/ZSharp.Library.Standard.FileSystem/items/directory/Directory.From.cs b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.From.cs new file mode 100644 index 00000000..ed3c7fdc --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.From.cs @@ -0,0 +1,13 @@ +namespace Standard.FileSystem +{ + partial class Directory + { + public new static Directory? From(RawPath raw) + { + ArgumentNullException.ThrowIfNull(raw, nameof(raw)); + if (System.IO.Directory.Exists(raw)) + return new(raw); + return null; + } + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/directory/Directory.Items.cs b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.Items.cs new file mode 100644 index 00000000..442305b5 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.Items.cs @@ -0,0 +1,16 @@ +using System.Collections; + +namespace Standard.FileSystem +{ + partial class Directory + : IEnumerable + { + IEnumerator IEnumerable.GetEnumerator() + => System.IO.Directory.EnumerateFileSystemEntries(raw) + .Select(Item.From) + .GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() + => (this as IEnumerable).GetEnumerator(); + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/directory/Directory.Name.cs b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.Name.cs new file mode 100644 index 00000000..b86cc23c --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.Name.cs @@ -0,0 +1,11 @@ +namespace Standard.FileSystem +{ + partial class Directory + { + public string Name + { + get => System.IO.Path.GetFileName(raw); + set => System.IO.Directory.Move(raw, (Parent / value).raw); + } + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/directory/Directory.Operators.cs b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.Operators.cs new file mode 100644 index 00000000..bc6b5139 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.Operators.cs @@ -0,0 +1,11 @@ +namespace Standard.FileSystem +{ + partial class Directory + { + public static Item operator /(Directory directory, RawPath path) + => ModuleScope.Join(directory, path); + + public static Item operator/(Directory directory, RelativePath path) + => ModuleScope.Join(directory, path.raw); + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/directory/Directory.cs b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.cs new file mode 100644 index 00000000..cddb47b7 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/directory/Directory.cs @@ -0,0 +1,27 @@ +namespace Standard.FileSystem +{ + public sealed partial class Directory + : Item + { + private Directory(RawPath raw) : base(raw) + { + + } + + [Alias("createDirectory")] + public Directory CreateDirectory(string name, [NamedParameter] bool existsOk = false) + { + var path = (this / name).raw; + + if (!System.IO.Directory.Exists(path)) + System.IO.Directory.CreateDirectory(path); + else if (!existsOk) throw new InvalidOperationException(); + + return new(path); + } + + [Alias("cwd")] + public static Directory CurrentWorkingDirectory() + => new(System.IO.Directory.GetCurrentDirectory()); + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/file/File.From.cs b/ZSharp.Library.Standard.FileSystem/items/file/File.From.cs new file mode 100644 index 00000000..aa38e17b --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/file/File.From.cs @@ -0,0 +1,13 @@ +namespace Standard.FileSystem +{ + partial class File + { + public new static File? From(RawPath raw) + { + ArgumentNullException.ThrowIfNull(raw, nameof(raw)); + if (System.IO.File.Exists(raw)) + return new(raw); + return null; + } + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/file/File.Name.cs b/ZSharp.Library.Standard.FileSystem/items/file/File.Name.cs new file mode 100644 index 00000000..7af9f445 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/file/File.Name.cs @@ -0,0 +1,23 @@ +namespace Standard.FileSystem +{ + partial class File + { + public string Extension + { + get => System.IO.Path.GetExtension(raw); + set => System.IO.File.Move(raw, (Parent / $"{Stem}{value}").raw); + } + + public string Name + { + get => System.IO.Path.GetFileName(raw); + set => System.IO.File.Move(raw, (Parent / value).raw); + } + + public string Stem + { + get => System.IO.Path.GetFileNameWithoutExtension(raw); + set => System.IO.File.Move(raw, (Parent / $"{value}{Extension}").raw); + } + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/file/File.cs b/ZSharp.Library.Standard.FileSystem/items/file/File.cs new file mode 100644 index 00000000..1375f4e7 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/file/File.cs @@ -0,0 +1,15 @@ +namespace Standard.FileSystem +{ + public sealed partial class File + : Item + { + private File(RawPath raw) : base(raw) + { + + } + + [Alias("getContent")] + public string GetContent() + => System.IO.File.ReadAllText(raw); + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/item/Item.Parent.cs b/ZSharp.Library.Standard.FileSystem/items/item/Item.Parent.cs new file mode 100644 index 00000000..075cb9dc --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/item/Item.Parent.cs @@ -0,0 +1,17 @@ +namespace Standard.FileSystem +{ + partial class Item + { + private Directory? parent; + + public Directory Parent + { + get + { + if (parent is not null) return parent; + + return parent = Directory.From(System.IO.Directory.GetParent(raw)!.FullName) ?? throw new(); + } + } + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/item/Item.cs b/ZSharp.Library.Standard.FileSystem/items/item/Item.cs new file mode 100644 index 00000000..dc8a53f5 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/item/Item.cs @@ -0,0 +1,29 @@ +namespace Standard.FileSystem +{ + public abstract partial class Item(RawPath raw) + { + protected internal readonly RawPath raw = raw ?? throw new ArgumentNullException(nameof(raw)); + + [Alias("toString")] + public override string ToString() + => $"{GetType().Name}<{raw}>"; + + internal static Item From(RawPath raw) + => Directory.From(raw) as Item + ?? File.From(raw) as Item + ?? Location.From(raw); + + public override int GetHashCode() + => (GetType(), raw).GetHashCode(); + + public override bool Equals(object? obj) + { + if (obj is Item other) + { + return raw == other.raw && GetType() == other.GetType(); + } + + return false; + } + } +} diff --git a/ZSharp.Library.Standard.FileSystem/items/location/Location.cs b/ZSharp.Library.Standard.FileSystem/items/location/Location.cs new file mode 100644 index 00000000..375ce193 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/items/location/Location.cs @@ -0,0 +1,18 @@ + +namespace Standard.FileSystem +{ + public sealed class Location + : Item + { + private Location(RawPath raw) : base(raw) + { + + } + + public new static Location From(RawPath raw) + { + ArgumentNullException.ThrowIfNull(raw, nameof(raw)); + return new(raw); + } + } +} diff --git a/ZSharp.Library.Standard.FileSystem/module scope/ModuleScope.Operators.cs b/ZSharp.Library.Standard.FileSystem/module scope/ModuleScope.Operators.cs new file mode 100644 index 00000000..5aeac8c1 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/module scope/ModuleScope.Operators.cs @@ -0,0 +1,21 @@ +namespace Standard.FileSystem +{ + partial class ModuleScope + { + [Operator("/", Kind = OperatorKind.Infix)] + public static Path Join(Path path, RawPath sub) + => path.JoinWith(sub); + + [Operator("/", Kind = OperatorKind.Infix)] + public static Path Join(Path path, RelativePath sub) + => path.JoinWith(sub.raw); + + [Operator("/", Kind = OperatorKind.Infix)] + public static Item Join(Directory directory, RelativePath path) + => Item.From(System.IO.Path.Combine(directory.raw, path.raw)); + + [Operator("/", Kind = OperatorKind.Infix)] + public static Item Join(Directory directory, RawPath path) + => Item.From(System.IO.Path.Combine(directory.raw, path)); + } +} diff --git a/ZSharp.Library.Standard.FileSystem/module scope/ModuleScope.cs b/ZSharp.Library.Standard.FileSystem/module scope/ModuleScope.cs new file mode 100644 index 00000000..7bc2ab71 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/module scope/ModuleScope.cs @@ -0,0 +1,7 @@ +namespace Standard.FileSystem +{ + [ModuleScope] + public static partial class ModuleScope + { + } +} diff --git a/ZSharp.Library.Standard.FileSystem/path/AbsolutePath.cs b/ZSharp.Library.Standard.FileSystem/path/AbsolutePath.cs new file mode 100644 index 00000000..b70af526 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/path/AbsolutePath.cs @@ -0,0 +1,32 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Standard.FileSystem +{ + public sealed class AbsolutePath : Path + { + private AbsolutePath(RawPath raw) : base(raw) + { + + } + + public new bool Is([NotNullWhen(true)] out Directory? result) + => (result = Directory.From(raw)) is not null; + + public new bool Is([NotNullWhen(true)] out File? result) + => (result = File.From(raw)) is not null; + + public override AbsolutePath Resolve() + => this; + + public override Path JoinWith(params RawPath[] raw) + => new AbsolutePath(System.IO.Path.Combine([this.raw, ..raw])); + + public new static AbsolutePath? From(RawPath raw) + { + if (!System.IO.Path.IsPathRooted(raw)) + return null; + + return new(raw); + } + } +} diff --git a/ZSharp.Library.Standard.FileSystem/path/Path.cs b/ZSharp.Library.Standard.FileSystem/path/Path.cs new file mode 100644 index 00000000..cebee0ec --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/path/Path.cs @@ -0,0 +1,26 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Standard.FileSystem +{ + public abstract class Path(RawPath raw) + { + protected internal readonly RawPath raw = raw ?? throw new ArgumentNullException(nameof(raw)); + + public bool Is([NotNullWhen(true)] out Directory? result) + => Resolve().Is(out result); + + public bool Is([NotNullWhen(true)] out File? result) + => Resolve().Is(out result); + + public abstract AbsolutePath Resolve(); + + public abstract Path JoinWith(params RawPath[] raw); + + public override string ToString() + => $"{GetType().Name}<{raw}>"; + + public static Path? From(RawPath raw) + => AbsolutePath.From(raw) as Path + ?? RelativePath.From(raw); + } +} diff --git a/ZSharp.Library.Standard.FileSystem/path/RawPath.cs b/ZSharp.Library.Standard.FileSystem/path/RawPath.cs new file mode 100644 index 00000000..02d2ef11 --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/path/RawPath.cs @@ -0,0 +1 @@ +global using RawPath = string; diff --git a/ZSharp.Library.Standard.FileSystem/path/RelativePath.cs b/ZSharp.Library.Standard.FileSystem/path/RelativePath.cs new file mode 100644 index 00000000..a714e18a --- /dev/null +++ b/ZSharp.Library.Standard.FileSystem/path/RelativePath.cs @@ -0,0 +1,24 @@ +namespace Standard.FileSystem +{ + public sealed class RelativePath : Path + { + private RelativePath(RawPath raw) : base(raw) + { + + } + + public override AbsolutePath Resolve() + => AbsolutePath.From(System.IO.Path.GetFullPath(raw))!; + + public override Path JoinWith(params RawPath[] raw) + => new RelativePath(System.IO.Path.Combine([this.raw, .. raw])); + + public new static RelativePath? From(RawPath raw) + { + if (System.IO.Path.IsPathRooted(raw)) + return null; + + return new(raw); + } + } +} diff --git a/ZSharp.Library.Standard.IO/GlobalUsings.cs b/ZSharp.Library.Standard.IO/GlobalUsings.cs new file mode 100644 index 00000000..aaaf8106 --- /dev/null +++ b/ZSharp.Library.Standard.IO/GlobalUsings.cs @@ -0,0 +1 @@ +global using ZSharp.Importer.ILLoader; diff --git a/ZSharp.Library.Standard.IO/ModuleAttributes.cs b/ZSharp.Library.Standard.IO/ModuleAttributes.cs new file mode 100644 index 00000000..92ac4d01 --- /dev/null +++ b/ZSharp.Library.Standard.IO/ModuleAttributes.cs @@ -0,0 +1 @@ +[module: MapNamespace(OldName = "Standard.IO", NewName = "")] diff --git a/ZSharp.Library.Standard.IO/ZSharp.Library.Standard.IO.csproj b/ZSharp.Library.Standard.IO/ZSharp.Library.Standard.IO.csproj new file mode 100644 index 00000000..b54aaff8 --- /dev/null +++ b/ZSharp.Library.Standard.IO/ZSharp.Library.Standard.IO.csproj @@ -0,0 +1,13 @@ + + + + net9.0 + enable + enable + + + + + + + diff --git a/ZSharp.Library.Standard.IO/module scope/ModuleScope.Functions.cs b/ZSharp.Library.Standard.IO/module scope/ModuleScope.Functions.cs new file mode 100644 index 00000000..9566ea31 --- /dev/null +++ b/ZSharp.Library.Standard.IO/module scope/ModuleScope.Functions.cs @@ -0,0 +1,9 @@ +namespace Standard.IO +{ + partial class ModuleScope + { + [Alias("print")] + public static void Print(object value) + => System.Console.WriteLine(value); + } +} diff --git a/ZSharp.Library.Standard.IO/module scope/ModuleScope.Operators.cs b/ZSharp.Library.Standard.IO/module scope/ModuleScope.Operators.cs new file mode 100644 index 00000000..0bc0900f --- /dev/null +++ b/ZSharp.Library.Standard.IO/module scope/ModuleScope.Operators.cs @@ -0,0 +1,7 @@ +namespace Standard.IO +{ + partial class ModuleScope + { + + } +} diff --git a/ZSharp.Library.Standard.IO/module scope/ModuleScope.cs b/ZSharp.Library.Standard.IO/module scope/ModuleScope.cs new file mode 100644 index 00000000..9e73534e --- /dev/null +++ b/ZSharp.Library.Standard.IO/module scope/ModuleScope.cs @@ -0,0 +1,7 @@ +namespace Standard.IO +{ + [ModuleScope] + public static partial class ModuleScope + { + } +} diff --git a/ZSharp.Library.Standard.Math/GlobalUsings.cs b/ZSharp.Library.Standard.Math/GlobalUsings.cs new file mode 100644 index 00000000..aaaf8106 --- /dev/null +++ b/ZSharp.Library.Standard.Math/GlobalUsings.cs @@ -0,0 +1 @@ +global using ZSharp.Importer.ILLoader; diff --git a/ZSharp.CT.StandardLibrary.Math/Impl_Globals.cs b/ZSharp.Library.Standard.Math/ModuleScope.cs similarity index 53% rename from ZSharp.CT.StandardLibrary.Math/Impl_Globals.cs rename to ZSharp.Library.Standard.Math/ModuleScope.cs index 97159d3b..a4820d6b 100644 --- a/ZSharp.CT.StandardLibrary.Math/Impl_Globals.cs +++ b/ZSharp.Library.Standard.Math/ModuleScope.cs @@ -1,32 +1,30 @@ -using ZSharp.Runtime.NET.IL2IR; - -namespace Standard.Math +namespace Standard.Math { - [ModuleGlobals] - public static class Impl_Globals + [ModuleScope] + public static class ModuleScope { - [Alias(Name = "ceil")] + [Alias("ceil")] public static int Ceil(float x) => (int)System.Math.Ceiling(x); - [Alias(Name = "log2")] + [Alias("log2")] public static float Log2(int x) => (float)System.Math.Log(x, 2); - [Alias(Name = "random")] + [Alias("random")] public static int Random(int min, int max) => new System.Random().Next(min, max); - [Alias(Name = "_<_")] + [Operator("+", Kind = OperatorKind.Infix)] + public static int Add(int a, int b) + => a + b; + + [Operator("<", Kind = OperatorKind.Infix)] public static bool LessThan(int a, int b) => a < b; - [Alias(Name = "_-_")] + [Operator("-", Kind = OperatorKind.Infix)] public static int Subtract(int a, int b) => a - b; - - [Alias(Name = "increment")] - public static int Increment(int x) - => x + 1; } } diff --git a/ZSharp.Library.Standard.Math/ZSharp.Library.Standard.Math.csproj b/ZSharp.Library.Standard.Math/ZSharp.Library.Standard.Math.csproj new file mode 100644 index 00000000..b54aaff8 --- /dev/null +++ b/ZSharp.Library.Standard.Math/ZSharp.Library.Standard.Math.csproj @@ -0,0 +1,13 @@ + + + + net9.0 + enable + enable + + + + + + + diff --git a/ZSharp.Compiler/compiler core/core/logging/Log.cs b/ZSharp.Logging/Log.cs similarity index 92% rename from ZSharp.Compiler/compiler core/core/logging/Log.cs rename to ZSharp.Logging/Log.cs index 6ee0b315..ba3fab6d 100644 --- a/ZSharp.Compiler/compiler core/core/logging/Log.cs +++ b/ZSharp.Logging/Log.cs @@ -1,4 +1,4 @@ -namespace ZSharp.Compiler +namespace ZSharp.Logging { public readonly struct Log { diff --git a/ZSharp.Compiler/compiler core/core/logging/LogLevel.cs b/ZSharp.Logging/LogLevel.cs similarity index 74% rename from ZSharp.Compiler/compiler core/core/logging/LogLevel.cs rename to ZSharp.Logging/LogLevel.cs index 154dda15..51b029f7 100644 --- a/ZSharp.Compiler/compiler core/core/logging/LogLevel.cs +++ b/ZSharp.Logging/LogLevel.cs @@ -1,4 +1,4 @@ -namespace ZSharp.Compiler +namespace ZSharp.Logging { public enum LogLevel { diff --git a/ZSharp.Compiler/compiler core/core/logging/LogOrigin.cs b/ZSharp.Logging/LogOrigin.cs similarity index 64% rename from ZSharp.Compiler/compiler core/core/logging/LogOrigin.cs rename to ZSharp.Logging/LogOrigin.cs index 8b19d568..0a0fb929 100644 --- a/ZSharp.Compiler/compiler core/core/logging/LogOrigin.cs +++ b/ZSharp.Logging/LogOrigin.cs @@ -1,4 +1,4 @@ -namespace ZSharp.Compiler +namespace ZSharp.Logging { public abstract class LogOrigin { diff --git a/ZSharp.Compiler/compiler core/core/logging/Logger.cs b/ZSharp.Logging/Logger.cs similarity index 52% rename from ZSharp.Compiler/compiler core/core/logging/Logger.cs rename to ZSharp.Logging/Logger.cs index 5f6cd779..813f4054 100644 --- a/ZSharp.Compiler/compiler core/core/logging/Logger.cs +++ b/ZSharp.Logging/Logger.cs @@ -1,4 +1,4 @@ -namespace ZSharp.Compiler +namespace ZSharp.Logging { public sealed class Logger { @@ -17,17 +17,5 @@ public void Warning(T message, LogOrigin origin) public void Error(T message, LogOrigin origin) => Log(new() { Message = message, Level = LogLevel.Error, Origin = origin }); - - public void Info(T message, CompilerObject origin) - => Log(new() { Message = message, Level = LogLevel.Info, Origin = Origin(origin) }); - - public void Warning(T message, CompilerObject origin) - => Log(new() { Message = message, Level = LogLevel.Warning, Origin = Origin(origin) }); - - public void Error(T message, CompilerObject origin) - => Log(new() { Message = message, Level = LogLevel.Error, Origin = Origin(origin) }); - - public LogOrigin Origin(CompilerObject @object) - => new ObjectLogOrigin(@object); } } diff --git a/ZSharp.Logging/ZSharp.Logging.csproj b/ZSharp.Logging/ZSharp.Logging.csproj new file mode 100644 index 00000000..125f4c93 --- /dev/null +++ b/ZSharp.Logging/ZSharp.Logging.csproj @@ -0,0 +1,9 @@ + + + + net9.0 + enable + enable + + + diff --git a/ZSharp.Parser/Utils.cs b/ZSharp.Parser/Utils.cs index 5e7d5825..e6ebe66f 100644 --- a/ZSharp.Parser/Utils.cs +++ b/ZSharp.Parser/Utils.cs @@ -10,13 +10,13 @@ public static class Utils public static Parser DefinitionStatement(Parser defParser) where T : Expression => new FunctionalParser( - parser => new ExpressionStatement() { Expression = defParser.Parse(parser) } + parser => new DefinitionStatement() { Definition = defParser.Parse(parser) } ); public static Parser DefinitionStatement(ParserFunction defParser) where T : Expression => new FunctionalParser( - parser => new ExpressionStatement() { Expression = defParser(parser) } + parser => new DefinitionStatement() { Definition = defParser(parser) } ); public static ParserFunction ExpressionStatement(Func fn, bool semicolon = true) diff --git a/ZSharp.Parser/ZSharp.Parser.csproj b/ZSharp.Parser/ZSharp.Parser.csproj index ecc964da..4ee05270 100644 --- a/ZSharp.Parser/ZSharp.Parser.csproj +++ b/ZSharp.Parser/ZSharp.Parser.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable @@ -11,7 +11,7 @@ - + diff --git a/ZSharp.Parser/core/ParseError.cs b/ZSharp.Parser/core/ParseError.cs deleted file mode 100644 index bafe6fed..00000000 --- a/ZSharp.Parser/core/ParseError.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ZSharp.Parser -{ - public class ParseError : Exception - { - } -} diff --git a/ZSharp.Parser/core/errors/ParseError.cs b/ZSharp.Parser/core/errors/ParseError.cs new file mode 100644 index 00000000..e2f1ee6f --- /dev/null +++ b/ZSharp.Parser/core/errors/ParseError.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Parser +{ + public class ParseError(string? message = null) : Exception(message) + { + } +} diff --git a/ZSharp.Parser/core/errors/UnexpectedTokenError.cs b/ZSharp.Parser/core/errors/UnexpectedTokenError.cs new file mode 100644 index 00000000..24233a45 --- /dev/null +++ b/ZSharp.Parser/core/errors/UnexpectedTokenError.cs @@ -0,0 +1,20 @@ +using ZSharp.Text; + +namespace ZSharp.Parser +{ + public sealed class UnexpectedTokenError( + string expectedToken, + Token gotToken + ) : ParseError(FormatMessage(expectedToken, gotToken)) + { + public Token GotToken { get; } = gotToken; + + private static string FormatMessage( + string expectedToken, + Token gotToken + ) + { + return $"Expected token '{expectedToken}' but got '{gotToken}'"; + } + } +} diff --git a/ZSharp.Parser/core/parser/Parser.Tokens.cs b/ZSharp.Parser/core/parser/Parser.Tokens.cs index 57cac751..17dd70fb 100644 --- a/ZSharp.Parser/core/parser/Parser.Tokens.cs +++ b/ZSharp.Parser/core/parser/Parser.Tokens.cs @@ -9,7 +9,7 @@ public sealed partial class Parser public Token Token => HasTokens ? TokenStream.PeekToken() : throw new ParseError(); public Token Eat(TokenType type) - => Is(type) ? TokenStream.Advance() : throw new ParseError(); + => Is(type) ? TokenStream.Advance() : throw new UnexpectedTokenError(type.ToString(), Token); public bool Eat(TokenType type, out Token token) { @@ -19,7 +19,7 @@ public bool Eat(TokenType type, out Token token) } public Token Eat(string value) - => Is(value) ? TokenStream.Advance() : throw new ParseError(); + => Is(value) ? TokenStream.Advance() : throw new UnexpectedTokenError(value, Token); public bool Eat(string value, out Token token) { diff --git a/ZSharp.Parser/lang/LangParser.Keywords.cs b/ZSharp.Parser/lang/LangParser.Keywords.cs index cacdfd2f..a65e2827 100644 --- a/ZSharp.Parser/lang/LangParser.Keywords.cs +++ b/ZSharp.Parser/lang/LangParser.Keywords.cs @@ -9,14 +9,18 @@ public static class Keywords public const string Case = "case"; public const string Class = "class"; public const string Else = "else"; + public const string For = "for"; public const string From = "from"; public const string Function = "fun"; public const string If = "if"; public const string Import = "import"; + public const string In = "in"; + public const string Is = "is"; public const string Let = "let"; public const string Module = "module"; public const string New = "new"; public const string Of = "of"; + public const string Or = "or"; public const string Return = "return"; public const string Var = "var"; public const string When = "when"; diff --git a/ZSharp.Parser/lang/abs/LangParser.Signature.cs b/ZSharp.Parser/lang/abs/LangParser.Signature.cs index 55e76b92..78155c1c 100644 --- a/ZSharp.Parser/lang/abs/LangParser.Signature.cs +++ b/ZSharp.Parser/lang/abs/LangParser.Signature.cs @@ -63,24 +63,30 @@ public static Signature ParseSignature(Parser parser) public static Parameter ParseParameter(Parser parser) { - var name = parser.Eat(TokenType.Identifier).Value; + var name = parser.Eat(TokenType.Identifier); - string? alias = null; + Token? alias = null; if (parser.Is(Keywords.As, eat: true)) - alias = parser.Eat(TokenType.Identifier).Value; + alias = parser.Eat(TokenType.Identifier); Expression? type = null; - if (parser.Is(TokenType.Colon, eat: true)) + if (parser.Is(TokenType.Colon, out var typeSeparator, eat: true)) type = ParseType(parser); Expression? initializer = null; - if (parser.Is(Symbols.Assign, eat: true)) + if (parser.Is(Symbols.Assign, out var valueSeparator, eat: true)) initializer = parser.Parse(); - return new() + return new(new() { - Alias = alias, + AsKeyword = alias, Name = name, + TypeSeparator = typeSeparator, + ValueSeparator = valueSeparator, + }) + { + Alias = alias?.Value, + Name = name.Value, Type = type, Initializer = initializer, }; diff --git a/ZSharp.Parser/lang/expr/LangParser.As.cs b/ZSharp.Parser/lang/expr/LangParser.As.cs new file mode 100644 index 00000000..9874627e --- /dev/null +++ b/ZSharp.Parser/lang/expr/LangParser.As.cs @@ -0,0 +1,20 @@ +using ZSharp.AST; + +namespace ZSharp.Parser +{ + public static partial class LangParser + { + public static CastExpression ParseCastExpression(Parser parser, Expression expression) + { + var asKeyword = parser.Eat(Keywords.As); + + var targetType = parser.Parse(); + + return new() + { + Expression = expression, + TargetType = targetType, + }; + } + } +} diff --git a/ZSharp.Parser/lang/expr/LangParser.Index.cs b/ZSharp.Parser/lang/expr/LangParser.Index.cs new file mode 100644 index 00000000..556a47d2 --- /dev/null +++ b/ZSharp.Parser/lang/expr/LangParser.Index.cs @@ -0,0 +1,33 @@ +using ZSharp.AST; + +namespace ZSharp.Parser +{ + public static partial class LangParser + { + public static CallArgument ParseIndexArgument(Parser parser) + => ParseCallArgument(parser); + + public static IndexExpression ParseIndexExpression(Parser parser, Expression target) + { + var lBracker = parser.Eat(Text.TokenType.LBracket); + + List arguments = []; + + if (!parser.Is(Text.TokenType.RBracket)) + { + arguments.Add(ParseCallArgument(parser)); + + while (parser.Is(Text.TokenType.Comma, eat: true)) + arguments.Add(ParseCallArgument(parser)); + } + + var rBracket = parser.Eat(Text.TokenType.RBracket); + + return new() + { + Arguments = arguments, + Target = target, + }; + } + } +} diff --git a/ZSharp.Parser/lang/expr/LangParser.IsOf.cs b/ZSharp.Parser/lang/expr/LangParser.IsOf.cs new file mode 100644 index 00000000..fd946a32 --- /dev/null +++ b/ZSharp.Parser/lang/expr/LangParser.IsOf.cs @@ -0,0 +1,27 @@ +using ZSharp.AST; + +namespace ZSharp.Parser +{ + public static partial class LangParser + { + public static IsOfExpression ParseIsOfExpression(Parser parser, Expression expression) + { + var isKeyword = parser.Eat(Keywords.Is); + + string? name = null; + if (!parser.Is(Keywords.Of)) + name = parser.Eat(Text.TokenType.Identifier).Value; + + var ofKeyword = parser.Eat(Keywords.Of); + + var ofType = parser.Parse(); + + return new() + { + Expression = expression, + Name = name, + OfType = ofType + }; + } + } +} diff --git a/ZSharp.Parser/lang/expr/LangParser.Literals.cs b/ZSharp.Parser/lang/expr/LangParser.Literals.cs index e549a812..d1d773e0 100644 --- a/ZSharp.Parser/lang/expr/LangParser.Literals.cs +++ b/ZSharp.Parser/lang/expr/LangParser.Literals.cs @@ -1,7 +1,28 @@ -namespace ZSharp.Parser +using ZSharp.AST; + +namespace ZSharp.Parser { public static partial class LangParser { + public static ArrayLiteral ParseArrayLiteral(Parser parser) + { + var lBracket = parser.Eat(Text.TokenType.LBracket); + + List items = []; + while (!parser.Is(Text.TokenType.RBracket)) + { + items.Add(parser.Parse()); + + if (!parser.Is(Text.TokenType.Comma, eat: true)) + break; + } + + var rBracket = parser.Eat(Text.TokenType.RBracket); + return new() + { + Items = items + }; + } } } diff --git a/ZSharp.Parser/lang/expr/LangParser.MemberAccess.cs b/ZSharp.Parser/lang/expr/LangParser.MemberAccess.cs index 8b28c88e..fd20f567 100644 --- a/ZSharp.Parser/lang/expr/LangParser.MemberAccess.cs +++ b/ZSharp.Parser/lang/expr/LangParser.MemberAccess.cs @@ -14,7 +14,7 @@ public static BinaryExpression ParseMemberAccess(Parser parser, Expression targe { Left = target, Operator = @operator, - Right = LiteralExpression.String(name.Value), + Right = new IdentifierExpression(new(name))//LiteralExpression.String(name.Value), }; else if (parser.Is(TokenType.Number, out var index)) throw new NotImplementedException("Member access by index"); diff --git a/ZSharp.Parser/lang/expr/LangParser.While.cs b/ZSharp.Parser/lang/expr/LangParser.While.cs index 1239df51..67cee9dd 100644 --- a/ZSharp.Parser/lang/expr/LangParser.While.cs +++ b/ZSharp.Parser/lang/expr/LangParser.While.cs @@ -5,7 +5,8 @@ namespace ZSharp.Parser { public static partial class LangParser { - public static WhileExpression ParseWhileExpression(Parser parser) + public static WhileExpression ParseWhileExpression(Parser parser) + where TElse : Node { parser.Eat(Keywords.While); @@ -33,9 +34,9 @@ public static WhileExpression ParseWhileExpression(Parser parser) using (parser.Stack(LoopBody.Content)) @while = parser.Parse(); - Statement? @else = null; + TElse? @else = null; if (parser.Is(Keywords.Else, eat: true)) - @else = parser.Parse(); + @else = parser.Parse(); return new() { diff --git a/ZSharp.Parser/lang/stmt/LangParser.For.cs b/ZSharp.Parser/lang/stmt/LangParser.For.cs new file mode 100644 index 00000000..c6bac4a6 --- /dev/null +++ b/ZSharp.Parser/lang/stmt/LangParser.For.cs @@ -0,0 +1,75 @@ +using ZSharp.AST; +#if !ZSHARP_MINIMAL_PARENTHESIS +using ZSharp.Text; +#endif + +namespace ZSharp.Parser +{ + public static partial class LangParser + { + public static ForStatement ParseForStatement(Parser parser) + { + parser.Eat(Keywords.For); + +#if !ZSHARP_MINIMAL_PARENTHESIS + parser.Eat(TokenType.LParen); +#endif + + var currentItem = ParseForValue(parser); + + var inKeyword = parser.Eat(Keywords.In); + + var iterable = parser.Parse(); + +#if !ZSHARP_MINIMAL_PARENTHESIS + parser.Eat(TokenType.RParen); +#endif + +#if ZSHARP_MINIMAL_PARENTHESIS + parser.Eat(Symbols.ThenDo); +#endif + + Statement @for; + using (parser.Stack(LoopBody.Content)) + @for = parser.Parse(); + + Statement? @else = null; + + if (parser.Is(Keywords.Else, eat: true)) + @else = parser.Parse(); + + return new() + { + Value = currentItem, + Source = iterable, + Body = @for, + Else = @else, + }; + } + + private static ForValue ParseForValue(Parser parser) + { + if (parser.Is(Keywords.Let)) + return ParseLetForValue(parser); + + throw new ParseError($"Expected 'let', got {parser.Token}"); + } + + private static LetForValue ParseLetForValue(Parser parser) + { + parser.Eat(Keywords.Let); + + var name = parser.Eat(TokenType.Identifier).Value; + + Expression? type = null; + if (parser.Is(TokenType.Colon, eat: true)) + type = parser.Parse(); + + return new() + { + Name = name, + Type = type + }; + } + } +} diff --git a/ZSharp.Parser/parsers/FunctionParser.cs b/ZSharp.Parser/parsers/FunctionParser.cs index 70218bac..5d2116f7 100644 --- a/ZSharp.Parser/parsers/FunctionParser.cs +++ b/ZSharp.Parser/parsers/FunctionParser.cs @@ -65,7 +65,15 @@ private Statement ParseFunctionBody(Parser parser) using (parser.NewStack(FunctionBody.Content, parser.GetParserFor())) { if (parser.Is(LangParser.Symbols.ThenDo, eat: true)) - return ParseContextItem(parser); + //return ParseContextItem(parser); + { + var result = new Return() + { + Value = parser.Parse() + }; + parser.Eat(TokenType.Semicolon); + return result; + } return LangParser.ParseBlockStatement(parser); } diff --git a/ZSharp.Parser/parsers/ModuleParser.cs b/ZSharp.Parser/parsers/ModuleParser.cs index e609a0aa..77c20cf3 100644 --- a/ZSharp.Parser/parsers/ModuleParser.cs +++ b/ZSharp.Parser/parsers/ModuleParser.cs @@ -8,9 +8,9 @@ public sealed class ModuleParser { public override Module Parse(Parser parser) { - parser.Eat(LangParser.Keywords.Module); + var moduleKeyword = parser.Eat(LangParser.Keywords.Module); - var name = parser.Eat(TokenType.Identifier).Value; + var name = parser.Eat(TokenType.Identifier); List body; if (parser.Is(TokenType.LCurly, eat: true)) @@ -21,10 +21,14 @@ public override Module Parse(Parser parser) body = ParseModuleBody(parser, TokenType.EOF); } - return new() + return new(new() { - Body = body, + ModuleKeyword = moduleKeyword, Name = name, + }) + { + Body = body, + Name = name.Value, }; } diff --git a/ZSharp.Parser/parsers/oop/ClassParser.cs b/ZSharp.Parser/parsers/oop/ClassParser.cs index 7819d5b5..453005e7 100644 --- a/ZSharp.Parser/parsers/oop/ClassParser.cs +++ b/ZSharp.Parser/parsers/oop/ClassParser.cs @@ -16,23 +16,27 @@ public ClassParser() LangParser.Keywords.Let, Utils.ExpressionStatement(LangParser.ParseLetExpression) ); + AddKeywordParser( + LangParser.Keywords.Var, + Utils.ExpressionStatement(LangParser.ParseVarExpression) + ); AddKeywordParser( LangParser.Keywords.Function, Utils.DefinitionStatement(Method.Parse) ); AddKeywordParser( LangParser.Keywords.New, - Constructor.Parse + Utils.DefinitionStatement(Constructor.Parse) ); } public override OOPDefinition Parse(Parser parser) { - var type = parser.Eat(LangParser.Keywords.Class).Value; + var type = parser.Eat(LangParser.Keywords.Class); - string? name = null; + Token? name = null; if (parser.Is(TokenType.Identifier)) - name = parser.Eat(TokenType.Identifier).Value; + name = parser.Eat(TokenType.Identifier); Signature? signature = null; if (parser.Is(TokenType.LParen, eat: true)) @@ -42,8 +46,12 @@ public override OOPDefinition Parse(Parser parser) parser.Eat(TokenType.RParen); } + Expression? of = null; + if (parser.Is(LangParser.Keywords.Of, out var ofKeyword, eat: true)) + of = parser.Parse(); + List? bases = null; - if (parser.Is(TokenType.Colon, eat: true)) + if (parser.Is(TokenType.Colon, out var basesSeparator, eat: true)) { bases = []; @@ -59,13 +67,20 @@ public override OOPDefinition Parse(Parser parser) else parser.Eat(TokenType.Semicolon); - return new() + return new(new() { + BasesSeparator = basesSeparator, + Name = name, + OfKeyword = ofKeyword, Type = type, + }) + { + Type = type.Value, Signature = signature, + Of = of, Bases = bases, Content = body, - Name = name, + Name = name?.Value ?? string.Empty, }; } diff --git a/ZSharp.Parser/parsers/oop/ConstructorParser.cs b/ZSharp.Parser/parsers/oop/ConstructorParser.cs index 72c2c7b1..1d7c6821 100644 --- a/ZSharp.Parser/parsers/oop/ConstructorParser.cs +++ b/ZSharp.Parser/parsers/oop/ConstructorParser.cs @@ -20,11 +20,11 @@ public ConstructorParser() public override Constructor Parse(Parser parser) { - var funKeyword = parser.Eat(LangParser.Keywords.New); + var newKeyword = parser.Eat(LangParser.Keywords.New); - string? name = null; + Token? name = null; if (parser.Is(TokenType.Identifier)) - name = parser.Eat(TokenType.Identifier).Value; + name = parser.Eat(TokenType.Identifier); parser.Eat(TokenType.LParen); @@ -41,10 +41,14 @@ public override Constructor Parse(Parser parser) var body = ParseConstructorBody(parser); - return new() + return new(new() { - Body = body, Name = name, + NewKeyword = newKeyword, + }) + { + Body = body, + Name = name?.Value ?? string.Empty, Initializers = initializers, Signature = signature, }; diff --git a/ZSharp.Parser/parsers/oop/MethodParser.cs b/ZSharp.Parser/parsers/oop/MethodParser.cs index 72aa71fa..53d00cf1 100644 --- a/ZSharp.Parser/parsers/oop/MethodParser.cs +++ b/ZSharp.Parser/parsers/oop/MethodParser.cs @@ -58,20 +58,13 @@ protected override Statement ParseDefaultContextItem(Parser parser) private Statement ParseFunctionBody(Parser parser) { - if (parser.Is(LangParser.Symbols.ThenDo, eat: true)) - return ParseContextItem(parser); - - List body = []; - - parser.Eat(TokenType.LCurly); - - while (!parser.Is(TokenType.RCurly, eat: true)) - body.Add(ParseContextItem(parser)); - - return new BlockStatement() + using (parser.NewStack(MethodBody.Content, parser.GetParserFor())) { - Statements = body - }; + if (parser.Is(LangParser.Symbols.ThenDo, eat: true)) + return ParseContextItem(parser); + + return LangParser.ParseBlockStatement(parser); + } } } } diff --git a/ZSharp.Platform.IL/Compiler.cs b/ZSharp.Platform.IL/Compiler.cs new file mode 100644 index 00000000..942224d4 --- /dev/null +++ b/ZSharp.Platform.IL/Compiler.cs @@ -0,0 +1,20 @@ +using Mono.Cecil; + +namespace ZSharp.Platform.IL +{ + public sealed class Compiler + { + public ModuleDefinition Compile(IR.Module module) + { + var result = ModuleDefinition.CreateModule( + module.Name ?? "", + new ModuleParameters() + { + Kind = module.HasEntryPoint ? ModuleKind.Console : ModuleKind.Dll + } + ); + + return result; + } + } +} diff --git a/ZSharp.Platform.IL/ZSharp.Platform.IL.csproj b/ZSharp.Platform.IL/ZSharp.Platform.IL.csproj new file mode 100644 index 00000000..2cc6cd1f --- /dev/null +++ b/ZSharp.Platform.IL/ZSharp.Platform.IL.csproj @@ -0,0 +1,17 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + diff --git a/ZSharp.Platform.IL/compilers/ModuleCompiler.cs b/ZSharp.Platform.IL/compilers/ModuleCompiler.cs new file mode 100644 index 00000000..f72e1fae --- /dev/null +++ b/ZSharp.Platform.IL/compilers/ModuleCompiler.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Platform.IL +{ + internal sealed class ModuleCompiler + { + } +} diff --git a/ZSharp.Platform.IL/compilers/core/CompilerBase.cs b/ZSharp.Platform.IL/compilers/core/CompilerBase.cs new file mode 100644 index 00000000..b08d49ab --- /dev/null +++ b/ZSharp.Platform.IL/compilers/core/CompilerBase.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.IL +{ + internal abstract class CompilerBase(Context context) + { + public Context Context { get; } = context; + } +} diff --git a/ZSharp.Platform.IL/compilers/core/Context.cs b/ZSharp.Platform.IL/compilers/core/Context.cs new file mode 100644 index 00000000..04216d4f --- /dev/null +++ b/ZSharp.Platform.IL/compilers/core/Context.cs @@ -0,0 +1,6 @@ +namespace ZSharp.Platform.IL +{ + internal sealed class Context + { + } +} diff --git a/ZSharp.Platform.Runtime/GlobalUsings.cs b/ZSharp.Platform.Runtime/GlobalUsings.cs new file mode 100644 index 00000000..65bb20f3 --- /dev/null +++ b/ZSharp.Platform.Runtime/GlobalUsings.cs @@ -0,0 +1,4 @@ +global using IL = System.Reflection; + + +global using ExposedObjectHandle = int; diff --git a/ZSharp.Runtime.IL/ZSharp.Runtime.IL.csproj b/ZSharp.Platform.Runtime/ZSharp.Platform.Runtime.csproj similarity index 66% rename from ZSharp.Runtime.IL/ZSharp.Runtime.IL.csproj rename to ZSharp.Platform.Runtime/ZSharp.Platform.Runtime.csproj index 34efc948..9b9ccdd2 100644 --- a/ZSharp.Runtime.IL/ZSharp.Runtime.IL.csproj +++ b/ZSharp.Platform.Runtime/ZSharp.Platform.Runtime.csproj @@ -1,13 +1,12 @@  - net8.0 + net9.0 enable enable - diff --git a/ZSharp.Platform.Runtime/loader/GlobalUsings.cs b/ZSharp.Platform.Runtime/loader/GlobalUsings.cs new file mode 100644 index 00000000..a2fedddb --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/GlobalUsings.cs @@ -0,0 +1 @@ +global using Emit = System.Reflection.Emit; diff --git a/ZSharp.Platform.Runtime/loader/context/DebuggableEvaluationContext.cs b/ZSharp.Platform.Runtime/loader/context/DebuggableEvaluationContext.cs new file mode 100644 index 00000000..9e53d548 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/context/DebuggableEvaluationContext.cs @@ -0,0 +1,105 @@ +using System.Reflection; +using System.Reflection.Emit; + +namespace ZSharp.Platform.Runtime +{ + internal sealed class DebuggableEvaluationContext + : IEvaluationContext + { + private const string TypeName = ""; + private const string MethodName = ""; + + private readonly PersistedAssemblyBuilder assemblyBuilder; + private readonly ModuleBuilder moduleBuilder; + private readonly TypeBuilder typeBuilder; + private MethodBuilder? methodBuilder; + + public string? OutputPath { get; init; } + + internal DebuggableEvaluationContext(string name) + { + assemblyBuilder = new PersistedAssemblyBuilder( + new AssemblyName(name), + typeof(object).Assembly, + [ + new( + typeof(System.Diagnostics.DebuggableAttribute).GetConstructor([ + typeof(System.Diagnostics.DebuggableAttribute.DebuggingModes) + ]) ?? throw new(), + [ + System.Diagnostics.DebuggableAttribute.DebuggingModes.DisableOptimizations | + System.Diagnostics.DebuggableAttribute.DebuggingModes.Default | + System.Diagnostics.DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | + System.Diagnostics.DebuggableAttribute.DebuggingModes.EnableEditAndContinue + ] + ) + ] + ); + moduleBuilder = assemblyBuilder.DefineDynamicModule(name); + typeBuilder = moduleBuilder.DefineType( + TypeName, + TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract + ); + } + + ModuleBuilder IEvaluationContext.Module => moduleBuilder; + + ILGenerator IEvaluationContext.DefineCode(Type returnType) + { + if (methodBuilder is not null) + throw new InvalidOperationException("Code method has already been defined."); + + return (methodBuilder = typeBuilder.DefineMethod( + MethodName, + MethodAttributes.Public | MethodAttributes.Static, + returnType, + [] + )).GetILGenerator(); + } + + MethodInfo IEvaluationContext.LoadMethod() + { + typeBuilder.CreateType(); + + var metadataBuilder = assemblyBuilder.GenerateMetadata(out var ilStream, out _, out var pdbBuilder); + var entryPointHandle = IL.Metadata.Ecma335.MetadataTokens.MethodDefinitionHandle(methodBuilder!.MetadataToken); + + var portablePdbBlob = new IL.Metadata.BlobBuilder(); + var portablePdbBuilder = new IL.Metadata.Ecma335.PortablePdbBuilder(pdbBuilder, metadataBuilder.GetRowCounts(), entryPointHandle); + var pdbContentId = portablePdbBuilder.Serialize(portablePdbBlob); + + var debugDirectoryBuilder = new IL.PortableExecutable.DebugDirectoryBuilder(); + debugDirectoryBuilder.AddCodeViewEntry($"{assemblyBuilder.GetName().Name}.pdb", pdbContentId, portablePdbBuilder.FormatVersion); + debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbBlob, portablePdbBuilder.FormatVersion); + + IL.PortableExecutable.ManagedPEBuilder peBuilder = new( + header: new( + imageCharacteristics: IL.PortableExecutable.Characteristics.Dll, + subsystem: IL.PortableExecutable.Subsystem.WindowsCui + ), + metadataRootBuilder: new(metadataBuilder), + ilStream: ilStream, + debugDirectoryBuilder: debugDirectoryBuilder + ); + + var peBlob = new IL.Metadata.BlobBuilder(); + peBuilder.Serialize(peBlob); + + using var stream = new MemoryStream(); + peBlob.WriteContentTo(stream); + + if (OutputPath is not null) + { + stream.Seek(0, SeekOrigin.Begin); + using var fileStream = File.Create(Path.Join(OutputPath, $"{assemblyBuilder.GetName().Name}.dll")); + stream.CopyTo(fileStream); + } + + stream.Seek(0, SeekOrigin.Begin); + var loadedAssembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromStream(stream); + var method = loadedAssembly.GetType(TypeName)?.GetMethod(MethodName) + ?? throw new InvalidOperationException("Failed to load generated code method."); + return method; + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/context/ExecutionEvaluationContext.cs b/ZSharp.Platform.Runtime/loader/context/ExecutionEvaluationContext.cs new file mode 100644 index 00000000..851e9fa8 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/context/ExecutionEvaluationContext.cs @@ -0,0 +1,30 @@ +using System.Reflection; +using System.Reflection.Emit; + +namespace ZSharp.Platform.Runtime +{ + internal sealed class ExecutionEvaluationContext(ModuleBuilder moduleBuilder) + : IEvaluationContext + { + private readonly ModuleBuilder moduleBuilder = moduleBuilder; + private DynamicMethod? dynamicMethod; + + ModuleBuilder IEvaluationContext.Module => throw new NotImplementedException(); + + ILGenerator IEvaluationContext.DefineCode(Type returnType) + { + if (dynamicMethod is not null) + throw new InvalidOperationException("Code has already been defined."); + + return (dynamicMethod = new( + "", + returnType, + [], + moduleBuilder + )).GetILGenerator(); + } + + MethodInfo IEvaluationContext.LoadMethod() + => dynamicMethod ?? throw new InvalidOperationException("Code has not been defined."); + } +} diff --git a/ZSharp.Platform.Runtime/loader/context/IEvaluationContext.cs b/ZSharp.Platform.Runtime/loader/context/IEvaluationContext.cs new file mode 100644 index 00000000..acf77dcb --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/context/IEvaluationContext.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Platform.Runtime +{ + public interface IEvaluationContext + { + public Emit.ModuleBuilder Module { get; } + + public Emit.ILGenerator DefineCode(Type returnType); + + public IL.MethodInfo LoadMethod(); + } +} diff --git a/ZSharp.Platform.Runtime/loader/context/factories/DebuggableEvaluationContextFactory.cs b/ZSharp.Platform.Runtime/loader/context/factories/DebuggableEvaluationContextFactory.cs new file mode 100644 index 00000000..c419ac04 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/context/factories/DebuggableEvaluationContextFactory.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Platform.Runtime +{ + internal sealed class DebuggableEvaluationContextFactory + : IEvaluationContextFactory + { + private const string AssemblyFormat = "ZSharpPersistedAssembly_{0}"; + private int persistedAssemblyCount = 0; + + public string? OutputPath { get; init; } + + IEvaluationContext IEvaluationContextFactory.CreateEvaluationContext() + => new DebuggableEvaluationContext(string.Format(AssemblyFormat, persistedAssemblyCount++)) + { + OutputPath = OutputPath + }; + } +} diff --git a/ZSharp.Platform.Runtime/loader/context/factories/ExecutionEvaluationContextFactory.cs b/ZSharp.Platform.Runtime/loader/context/factories/ExecutionEvaluationContextFactory.cs new file mode 100644 index 00000000..67438b1c --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/context/factories/ExecutionEvaluationContextFactory.cs @@ -0,0 +1,24 @@ +namespace ZSharp.Platform.Runtime +{ + internal sealed class ExecutionEvaluationContextFactory + : IEvaluationContextFactory + { + public Emit.AssemblyBuilder StandaloneAssembly { get; } + + public Emit.ModuleBuilder StandaloneModule { get; } + + public ExecutionEvaluationContextFactory() + { + StandaloneAssembly = Emit.AssemblyBuilder.DefineDynamicAssembly( + new(""), + Emit.AssemblyBuilderAccess.RunAndCollect + ); + StandaloneModule = StandaloneAssembly.DefineDynamicModule( + "" + ); + } + + IEvaluationContext IEvaluationContextFactory.CreateEvaluationContext() + => new ExecutionEvaluationContext(StandaloneModule); + } +} diff --git a/ZSharp.Platform.Runtime/loader/context/factories/IEvaluationContextFactory.cs b/ZSharp.Platform.Runtime/loader/context/factories/IEvaluationContextFactory.cs new file mode 100644 index 00000000..2b5f2e1b --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/context/factories/IEvaluationContextFactory.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + public interface IEvaluationContextFactory + { + public IEvaluationContext CreateEvaluationContext(); + } +} diff --git a/ZSharp.Platform.Runtime/loader/emit/EmitLoader.Standalone.cs b/ZSharp.Platform.Runtime/loader/emit/EmitLoader.Standalone.cs new file mode 100644 index 00000000..0bfa89b2 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/emit/EmitLoader.Standalone.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class EmitLoader + { + public Emit.AssemblyBuilder StandaloneAssembly { get; } + + public Emit.ModuleBuilder StandaloneModule { get; } + } +} diff --git a/ZSharp.Platform.Runtime/loader/emit/EmitLoader.cs b/ZSharp.Platform.Runtime/loader/emit/EmitLoader.cs new file mode 100644 index 00000000..4fb3bb3c --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/emit/EmitLoader.cs @@ -0,0 +1,33 @@ +using Debuggable = System.Diagnostics.DebuggableAttribute; + +namespace ZSharp.Platform.Runtime.Loaders +{ + public sealed partial class EmitLoader + { + public Runtime Runtime { get; } + + internal EmitLoader(Runtime runtime) + { + Runtime = runtime; + + StandaloneAssembly = new Emit.PersistedAssemblyBuilder( + new(""), + typeof(void).Assembly, + [ + new( + typeof(Debuggable).GetConstructor([ + typeof(Debuggable.DebuggingModes) + ]) ?? throw new(), + [ + Debuggable.DebuggingModes.Default + ] + ) + ] + ); + + StandaloneModule = StandaloneAssembly.DefineDynamicModule( + "" + ); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Code.cs b/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Code.cs new file mode 100644 index 00000000..a548b5b1 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Code.cs @@ -0,0 +1,43 @@ +using CommonZ.Utils; + +using Debuggable = System.Diagnostics.DebuggableAttribute; + +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class EmitLoader + { + private delegate T CodeFunctionType(); + private delegate void VoidCodeFunction(); + + public Delegate LoadCode( + Collection code, + IR.IType irReturnType, + IEvaluationContext evaluationContext + ) + { + if (code.Count == 0) return () => { }; + + if (code.Last() is not IR.VM.Return) + code.Add(new IR.VM.Return()); + + var ilReturnType = Runtime.ImportType(irReturnType); + var ilGenerator = evaluationContext.DefineCode(ilReturnType); + + var codeLoader = new CodeCompiler(new UnboundCodeContext(Runtime, ilGenerator)); + codeLoader.CompileCode(code); + + var method = evaluationContext.LoadMethod(); + + return + ilReturnType != typeof(void) + ? method.CreateDelegate( + typeof(CodeFunctionType<>) + .MakeGenericType(ilReturnType) + ) + : method.CreateDelegate( + typeof(VoidCodeFunction) + ) + ; + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Function.cs b/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Function.cs new file mode 100644 index 00000000..130baa57 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Function.cs @@ -0,0 +1,81 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class EmitLoader + { + public IL.MethodInfo LoadStandaloneFunction(IR.Function function) + { + if (function.HasGenericParameters) + return LoadStandaloneGenericFunction(function); + return LoadStandaloneRegularFunction(function); + } + + private IL.MethodInfo LoadStandaloneRegularFunction(IR.Function function) + { + var method = new Emit.DynamicMethod( + function.Name ?? string.Empty, + Runtime.ImportType(function.ReturnType), + [ + .. function.Signature + .GetParameters() + .Select(p => p.Type) + .Select(Runtime.ImportType) + ], + StandaloneModule + ); + + foreach (var (i, parameter) in function.Signature.GetParameters().Select((v, i) => (i, v))) + method.DefineParameter(i + 1, IL.ParameterAttributes.None, parameter.Name); + + CompileFunctionCode(function, method.GetILGenerator()); + + return method; + } + + private IL.MethodInfo LoadStandaloneGenericFunction(IR.Function function) + { + var type = StandaloneModule.DefineType( + $"<{function.Name ?? string.Empty}>{StandaloneModule.GetTypes().Length}", + IL.TypeAttributes.Abstract | IL.TypeAttributes.Sealed + ); + var method = type.DefineMethod( + function.Name ?? "", + IL.MethodAttributes.Public | IL.MethodAttributes.Static, + Runtime.ImportType(function.ReturnType), + [ + .. function.Signature + .GetParameters() + .Select(p => p.Type) + .Select(Runtime.ImportType) + ] + ); + + var genericParameters = method.DefineGenericParameters( + [ + .. function.GenericParameters + .Select(p => p.Name) + ] + ); + + foreach (var (ir, il) in function.GenericParameters.Zip(genericParameters)) + Runtime.AddType(ir, il); + + foreach (var (i, parameter) in function.Signature.GetParameters().Select((v, i) => (i, v))) + method.DefineParameter(i + 1, IL.ParameterAttributes.None, parameter.Name); + + CompileFunctionCode(function, method.GetILGenerator()); + + foreach (var genericParameter in function.GenericParameters) + Runtime.DelType(genericParameter); + + type.CreateType(); + + return method; + } + + private void CompileFunctionCode(IR.Function function, Emit.ILGenerator il) + { + var codeLoader = new CodeCompiler(FunctionCodeContext.From(Runtime, il, function)); + codeLoader.CompileCode(function.Body.Instructions); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Module.cs b/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Module.cs new file mode 100644 index 00000000..43f659e4 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Module.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class EmitLoader + { + public IL.Module LoadModule(IR.Module module) + => new ModuleLoader(this, module).Load(); + } +} diff --git a/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Type.cs b/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Type.cs new file mode 100644 index 00000000..86c7b807 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/emit/load/EmitLoader.Load.Type.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class EmitLoader + { + public Type LoadType(IR.TypeDefinition type) + => TypeLoaderHelper.LoadType(this, StandaloneModule, type); + } +} diff --git a/ZSharp.Platform.Runtime/loader/helpers/LoaderBase.cs b/ZSharp.Platform.Runtime/loader/helpers/LoaderBase.cs new file mode 100644 index 00000000..2974eb53 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/helpers/LoaderBase.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal abstract class LoaderBase(EmitLoader loader) + { + public EmitLoader Loader { get; } = loader; + } +} diff --git a/ZSharp.Platform.Runtime/loader/helpers/TypeLoaderBase.cs b/ZSharp.Platform.Runtime/loader/helpers/TypeLoaderBase.cs new file mode 100644 index 00000000..8b7dba5f --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/helpers/TypeLoaderBase.cs @@ -0,0 +1,29 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal abstract class TypeLoaderBase(EmitLoader loader) + : LoaderBase(loader) + where T: IR.TypeDefinition + { + public required Emit.TypeBuilder ILType { get; init; } + + public required T IRType { get; init; } + + public required TaskManager Tasks { get; init; } + + public Type Load() + { + Loader.Runtime.AddTypeDefinition(IRType, ILType); + + DoLoad(); + + AddTask(() => AddTask(() => Loader.Runtime.SetTypeDefinition(IRType, ILType.CreateType()))); + + return ILType; + } + + protected abstract void DoLoad(); + + protected virtual void AddTask(Action task) + => Tasks.AddTask(task); + } +} diff --git a/ZSharp.Platform.Runtime/loader/helpers/TypeLoaderHelper.cs b/ZSharp.Platform.Runtime/loader/helpers/TypeLoaderHelper.cs new file mode 100644 index 00000000..c3eaea44 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/helpers/TypeLoaderHelper.cs @@ -0,0 +1,85 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal static class TypeLoaderHelper + { + public static Type LoadType(EmitLoader loader, Emit.TypeBuilder parentBuilder, IR.TypeDefinition type) + { + var tasks = new TaskManager(() => { }); + var result = type switch + { + IR.Class def => new ClassLoader(loader) + { + ILType = parentBuilder.DefineNestedType( + def.Name ?? throw new(), + IL.TypeAttributes.Public + ), + IRType = def, + Tasks = tasks + }.Load(), + IR.EnumClass def => new EnumClassLoader(loader) + { + ILType = parentBuilder.DefineNestedType( + def.Name ?? throw new(), + IL.TypeAttributes.Public | IL.TypeAttributes.Sealed, + typeof(Enum) + ), + IRType = def, + Tasks = tasks + }.Load(), + IR.Interface def => new InterfaceLoader(loader) + { + ILType = parentBuilder.DefineNestedType( + def.Name ?? throw new(), + IL.TypeAttributes.Public | IL.TypeAttributes.Interface + ), + IRType = def, + Tasks = tasks + }.Load(), + IR.ValueType def => throw new NotSupportedException(), + _ => throw new NotSupportedException(), + }; + tasks.RunUntilComplete(); + return result; + } + + public static Type LoadType(EmitLoader loader, Emit.ModuleBuilder parentBuilder, IR.TypeDefinition type) + { + var tasks = new TaskManager(() => { }); + var result = type switch + { + IR.Class def => new ClassLoader(loader) + { + ILType = parentBuilder.DefineType( + def.Name ?? throw new(), + IL.TypeAttributes.Public + ), + IRType = def, + Tasks = tasks + }.Load(), + IR.EnumClass def => new EnumClassLoader(loader) + { + ILType = parentBuilder.DefineType( + def.Name ?? throw new(), + IL.TypeAttributes.Public | IL.TypeAttributes.Sealed, + typeof(Enum) + ), + IRType = def, + Tasks = tasks + }.Load(), + IR.Interface def => new InterfaceLoader(loader) + { + ILType = parentBuilder.DefineType( + def.Name ?? throw new(), + IL.TypeAttributes.Public | IL.TypeAttributes.Interface + ), + IRType = def, + Tasks = tasks + }.Load(), + IR.ValueType def => throw new NotSupportedException(), + _ => throw new NotSupportedException(), + }; + tasks.RunUntilComplete(); + return result; + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/class/ClassLoader.Context.cs b/ZSharp.Platform.Runtime/loader/loaders/class/ClassLoader.Context.cs new file mode 100644 index 00000000..ac0e4fb7 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/class/ClassLoader.Context.cs @@ -0,0 +1,9 @@ +using CommonZ.Utils; + +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ClassLoader + { + private Cache? genericTypeContext; + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/class/ClassLoader.Tasks.cs b/ZSharp.Platform.Runtime/loader/loaders/class/ClassLoader.Tasks.cs new file mode 100644 index 00000000..38ee2933 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/class/ClassLoader.Tasks.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ClassLoader + { + protected override void AddTask(Action task) + { + if (genericTypeContext is not null) + { + var originalTask = task; + task = () => + { + using (Loader.Runtime.TypeContext(genericTypeContext)) + originalTask(); + }; + } + + base.AddTask(task); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/class/ClassLoader.cs b/ZSharp.Platform.Runtime/loader/loaders/class/ClassLoader.cs new file mode 100644 index 00000000..499e65b7 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/class/ClassLoader.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal sealed partial class ClassLoader(EmitLoader loader) + : TypeLoaderBase(loader) + { + + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Constructor.cs b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Constructor.cs new file mode 100644 index 00000000..0ad0297b --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Constructor.cs @@ -0,0 +1,22 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ClassLoader + { + private void LoadConstructor(IR.Constructor constructor) + { + var result = ILType.DefineConstructor( + IL.MethodAttributes.Public, + IL.CallingConventions.HasThis, + [.. constructor.Method.Signature.GetParameters().Skip(1).Select(p => Loader.Runtime.ImportType(p.Type))] + ); + + Loader.Runtime.AddFunction(constructor.Method.UnderlyingFunction, result); + + var context = FunctionCodeContext.From(Loader.Runtime, result, constructor.Method.UnderlyingFunction); + + var codeLoader = new CodeCompiler(context); + + AddTask(() => codeLoader.CompileCode(constructor.Method.Body.Instructions)); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Field.cs b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Field.cs new file mode 100644 index 00000000..cc7c4b3a --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Field.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ClassLoader + { + private void LoadField(IR.Field field) + { + var attributes = IL.FieldAttributes.Public; + + if (field.IsStatic) + attributes |= IL.FieldAttributes.Static; + + var il = ILType.DefineField(field.Name, Loader.Runtime.ImportType(field.Type), attributes); + + Loader.Runtime.AddField(field, il); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Generic.cs b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Generic.cs new file mode 100644 index 00000000..39cee374 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Generic.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ClassLoader + { + private void LoadGenericParameters() + { + if (!IRType.HasGenericParameters) return; + + var ils = ILType.DefineGenericParameters( + [ + .. IRType.GenericParameters + .Select(p => p.Name) + ] + ); + + foreach (var (ir, il) in IRType.GenericParameters.Zip(ils)) + Loader.Runtime.AddType(ir, il); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Method.cs b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Method.cs new file mode 100644 index 00000000..dea1826a --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Method.cs @@ -0,0 +1,38 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ClassLoader + { + private void LoadMethod(IR.Method method) + { + var attributes = IL.MethodAttributes.Public; + + if (method.IsStatic) + attributes |= IL.MethodAttributes.Static; + if (method.IsVirtual) + attributes |= IL.MethodAttributes.Virtual | IL.MethodAttributes.NewSlot; + + var result = ILType.DefineMethod( + method.Name ?? string.Empty, + attributes, + Loader.Runtime.ImportType(method.ReturnType), + [.. ( + method.IsInstance || method.IsVirtual + ? method.Signature.GetParameters().Skip(1) + : method.Signature.GetParameters() + ).Select(p => Loader.Runtime.ImportType(p.Type)) + ] + ); + + Loader.Runtime.AddFunction(method.UnderlyingFunction, result); + + var context = FunctionCodeContext.From(Loader.Runtime, result, method.UnderlyingFunction); + + foreach (var local in method.Body.Locals) + result.GetILGenerator().DeclareLocal(Loader.Runtime.ImportType(local.Type)); + + var codeLoader = new CodeCompiler(context); + + AddTask(() => codeLoader.CompileCode(method.Body.Instructions)); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Type.cs b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Type.cs new file mode 100644 index 00000000..52437ddf --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.Type.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ClassLoader + { + private void LoadNestedType(IR.TypeDefinition type) + { + TypeLoaderHelper.LoadType(Loader, ILType, type); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.cs b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.cs new file mode 100644 index 00000000..35297072 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/class/load/ClassLoader.Load.cs @@ -0,0 +1,65 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ClassLoader + { + protected override void DoLoad() + { + if (IRType.HasGenericParameters) + genericTypeContext = Loader.Runtime.NewTypeContext(); + + if (genericTypeContext is not null) + using (Loader.Runtime.TypeContext(genericTypeContext)) + LoadAll(); + else + LoadAll(); + } + + private void LoadAll() + { + LoadGenericParameters(); + + LoadNestedTypes(); + + AddTask(LoadBase); + + AddTask(LoadFields); + + AddTask(LoadConstructors); + + AddTask(LoadMethods); + } + + private void LoadBase() + { + if (IRType.Base is not null) + ILType.SetParent(Loader.Runtime.ImportType(IRType.Base)); + } + + private void LoadNestedTypes() + { + foreach (var type in IRType.NestedTypes) + LoadNestedType(type); + } + + private void LoadFields() + { + if (IRType.HasFields) + foreach (var field in IRType.Fields) + LoadField(field); + } + + private void LoadMethods() + { + if (IRType.HasMethods) + foreach (var method in IRType.Methods) + LoadMethod(method); + } + + private void LoadConstructors() + { + if (IRType.HasConstructors) + foreach (var constructor in IRType.Constructors) + LoadConstructor(constructor); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code contexts/FunctionCodeContext.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code contexts/FunctionCodeContext.cs new file mode 100644 index 00000000..f5a1a1e1 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code contexts/FunctionCodeContext.cs @@ -0,0 +1,82 @@ +using CommonZ.Utils; +using ZSharp.IR; + +namespace ZSharp.Platform.Runtime.Loaders +{ + internal sealed class FunctionCodeContext + : ICodeContext + , IBranchingCodeContext + , IFrameCodeContext + , IFunctionalCodeContext + { + private readonly Mapping locals = []; + private readonly Mapping parameters = []; + private readonly Mapping labels = []; + + public Emit.ILGenerator IL { get; } + + public CodeStack Stack { get; } = new(); + + public Runtime Runtime { get; } + + public Function Function { get; } + + private FunctionCodeContext(Runtime runtime, Emit.ILGenerator il, Function function) + { + Runtime = runtime; + IL = il; + Function = function; + } + + void IBranchingCodeContext.AddBranchTarget(IR.VM.Instruction target) + => labels[target] = IL.DefineLabel(); + + Emit.Label IBranchingCodeContext.GetBranchTarget(IR.VM.Instruction target) + => labels[target]; + + Local IFrameCodeContext.GetLocal(IR.VM.Local local) + => locals[local]; + + Parameter IFrameCodeContext.GetParameter(IR.Parameter parameter) + => parameters[parameter]; + + private void SetupFromIR() + { + foreach (var parameter in Function.Signature.GetParameters()) + parameters[parameter] = new() + { + Index = parameter.Index, + Name = parameter.Name, + Type = Runtime.ImportType(parameter.Type) + }; + + if (Function.HasBody && Function.Body.HasLocals) + foreach (var local in Function.Body.Locals) + { + var il = locals[local] = new() + { + Index = local.Index, + Name = local.Name, + Type = Runtime.ImportType(local.Type) + }; + + IL.DeclareLocal(il.Type); + } + } + + public static FunctionCodeContext From(Runtime runtime, Emit.ConstructorBuilder constructor, Function function) + => From(runtime, constructor.GetILGenerator(), function); + + public static FunctionCodeContext From(Runtime runtime, Emit.MethodBuilder method, Function function) + => From(runtime, method.GetILGenerator(), function); + + public static FunctionCodeContext From(Runtime runtime, Emit.ILGenerator il, Function function) + { + var context = new FunctionCodeContext(runtime, il, function); + + context.SetupFromIR(); + + return context; + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code contexts/UnboundCodeContext.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code contexts/UnboundCodeContext.cs new file mode 100644 index 00000000..072d030a --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code contexts/UnboundCodeContext.cs @@ -0,0 +1,27 @@ +using CommonZ.Utils; +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Platform.Runtime.Loaders +{ + internal sealed class UnboundCodeContext(Runtime runtime, Emit.ILGenerator il) + : ICodeContext + , IBranchingCodeContext + { + private readonly Mapping labels = []; + + public Emit.ILGenerator IL { get; } = il; + + public CodeStack Stack { get; } = new(); + + public Runtime Runtime { get; } = runtime; + + void IBranchingCodeContext.AddBranchTarget(IR.VM.Instruction target) + => labels[target] = IL.DefineLabel(); + + Emit.Label IBranchingCodeContext.GetBranchTarget(IR.VM.Instruction target) + => labels[target]; + + bool IContext.Is([NotNullWhen(true)] out T? context) where T : class + => (context = this as T) is not null; + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/CodeCompiler.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/CodeCompiler.cs new file mode 100644 index 00000000..98baad79 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/CodeCompiler.cs @@ -0,0 +1,70 @@ +using CommonZ.Utils; + +namespace ZSharp.Platform.Runtime.Loaders +{ + public sealed class CodeCompiler(ICodeContext context) + { + public ICodeContext Context { get; } = context; + + public void CompileCode(Collection instructions) + { + if (Context.Is(out var branchingContext)) + { + foreach (var instruction in instructions) + branchingContext.AddBranchTarget(instruction); + + foreach (var instruction in instructions) + { + Context.IL.MarkLabel(branchingContext.GetBranchTarget(instruction)); + + Compile(instruction); + } + } else + foreach (var instruction in instructions) + Compile(instruction); + } + + private void Compile(IR.VM.Instruction instruction) + { + switch (instruction) + { + case IR.VM.Call call: CodeCompiler_Impl.Compile(RequireContext(), call); break; + case IR.VM.CallIndirect callIndirect: CodeCompiler_Impl.Compile(RequireContext(), callIndirect); break; + case IR.VM.CallVirtual callVirtual: CodeCompiler_Impl.Compile(RequireContext(), callVirtual); break; + case IR.VM.CastReference castReference: CodeCompiler_Impl.Compile(RequireContext(), castReference); break; + case IR.VM.CreateInstance createInstance: CodeCompiler_Impl.Compile(RequireContext(), createInstance); break; + case IR.VM.Dup dup: CodeCompiler_Impl.Compile(RequireContext(), dup); break; + case IR.VM.GetArgument getArgument: CodeCompiler_Impl.Compile(RequireContext(), getArgument); break; + //case IR.VM.GetClass getClass: CodeCompiler_Impl.Compile(RequireContext(), getClass); break; + case IR.VM.GetField getField: CodeCompiler_Impl.Compile(RequireContext(), getField); break; + case IR.VM.GetGlobal getGlobal: CodeCompiler_Impl.Compile(RequireContext(), getGlobal); break; + case IR.VM.GetLocal getLocal: CodeCompiler_Impl.Compile(RequireContext(), getLocal); break; + //case IR.VM.GetObject getObject: CodeCompiler_Impl.Compile(RequireContext(), getObject); break; + case IR.VM.IsNotNull isNotNull: CodeCompiler_Impl.Compile(RequireContext(), isNotNull); break; + case IR.VM.IsNull isNull: CodeCompiler_Impl.Compile(RequireContext(), isNull); break; + case IR.VM.Jump jump: CodeCompiler_Impl.Compile(RequireContext(), jump); break; + case IR.VM.JumpIfTrue jumpIfTrue: CodeCompiler_Impl.Compile(RequireContext(), jumpIfTrue); break; + case IR.VM.JumpIfFalse jumpIfFalse: CodeCompiler_Impl.Compile(RequireContext(), jumpIfFalse); break; + case IR.VM.Nop nop: CodeCompiler_Impl.Compile(RequireContext(), nop); break; + case IR.VM.Pop pop: CodeCompiler_Impl.Compile(RequireContext(), pop); break; + case IR.VM.PutBoolean putBoolean: CodeCompiler_Impl.Compile(RequireContext(), putBoolean); break; + case IR.VM.PutFloat32 putFloat32: CodeCompiler_Impl.Compile(RequireContext(), putFloat32); break; + case IR.VM.PutInt32 putInt32: CodeCompiler_Impl.Compile(RequireContext(), putInt32); break; + case IR.VM.PutNull putNull: CodeCompiler_Impl.Compile(RequireContext(), putNull); break; + case IR.VM.PutString putString: CodeCompiler_Impl.Compile(RequireContext(), putString); break; + case IR.VM.Return @return: CodeCompiler_Impl.Compile(RequireContext(), @return); break; + case IR.VM.SetArgument setArgument: CodeCompiler_Impl.Compile(RequireContext(), setArgument); break; + case IR.VM.SetField setField: CodeCompiler_Impl.Compile(RequireContext(), setField); break; + case IR.VM.SetGlobal setGlobal: CodeCompiler_Impl.Compile(RequireContext(), setGlobal); break; + case IR.VM.SetLocal setLocal: CodeCompiler_Impl.Compile(RequireContext(), setLocal); break; + case IR.VM.Swap swap: CodeCompiler_Impl.Compile(RequireContext(), swap); break; + + default: throw new NotImplementedException(); + } + } + + private T RequireContext() + where T : class, ICodeContext + => Context.Is(out var required) ? required : throw new InvalidOperationException(); + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/branching/BranchingCodeCompiler.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/branching/BranchingCodeCompiler.cs new file mode 100644 index 00000000..67326da2 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/branching/BranchingCodeCompiler.cs @@ -0,0 +1,24 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal static partial class CodeCompiler_Impl + { + public static void Compile(IBranchingCodeContext ctx, IR.VM.Jump jump) + { + ctx.IL.Emit(IL.Emit.OpCodes.Br, ctx.GetBranchTarget(jump.Target)); + } + + public static void Compile(IBranchingCodeContext ctx, IR.VM.JumpIfTrue jump) + { + ctx.IL.Emit(IL.Emit.OpCodes.Brtrue, ctx.GetBranchTarget(jump.Target)); + + ctx.Stack.Pop(typeof(bool)); + } + + public static void Compile(IBranchingCodeContext ctx, IR.VM.JumpIfFalse jump) + { + ctx.IL.Emit(IL.Emit.OpCodes.Brfalse, ctx.GetBranchTarget(jump.Target)); + + ctx.Stack.Pop(typeof(bool)); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/branching/IBranchingCodeContext.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/branching/IBranchingCodeContext.cs new file mode 100644 index 00000000..9fc357e2 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/branching/IBranchingCodeContext.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + public interface IBranchingCodeContext + : ICodeContext + { + public void AddBranchTarget(IR.VM.Instruction target); + + public IL.Emit.Label GetBranchTarget(IR.VM.Instruction target); + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/core/CodeStack.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/core/CodeStack.cs new file mode 100644 index 00000000..c774bc58 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/core/CodeStack.cs @@ -0,0 +1,25 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + public sealed class CodeStack + { + private readonly Stack ilStack = []; + + public void Dup() + => ilStack.Push(ilStack.Peek()); + + public void Put(Type type) + => ilStack.Push(type); + + public Type Pop() => ilStack.Pop(); + + public Type Pop(Type expect) + { + var result = Pop(); + if (result != expect) throw new(); + return result; + } + + public Type? Top() + => ilStack.Count == 0 ? null : ilStack.Peek(); + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/core/ICodeContext.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/core/ICodeContext.cs new file mode 100644 index 00000000..d953c9b1 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/core/ICodeContext.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + public interface ICodeContext : IContext + { + public Emit.ILGenerator IL { get; } + + public CodeStack Stack { get; } + + public Runtime Runtime { get; } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/core/IContext.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/core/IContext.cs new file mode 100644 index 00000000..e8565445 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/core/IContext.cs @@ -0,0 +1,11 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.Platform.Runtime.Loaders +{ + public interface IContext + { + public bool Is([NotNullWhen(true)] out T? context) + where T : class, IContext + => (context = this as T) != null; + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/FrameCodeCompiler.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/FrameCodeCompiler.cs new file mode 100644 index 00000000..0fd3aa89 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/FrameCodeCompiler.cs @@ -0,0 +1,73 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal static partial class CodeCompiler_Impl + { + public static void Compile(IFrameCodeContext ctx, IR.VM.GetArgument get) + { + var parameter = ctx.GetParameter(get.Argument); + var index = parameter.Index; + + if (index == 0) + ctx.IL.Emit(IL.Emit.OpCodes.Ldarg_0); + else if (index == 1) + ctx.IL.Emit(IL.Emit.OpCodes.Ldarg_1); + else if (index == 2) + ctx.IL.Emit(IL.Emit.OpCodes.Ldarg_2); + else if (index == 3) + ctx.IL.Emit(IL.Emit.OpCodes.Ldarg_3); + else if (index <= byte.MaxValue) + ctx.IL.Emit(IL.Emit.OpCodes.Ldarg_S, (byte)index); + else + ctx.IL.Emit(IL.Emit.OpCodes.Ldarg, index); + + ctx.Stack.Put(parameter.Type); + } + + public static void Compile(IFrameCodeContext ctx, IR.VM.GetLocal get) + { + var l = ctx.GetLocal(get.Local); + var index = l.Index; + + if (index == 0) + ctx.IL.Emit(IL.Emit.OpCodes.Ldloc_0); + else if (index == 1) + ctx.IL.Emit(IL.Emit.OpCodes.Ldloc_1); + else if (index == 2) + ctx.IL.Emit(IL.Emit.OpCodes.Ldloc_2); + else if (index == 3) + ctx.IL.Emit(IL.Emit.OpCodes.Ldloc_3); + else if (index <= byte.MaxValue) + ctx.IL.Emit(IL.Emit.OpCodes.Ldloc_S, (byte)index); + else + ctx.IL.Emit(IL.Emit.OpCodes.Ldloc, index); + + ctx.Stack.Put(l.Type); + } + + public static void Compile(IFrameCodeContext ctx, IR.VM.SetArgument set) + { + var parameter = ctx.GetParameter(set.Argument); + var index = parameter.Index; + + if (index <= byte.MaxValue) + ctx.IL.Emit(IL.Emit.OpCodes.Starg_S, (byte)index); + else + ctx.IL.Emit(IL.Emit.OpCodes.Starg, index); + + ctx.Stack.Pop(parameter.Type); + } + + public static void Compile(IFrameCodeContext ctx, IR.VM.SetLocal set) + { + var local = ctx.GetLocal(set.Local); + var index = local.Index; + + if (index <= byte.MaxValue) + ctx.IL.Emit(IL.Emit.OpCodes.Stloc_S, (byte)index); + else + ctx.IL.Emit(IL.Emit.OpCodes.Stloc, index); + + ctx.Stack.Pop(local.Type); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/IFrameCodeContext.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/IFrameCodeContext.cs new file mode 100644 index 00000000..831eb0ab --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/IFrameCodeContext.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + public interface IFrameCodeContext + : ICodeContext + { + public Parameter GetParameter(IR.Parameter parameter); + + public Local GetLocal(IR.VM.Local local); + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/Local.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/Local.cs new file mode 100644 index 00000000..587e18ec --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/Local.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + public sealed class Local + { + public required string Name { get; init; } + + public required int Index { get; init; } + + public required Type Type { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/Parameter.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/Parameter.cs new file mode 100644 index 00000000..54dda7e5 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/frame/Parameter.cs @@ -0,0 +1,11 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + public sealed class Parameter + { + public required string Name { get; init; } + + public required int Index { get; init; } + + public required Type Type { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/functional/FunctionalCodeCompiler.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/functional/FunctionalCodeCompiler.cs new file mode 100644 index 00000000..8c077c8d --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/functional/FunctionalCodeCompiler.cs @@ -0,0 +1,34 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal static partial class CodeCompiler_Impl + { + public static void Compile(ICodeContext ctx, IR.VM.Call call) + { + var callable = ctx.Runtime.ImportCallable(call.Callable); + + foreach (var parameter in call.Callable.Signature.GetParameters().Reverse()) + ctx.Stack.Pop(ctx.Runtime.ImportType(parameter.Type)); + + if (callable is IL.MethodInfo method) + { + ctx.IL.Emit(Emit.OpCodes.Call, method); + + if (method.ReturnType != typeof(void)) + ctx.Stack.Put(method.ReturnType); + } + else if (callable is IL.ConstructorInfo constructor) + ctx.IL.Emit(Emit.OpCodes.Call, constructor); + else throw new($"Unknown callable type: {callable.GetType()}"); + } + + public static void Compile(ICodeContext ctx, IR.VM.CallIndirect call) + { + throw new NotImplementedException(); + } + + public static void Compile(ICodeContext ctx, IR.VM.Return _) + { + ctx.IL.Emit(Emit.OpCodes.Ret); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/functional/IFunctionalCodeContext.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/functional/IFunctionalCodeContext.cs new file mode 100644 index 00000000..aa6d8a66 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/functional/IFunctionalCodeContext.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + public interface IFunctionalCodeContext + : ICodeContext + { + public IR.Function Function { get; } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/modular/ModularCodeCompiler.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/modular/ModularCodeCompiler.cs new file mode 100644 index 00000000..87529349 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/modular/ModularCodeCompiler.cs @@ -0,0 +1,23 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal static partial class CodeCompiler_Impl + { + public static void Compile(ICodeContext ctx, IR.VM.GetGlobal get) + { + var global = ctx.Runtime.ImportGlobal(get.Global); + + ctx.IL.Emit(Emit.OpCodes.Ldsfld, global); + + ctx.Stack.Put(global.FieldType); + } + + public static void Compile(ICodeContext ctx, IR.VM.SetGlobal set) + { + var global = ctx.Runtime.ImportGlobal(set.Global); + + ctx.IL.Emit(IL.Emit.OpCodes.Stsfld, global); + + ctx.Stack.Pop(global.FieldType); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/object/OOPCodeCompiler.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/object/OOPCodeCompiler.cs new file mode 100644 index 00000000..d760beb8 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/object/OOPCodeCompiler.cs @@ -0,0 +1,59 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal static partial class CodeCompiler_Impl + { + public static void Compile(ICodeContext ctx, IR.VM.CallVirtual callVirtual) + { + var method = ctx.Runtime.ImportMethodReference(callVirtual.Method); + + if (!method.IsVirtual && !method.IsAbstract) + throw new($"Method {method} is not virtual or abstract!"); + + ctx.IL.Emit(Emit.OpCodes.Callvirt, method); + + if (method.ReturnType != typeof(void)) + ctx.Stack.Put(method.ReturnType); + } + + public static void Compile(ICodeContext ctx, IR.VM.CastReference castReference) + { + var targetType = ctx.Runtime.ImportType(castReference.Type); + + ctx.IL.Emit(Emit.OpCodes.Isinst, targetType); + + ctx.Stack.Pop(); + ctx.Stack.Put(targetType); + } + + public static void Compile(ICodeContext ctx, IR.VM.CreateInstance createInstance) + { + var constructor = ctx.Runtime.ImportConstructorReference(createInstance.Constructor); + + ctx.IL.Emit(Emit.OpCodes.Newobj, constructor); + + ctx.Stack.Put(constructor.DeclaringType ?? throw new()); + } + + public static void Compile(ICodeContext ctx, IR.VM.GetField get) + { + var field = ctx.Runtime.ImportFieldReference(get.Field); + + ctx.IL.Emit(field.IsStatic ? Emit.OpCodes.Ldsfld : Emit.OpCodes.Ldfld, field); + + if (!field.IsStatic) + ctx.Stack.Pop(field.DeclaringType ?? throw new()); + ctx.Stack.Put(field.FieldType); + } + + public static void Compile(ICodeContext ctx, IR.VM.SetField set) + { + var field = ctx.Runtime.ImportFieldReference(set.Field); + + ctx.IL.Emit(field.IsStatic ? Emit.OpCodes.Stsfld : Emit.OpCodes.Stfld, field); + + ctx.Stack.Pop(); + if (!field.IsStatic) + ctx.Stack.Pop(field.DeclaringType ?? throw new()); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/code/code/stack/StackCodeCompiler.cs b/ZSharp.Platform.Runtime/loader/loaders/code/code/stack/StackCodeCompiler.cs new file mode 100644 index 00000000..f59eba5d --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/code/code/stack/StackCodeCompiler.cs @@ -0,0 +1,82 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal static partial class CodeCompiler_Impl + { + public static void Compile(ICodeContext ctx, IR.VM.Dup _) + { + ctx.IL.Emit(IL.Emit.OpCodes.Dup); + + ctx.Stack.Dup(); + } + + public static void Compile(ICodeContext ctx, IR.VM.IsNotNull _) + { + ctx.IL.Emit(IL.Emit.OpCodes.Ldnull); + ctx.IL.Emit(IL.Emit.OpCodes.Cgt_Un); + + ctx.Stack.Pop(); + ctx.Stack.Put(typeof(bool)); + } + + public static void Compile(ICodeContext ctx, IR.VM.IsNull _) + { + ctx.IL.Emit(IL.Emit.OpCodes.Ldnull); + ctx.IL.Emit(IL.Emit.OpCodes.Ceq); + + ctx.Stack.Pop(); + ctx.Stack.Put(typeof(bool)); + } + + public static void Compile(ICodeContext ctx, IR.VM.Nop _) + { + ctx.IL.Emit(IL.Emit.OpCodes.Nop); + } + + public static void Compile(ICodeContext ctx, IR.VM.Pop _) + { + ctx.IL.Emit(IL.Emit.OpCodes.Pop); + + ctx.Stack.Pop(); + } + + public static void Compile(ICodeContext ctx, IR.VM.PutBoolean put) + { + ctx.IL.Emit(put.Value ? IL.Emit.OpCodes.Ldc_I4_1 : IL.Emit.OpCodes.Ldc_I4_0); + + ctx.Stack.Put(typeof(bool)); + } + + public static void Compile(ICodeContext ctx, IR.VM.PutFloat32 put) + { + ctx.IL.Emit(IL.Emit.OpCodes.Ldc_R4, put.Value); + + ctx.Stack.Put(typeof(float)); + } + + public static void Compile(ICodeContext ctx, IR.VM.PutInt32 put) + { + ctx.IL.Emit(IL.Emit.OpCodes.Ldc_I4, put.Value); + + ctx.Stack.Put(typeof(int)); + } + + public static void Compile(ICodeContext ctx, IR.VM.PutNull _) + { + ctx.IL.Emit(IL.Emit.OpCodes.Ldnull); + + ctx.Stack.Put(typeof(object)); + } + + public static void Compile(ICodeContext ctx, IR.VM.PutString put) + { + ctx.IL.Emit(IL.Emit.OpCodes.Ldstr, put.Value); + + ctx.Stack.Put(typeof(string)); + } + + public static void Compile(ICodeContext ctx, IR.VM.Swap _) + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/enum/EnumClassLoader.cs b/ZSharp.Platform.Runtime/loader/loaders/enum/EnumClassLoader.cs new file mode 100644 index 00000000..e5806b40 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/enum/EnumClassLoader.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal sealed partial class EnumClassLoader(EmitLoader loader) + : TypeLoaderBase(loader) + { + + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.Method.cs b/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.Method.cs new file mode 100644 index 00000000..26eb80b6 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.Method.cs @@ -0,0 +1,38 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class EnumClassLoader + { + private void LoadMethod(IR.Method method) + { + var attributes = IL.MethodAttributes.Public; + + if (method.IsStatic) + attributes |= IL.MethodAttributes.Static; + if (method.IsVirtual) + attributes |= IL.MethodAttributes.Virtual | IL.MethodAttributes.NewSlot; + + var result = ILType.DefineMethod( + method.Name ?? string.Empty, + attributes, + Loader.Runtime.ImportType(method.ReturnType), + [.. ( + method.IsInstance || method.IsVirtual + ? method.Signature.GetParameters().Skip(1) + : method.Signature.GetParameters() + ).Select(p => Loader.Runtime.ImportType(p.Type)) + ] + ); + + Loader.Runtime.AddFunction(method.UnderlyingFunction, result); + + var context = FunctionCodeContext.From(Loader.Runtime, result, method.UnderlyingFunction); + + foreach (var local in method.Body.Locals) + result.GetILGenerator().DeclareLocal(Loader.Runtime.ImportType(local.Type)); + + var codeLoader = new CodeCompiler(context); + + AddTask(() => codeLoader.CompileCode(method.Body.Instructions)); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.Type.cs b/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.Type.cs new file mode 100644 index 00000000..1b260c59 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.Type.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class EnumClassLoader + { + private void LoadNestedType(IR.TypeDefinition type) + { + TypeLoaderHelper.LoadType(Loader, ILType, type); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.Value.cs b/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.Value.cs new file mode 100644 index 00000000..56c69b7f --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.Value.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class EnumClassLoader + { + private void LoadValue(IR.EnumValue value) + { + var il = ILType.DefineField( + value.Name, + ILType, + IL.FieldAttributes.Public | IL.FieldAttributes.Static + ); + + // TODO: add caching when adding IR instruction for loading enum value + //Loader.Runtime.AddField(value, il); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.cs b/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.cs new file mode 100644 index 00000000..b672abc8 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/enum/load/EnumClassLoader.Load.cs @@ -0,0 +1,49 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class EnumClassLoader + { + protected override void DoLoad() + { + LoadAll(); + } + + private void LoadAll() + { + CreateValueField(); + + LoadNestedTypes(); + + AddTask(LoadValues); + + AddTask(LoadMethods); + } + + private void CreateValueField() + { + ILType.DefineField( + "__value", + Loader.Runtime.ImportType(IRType.Type), + IL.FieldAttributes.Public | IL.FieldAttributes.SpecialName | IL.FieldAttributes.RTSpecialName + ); + } + + private void LoadNestedTypes() + { + //foreach (var type in IRType.NestedTypes) + // LoadNestedType(type); + } + + private void LoadValues() + { + foreach (var value in IRType.Values) + LoadValue(value); + } + + private void LoadMethods() + { + //if (IRType.HasMethods) + // foreach (var method in IRType.Methods) + // LoadMethod(method); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/interface/InterfaceLoader.Context.cs b/ZSharp.Platform.Runtime/loader/loaders/interface/InterfaceLoader.Context.cs new file mode 100644 index 00000000..6f780de9 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/interface/InterfaceLoader.Context.cs @@ -0,0 +1,9 @@ +using CommonZ.Utils; + +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class InterfaceLoader + { + private Cache? genericTypeContext; + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/interface/InterfaceLoader.Tasks.cs b/ZSharp.Platform.Runtime/loader/loaders/interface/InterfaceLoader.Tasks.cs new file mode 100644 index 00000000..6b653549 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/interface/InterfaceLoader.Tasks.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class InterfaceLoader + { + protected override void AddTask(Action task) + { + if (genericTypeContext is not null) + { + var originalTask = task; + task = () => + { + using (Loader.Runtime.TypeContext(genericTypeContext)) + originalTask(); + }; + } + + base.AddTask(task); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/interface/InterfaceLoader.cs b/ZSharp.Platform.Runtime/loader/loaders/interface/InterfaceLoader.cs new file mode 100644 index 00000000..29f36957 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/interface/InterfaceLoader.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal sealed partial class InterfaceLoader(EmitLoader loader) + : TypeLoaderBase(loader) + { + + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.Generic.cs b/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.Generic.cs new file mode 100644 index 00000000..547ea5aa --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.Generic.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class InterfaceLoader + { + private void LoadGenericParameters() + { + if (!IRType.HasGenericParameters) return; + + var ils = ILType.DefineGenericParameters( + [ + .. IRType.GenericParameters + .Select(p => p.Name) + ] + ); + + foreach (var (ir, il) in IRType.GenericParameters.Zip(ils)) + Loader.Runtime.AddType(ir, il); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.Method.cs b/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.Method.cs new file mode 100644 index 00000000..fb009903 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.Method.cs @@ -0,0 +1,38 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class InterfaceLoader + { + private void LoadMethod(IR.Method method) + { + var attributes = IL.MethodAttributes.Public; + + if (method.IsStatic) + attributes |= IL.MethodAttributes.Static; + if (method.IsVirtual) + attributes |= IL.MethodAttributes.Virtual | IL.MethodAttributes.NewSlot; + + var result = ILType.DefineMethod( + method.Name ?? string.Empty, + attributes, + Loader.Runtime.ImportType(method.ReturnType), + [.. ( + method.IsInstance || method.IsVirtual + ? method.Signature.GetParameters().Skip(1) + : method.Signature.GetParameters() + ).Select(p => Loader.Runtime.ImportType(p.Type)) + ] + ); + + Loader.Runtime.AddFunction(method.UnderlyingFunction, result); + + var context = FunctionCodeContext.From(Loader.Runtime, result, method.UnderlyingFunction); + + foreach (var local in method.Body.Locals) + result.GetILGenerator().DeclareLocal(Loader.Runtime.ImportType(local.Type)); + + var codeLoader = new CodeCompiler(context); + + AddTask(() => codeLoader.CompileCode(method.Body.Instructions)); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.Type.cs b/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.Type.cs new file mode 100644 index 00000000..7611fb04 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.Type.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class InterfaceLoader + { + private void LoadNestedType(IR.TypeDefinition type) + { + TypeLoaderHelper.LoadType(Loader, ILType, type); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.cs b/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.cs new file mode 100644 index 00000000..2a1edebc --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/interface/load/InterfaceLoader.Load.cs @@ -0,0 +1,49 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class InterfaceLoader + { + protected override void DoLoad() + { + if (IRType.HasGenericParameters) + genericTypeContext = Loader.Runtime.NewTypeContext(); + + if (genericTypeContext is not null) + using (Loader.Runtime.TypeContext(genericTypeContext)) + LoadAll(); + else + LoadAll(); + } + + private void LoadAll() + { + LoadGenericParameters(); + + LoadNestedTypes(); + + AddTask(LoadBases); + + AddTask(LoadMethods); + } + + private void LoadBases() + { + if (IRType.HasBases) + foreach (var @base in IRType.Bases) + ILType.AddInterfaceImplementation(Loader.Runtime.ImportType(@base)); + } + + private void LoadNestedTypes() + { + throw new NotSupportedException(); + //foreach (var type in IRType.NestedTypes) + // LoadNestedType(type); + } + + private void LoadMethods() + { + if (IRType.HasMethods) + foreach (var method in IRType.Methods) + LoadMethod(method); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/module/ModuleLoader.Tasks.cs b/ZSharp.Platform.Runtime/loader/loaders/module/ModuleLoader.Tasks.cs new file mode 100644 index 00000000..36f6dd85 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/module/ModuleLoader.Tasks.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ModuleLoader + { + private readonly TaskManager tasks; + + private void AddTask(Action task) + => tasks.AddTask(task); + + private void RunUntilComplete() + => tasks.RunUntilComplete(); + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/module/ModuleLoader.cs b/ZSharp.Platform.Runtime/loader/loaders/module/ModuleLoader.cs new file mode 100644 index 00000000..3f2c03b8 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/module/ModuleLoader.cs @@ -0,0 +1,28 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal sealed partial class ModuleLoader + : LoaderBase + { + public Emit.AssemblyBuilder AssemblyBuilder { get; private init; } + + public Emit.ModuleBuilder ILModule { get; } + + public Emit.TypeBuilder Globals { get; } + + public IR.Module IRModule { get; } + + public ModuleLoader(EmitLoader loader, IR.Module module) + : base(loader) + { + IRModule = module; + AssemblyBuilder ??= Emit.AssemblyBuilder.DefineDynamicAssembly( + new IL.AssemblyName(IRModule.Name ?? throw new()), + Emit.AssemblyBuilderAccess.RunAndCollect + ); + ILModule = AssemblyBuilder.DefineDynamicModule(IRModule.Name ?? throw new()); + Globals = ILModule.DefineType(""); + + tasks = new(LoadAll); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.Function.cs b/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.Function.cs new file mode 100644 index 00000000..85739f44 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.Function.cs @@ -0,0 +1,34 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ModuleLoader + { + public void LoadFunction(IR.Function function) + { + var returnType = Loader.Runtime.ImportType(function.ReturnType); + var parameterTypes = function + .Signature + .GetParameters() + .Select(p => p.Type) + .Select(Loader.Runtime.ImportType) + .ToArray(); + + var method = Globals.DefineMethod( + function.Name ?? "", + IL.MethodAttributes.Static | IL.MethodAttributes.Public, + returnType, + parameterTypes + ); + + Loader.Runtime.AddFunction(function, method); + + foreach (var (i, parameter) in function.Signature.GetParameters().Select((v, i) => (i, v))) + method.DefineParameter(i + 1, IL.ParameterAttributes.None, parameter.Name); + + AddTask(() => + { + var codeLoader = new CodeCompiler(FunctionCodeContext.From(Loader.Runtime, method, function)); + codeLoader.CompileCode(function.Body.Instructions); + }); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.Global.cs b/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.Global.cs new file mode 100644 index 00000000..3478b4d5 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.Global.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ModuleLoader + { + private void LoadGlobal(IR.Global global) + { + var field = Globals.DefineField( + global.Name, + Loader.Runtime.ImportType(global.Type), + IL.FieldAttributes.Public | IL.FieldAttributes.Static + ); + + Loader.Runtime.AddGlobal(global, field); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.Type.cs b/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.Type.cs new file mode 100644 index 00000000..5e164f53 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.Type.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ModuleLoader + { + public void LoadType(IR.TypeDefinition type) + => TypeLoaderHelper.LoadType(Loader, ILModule, type); + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.cs b/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.cs new file mode 100644 index 00000000..a0cb03d7 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/module/load/ModuleLoader.Load.cs @@ -0,0 +1,73 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ModuleLoader + { + public IL.Module Load() + { + RunUntilComplete(); + + Globals.CreateType(); + + return ILModule; + } + + private void LoadAll() + { + LoadTypes(); + + LoadGlobals(); + + LoadFunctions(); + + LoadInitializer(); + } + + private void LoadTypes() + { + if (IRModule.HasTypes) + foreach (var type in IRModule.Types) + LoadType(type); + } + + private void LoadGlobals() + { + if (IRModule.HasGlobals) + foreach (var global in IRModule.Globals) + LoadGlobal(global); + } + + private void LoadFunctions() + { + if (IRModule.HasFunctions) + foreach (var function in IRModule.Functions) + LoadFunction(function); + } + + private void LoadInitializer() + { + if (IRModule.Initializer is null) return; + + var typeInitializer = Globals.DefineTypeInitializer(); + + var initializationFunction = Loader.Runtime.ImportFunction(IRModule.Initializer); + + if (!initializationFunction.IsStatic) + throw new InvalidProgramException( + $"Module's {ILModule.Name} initializer function must be static" + ); + if (initializationFunction.ReturnType != typeof(void)) + throw new InvalidProgramException( + $"Module's {ILModule.Name} initializer function must return void" + ); + if (initializationFunction.GetParameters().Length != 0) + throw new InvalidProgramException( + $"Module's {ILModule.Name} initializer function must not have any parameters" + ); + + var il = typeInitializer.GetILGenerator(); + + il.Emit(Emit.OpCodes.Call, initializationFunction); + il.Emit(Emit.OpCodes.Ret); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.Context.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.Context.cs new file mode 100644 index 00000000..01cb52e8 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.Context.cs @@ -0,0 +1,9 @@ +using CommonZ.Utils; + +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ValueTypeLoader + { + private Cache? genericTypeContext; + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.T.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.T.cs new file mode 100644 index 00000000..91f66e3e --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ValueTypeLoader + { + + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.Tasks.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.Tasks.cs new file mode 100644 index 00000000..463e5874 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.Tasks.cs @@ -0,0 +1,22 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ValueTypeLoader + { + public required TaskManager Tasks { get; init; } + + private void AddTask(Action task) + { + if (genericTypeContext is not null) + { + var originalTask = task; + task = () => + { + using (Loader.Runtime.TypeContext(genericTypeContext)) + originalTask(); + }; + } + + Tasks.AddTask(task); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.cs new file mode 100644 index 00000000..bdbf8394 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/ValueTypeLoader.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + internal sealed partial class ValueTypeLoader + : LoaderBase + { + public required Emit.TypeBuilder ILType { get; init; } + + public required IR.ValueType IRType { get; init; } + + public ValueTypeLoader(EmitLoader loader) + : base(loader) + { + + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Constructor.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Constructor.cs new file mode 100644 index 00000000..059494ed --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Constructor.cs @@ -0,0 +1,22 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ValueTypeLoader + { + private void LoadConstructor(IR.Constructor constructor) + { + var result = ILType.DefineConstructor( + IL.MethodAttributes.Public, + IL.CallingConventions.HasThis, + [.. constructor.Method.Signature.GetParameters().Skip(1).Select(p => Loader.Runtime.ImportType(p.Type))] + ); + + Loader.Runtime.AddFunction(constructor.Method.UnderlyingFunction, result); + + var context = FunctionCodeContext.From(Loader.Runtime, result, constructor.Method.UnderlyingFunction); + + var codeLoader = new CodeCompiler(context); + + AddTask(() => codeLoader.CompileCode(constructor.Method.Body.Instructions)); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Field.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Field.cs new file mode 100644 index 00000000..4a00059d --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Field.cs @@ -0,0 +1,17 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ValueTypeLoader + { + private void LoadField(IR.Field field) + { + var attributes = IL.FieldAttributes.Public; + + if (field.IsStatic) + attributes |= IL.FieldAttributes.Static; + + var il = ILType.DefineField(field.Name, Loader.Runtime.ImportType(field.Type), attributes); + + Loader.Runtime.AddField(field, il); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Generic.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Generic.cs new file mode 100644 index 00000000..4c46cd20 --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Generic.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ValueTypeLoader + { + private void LoadGenericParameters() + { + //if (!IRType.HasGenericParameters) return; + + //var ils = ILType.DefineGenericParameters( + // [ + // .. IRType.GenericParameters + // .Select(p => p.Name) + // ] + //); + + //foreach (var (ir, il) in IRType.GenericParameters.Zip(ils)) + // Loader.Runtime.AddType(ir, il); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Method.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Method.cs new file mode 100644 index 00000000..0b780e3b --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Method.cs @@ -0,0 +1,38 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ValueTypeLoader + { + private void LoadMethod(IR.Method method) + { + var attributes = IL.MethodAttributes.Public; + + if (method.IsStatic) + attributes |= IL.MethodAttributes.Static; + if (method.IsVirtual) + attributes |= IL.MethodAttributes.Virtual | IL.MethodAttributes.NewSlot; + + var result = ILType.DefineMethod( + method.Name ?? string.Empty, + attributes, + Loader.Runtime.ImportType(method.ReturnType), + [.. ( + method.IsInstance || method.IsVirtual + ? method.Signature.GetParameters().Skip(1) + : method.Signature.GetParameters() + ).Select(p => Loader.Runtime.ImportType(p.Type)) + ] + ); + + Loader.Runtime.AddFunction(method.UnderlyingFunction, result); + + var context = FunctionCodeContext.From(Loader.Runtime, result, method.UnderlyingFunction); + + foreach (var local in method.Body.Locals) + result.GetILGenerator().DeclareLocal(Loader.Runtime.ImportType(local.Type)); + + var codeLoader = new CodeCompiler(context); + + AddTask(() => codeLoader.CompileCode(method.Body.Instructions)); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Type.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Type.cs new file mode 100644 index 00000000..6701addf --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.Type.cs @@ -0,0 +1,10 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ValueTypeLoader + { + private void LoadNestedType(IR.TypeDefinition type) + { + TypeLoaderHelper.LoadType(Loader, ILType, type); + } + } +} diff --git a/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.cs b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.cs new file mode 100644 index 00000000..38a7031e --- /dev/null +++ b/ZSharp.Platform.Runtime/loader/loaders/value type/load/ValueTypeLoader.Load.cs @@ -0,0 +1,61 @@ +namespace ZSharp.Platform.Runtime.Loaders +{ + partial class ValueTypeLoader + { + public Type Load() + { + //if (IRType.HasGenericParameters) + // genericTypeContext = Loader.Runtime.NewTypeContext(); + + if (genericTypeContext is not null) + using (Loader.Runtime.TypeContext(genericTypeContext)) + LoadAll(); + else + LoadAll(); + + ILType.CreateType(); + + return ILType; + } + + private void LoadAll() + { + LoadGenericParameters(); + + LoadNestedTypes(); + + AddTask(LoadFields); + + AddTask(LoadConstructors); + + AddTask(LoadMethods); + } + + private void LoadNestedTypes() + { + //foreach (var type in IRType.NestedTypes) + // LoadNestedType(type); + } + + private void LoadFields() + { + //if (IRType.HasFields) + // foreach (var field in IRType.Fields) + // LoadField(field); + } + + private void LoadMethods() + { + //if (IRType.HasMethods) + // foreach (var method in IRType.Methods) + // LoadMethod(method); + } + + private void LoadConstructors() + { + //if (IRType.HasConstructors) + // foreach (var constructor in IRType.Constructors) + // LoadConstructor(constructor); + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/Runtime.Evaluate.cs b/ZSharp.Platform.Runtime/runtime/Runtime.Evaluate.cs new file mode 100644 index 00000000..85b5b3e0 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/Runtime.Evaluate.cs @@ -0,0 +1,19 @@ +using CommonZ.Utils; + +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public object? Evaluate( + Collection code, + IR.IType type, + IEvaluationContext? evaluationContext = null + ) + { + return Loader.LoadCode( + code, type, + evaluationContext ?? EvaluationContextFactory.CreateEvaluationContext() + ).DynamicInvoke(null); + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/Runtime.Expose.cs b/ZSharp.Platform.Runtime/runtime/Runtime.Expose.cs new file mode 100644 index 00000000..1b603357 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/Runtime.Expose.cs @@ -0,0 +1,75 @@ +using CommonZ.Utils; +using System.Diagnostics.CodeAnalysis; +using ZSharp.IR; + +namespace ZSharp.Platform.Runtime +{ + public sealed partial class Runtime + { + private readonly List _exposedObjects = []; + private readonly Queue _avialableHandles = []; + + private Class ir_runtimeType; + + private Global ir_runtimeInstance; + + private Method ir_getExposedObjectFunction; + + public ExposedObjectHandle CreateHandle(object obj) + { + if (obj is null) + throw new ArgumentNullException(nameof(obj), "Cannot create a handle for a null object."); + + ExposedObjectHandle handle = _exposedObjects.Count; + + if (_avialableHandles.Count > 0) + handle = _avialableHandles.Dequeue(); + else _exposedObjects.Add(null!); + + _exposedObjects[handle] = obj; + + return handle; + } + + public void DestroyHandle(ExposedObjectHandle handle) + { + if (handle < 0 || handle >= _exposedObjects.Count) + throw new ArgumentOutOfRangeException(nameof(handle), "Invalid exposed object handle."); + _exposedObjects[handle] = null!; + _avialableHandles.Enqueue(handle); + } + + public Collection Expose(object? obj) + { + if (obj is null) + return [ + new IR.VM.PutNull() + ]; + + var handle = CreateHandle(obj); + + return [ + new IR.VM.GetGlobal(ir_runtimeInstance), + new IR.VM.PutInt32(handle), + new IR.VM.Call(ir_getExposedObjectFunction), + ]; + } + + public object GetExposedObject(ExposedObjectHandle handle) + => _exposedObjects[handle]!; + + [MemberNotNull(nameof(ir_runtimeType), nameof(ir_getExposedObjectFunction), nameof(ir_runtimeInstance))] + private void SetupExposeSystem() + { + ir_runtimeType = new("Runtime"); + ir_runtimeType.Methods.Add(ir_getExposedObjectFunction = new(TypeSystem.Object)); + ir_getExposedObjectFunction.Signature.Args.Parameters.Add(new("this", new ClassReference(ir_runtimeType))); + ir_getExposedObjectFunction.Signature.Args.Parameters.Add(new("handle", TypeSystem.SInt32)); + ir_runtimeInstance = new("Runtime.Instance", new ClassReference(ir_runtimeType)); + + _typeDefCache[ir_runtimeType] = typeof(Runtime); + _functionCache.Add(ir_getExposedObjectFunction.UnderlyingFunction, ((Delegate)GetExposedObject).Method); + _globalCache[ir_runtimeInstance] = typeof(Runtime).GetField(nameof(_instance)) ?? throw new("Internal error"); + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/Runtime.Loader.cs b/ZSharp.Platform.Runtime/runtime/Runtime.Loader.cs new file mode 100644 index 00000000..afa7f54e --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/Runtime.Loader.cs @@ -0,0 +1,9 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public IEvaluationContextFactory EvaluationContextFactory { get; } + + public Loaders.EmitLoader Loader { get; } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/Runtime.Singleton.cs b/ZSharp.Platform.Runtime/runtime/Runtime.Singleton.cs new file mode 100644 index 00000000..15601c6a --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/Runtime.Singleton.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public static Runtime _instance = null!; + } +} diff --git a/ZSharp.Platform.Runtime/runtime/Runtime.TypeSystem.cs b/ZSharp.Platform.Runtime/runtime/Runtime.TypeSystem.cs new file mode 100644 index 00000000..e5833ad6 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/Runtime.TypeSystem.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public TypeSystem TypeSystem { get; } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/Runtime.cs b/ZSharp.Platform.Runtime/runtime/Runtime.cs new file mode 100644 index 00000000..b5132fb4 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/Runtime.cs @@ -0,0 +1,38 @@ +namespace ZSharp.Platform.Runtime +{ + public sealed partial class Runtime + { + public bool DebugEnabled { get; } + + public Runtime(TypeSystem typeSystem) + { + if (_instance is not null) + throw new InvalidOperationException("Runtime instance already exists."); + _instance = this; + + EvaluationContextFactory = + (DebugEnabled = !true) + ? new DebuggableEvaluationContextFactory() + { + OutputPath = Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(), "generated")).FullName + } + : new ExecutionEvaluationContextFactory() + ; + + TypeSystem = typeSystem; + + SetupExposeSystem(); + + Loader = new(this); + + foreach (var (ir, il) in (IEnumerable<(IR.TypeReference, Type)>)[ + (TypeSystem.Void, typeof(void)), + (TypeSystem.Boolean, typeof(bool)), + (TypeSystem.Object, typeof(object)), + (TypeSystem.String, typeof(string)), + (TypeSystem.SInt32, typeof(int)), + ]) + _typeDefCache.Add(ir.Definition, il); + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Field.cs b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Field.cs new file mode 100644 index 00000000..30342be1 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Field.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + private readonly Dictionary _fieldCache = []; + + public void AddField(IR.Field ir, IL.FieldInfo il) + => _fieldCache.Add(ir, il); + + public void DelField(IR.Field ir) + => _fieldCache.Remove(ir); + + public void SetField(IR.Field ir, IL.FieldInfo il) + => _fieldCache[ir] = il; + } +} diff --git a/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Function.cs b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Function.cs new file mode 100644 index 00000000..888b7d0a --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Function.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + private readonly Dictionary _functionCache = []; + + public void AddFunction(IR.Function ir, IL.MethodBase il) + => _functionCache.Add(ir, il); + + public void DelFunction(IR.Function ir) + => _functionCache.Remove(ir); + + public void SetFunction(IR.Function ir, IL.MethodBase il) + => _functionCache[ir] = il; + } +} diff --git a/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Global.cs b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Global.cs new file mode 100644 index 00000000..7e44db5a --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Global.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + private readonly Dictionary _globalCache = []; + + public void AddGlobal(IR.Global ir, IL.FieldInfo il) + => _globalCache.Add(ir, il); + + public void DelGlobal(IR.Global ir) + => _globalCache.Remove(ir); + + public void SetGlobal(IR.Global ir, IL.FieldInfo il) + => _globalCache[ir] = il; + } +} diff --git a/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Module.cs b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Module.cs new file mode 100644 index 00000000..c695a315 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Module.cs @@ -0,0 +1,16 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + private readonly Dictionary _moduleCache = []; + + public void AddModule(IR.Module ir, IL.Module il) + => _moduleCache.Add(ir, il); + + public void DelModule(IR.Module ir) + => _moduleCache.Remove(ir); + + public void SetModule(IR.Module ir, IL.Module il) + => _moduleCache[ir] = il; + } +} diff --git a/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Type.cs b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Type.cs new file mode 100644 index 00000000..720369da --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/cache/Runtime.Cache.Type.cs @@ -0,0 +1,40 @@ +using CommonZ.Utils; + +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + private Cache _typeCache = []; + private readonly Dictionary _typeDefCache = []; + + public Cache NewTypeContext() + => new() { Parent = _typeCache }; + + public ContextManager TypeContext(Cache? context = null) + { + context ??= NewTypeContext(); + + (_typeCache, context) = (context, _typeCache); + + return new(() => _typeCache = context); + } + + public void AddType(IR.IType ir, Type il) + => SetType(ir, il); + + public void DelType(IR.IType ir) + => _typeCache.Uncache(ir); + + public void SetType(IR.IType ir, Type il) + => _typeCache.Cache(ir, il); + + public void AddTypeDefinition(IR.TypeDefinition ir, Type il) + => _typeDefCache.Add(ir, il); + + public void DelTypeDefinition(IR.TypeDefinition ir) + => _typeDefCache.Remove(ir); + + public void SetTypeDefinition(IR.TypeDefinition ir, Type il) + => _typeDefCache[ir] = il; + } +} diff --git a/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Callable.cs b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Callable.cs new file mode 100644 index 00000000..777e6913 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Callable.cs @@ -0,0 +1,19 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public IL.MethodBase ImportCallable(IR.ICallable callable) + => callable switch + { + IR.ConstructorReference target => ImportConstructorReference(target), + IR.Method target => ImportMethod(target), + IR.MethodReference target => ImportMethodReference(target), + IR.Function target => ImportFunction(target), + IR.ConstructedFunction target => ImportConstructedFunction(target), + _ => throw new ArgumentException( + $"Invalid callable type: {callable.GetType()}", + nameof(callable) + ) + }; + } +} diff --git a/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Constructor.cs b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Constructor.cs new file mode 100644 index 00000000..ea5ac412 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Constructor.cs @@ -0,0 +1,45 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public IL.ConstructorInfo ImportConstructor(IR.Constructor constructor) + { + var function = constructor.Method.UnderlyingFunction; + if (!_functionCache.TryGetValue(function, out var result)) + throw new InvalidOperationException( + $"Constructor{' ' + constructor.Name ?? string.Empty} in type {constructor.Method.Owner} is not loaded" + ); + if (result is not IL.ConstructorInfo info) + throw new InvalidOperationException(); + + return info; + } + + public IL.ConstructorInfo ImportConstructorReference(IR.ConstructorReference @ref) + { + var type = ImportType(@ref.OwningType); + + var def = ImportConstructor(@ref.Constructor); + + if (!type.IsGenericType) + return def; + + if (type.GetGenericTypeDefinition() is Emit.TypeBuilder typeBuilder) + if (!typeBuilder.IsCreated()) + return Emit.TypeBuilder.GetConstructor(type, def); + try + { + def = (IL.ConstructorInfo)(IL.MethodBase.GetMethodFromHandle( + def.MethodHandle, + type.TypeHandle + ) ?? throw new("Could not create constructor from method handle")); + } + catch (NotSupportedException) + { + def = Emit.TypeBuilder.GetConstructor(type, def); + } + + return def; + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Field.cs b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Field.cs new file mode 100644 index 00000000..f15fb04f --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Field.cs @@ -0,0 +1,34 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public IL.FieldInfo ImportField(IR.Field field) + { + if (!_fieldCache.TryGetValue(field, out var result)) + throw new InvalidOperationException( + $"Field {field.Name} in type {field.Owner?.Name ?? ""} is not loaded" + ); + + return result; + } + + public IL.FieldInfo ImportFieldReference(IR.FieldReference @ref) + { + var type = ImportType(@ref.OwningType); + + var def = ImportField(@ref.Field); + + if (!type.IsGenericType) + return def; + + if (type.GetGenericTypeDefinition() is Emit.TypeBuilder typeBuilder) + if (!typeBuilder.IsCreated()) + return Emit.TypeBuilder.GetField(type, def); + + return IL.FieldInfo.GetFieldFromHandle( + def.FieldHandle, + type.TypeHandle + ); + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Function.cs b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Function.cs new file mode 100644 index 00000000..fce1ab49 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Function.cs @@ -0,0 +1,28 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public IL.MethodInfo ImportFunction(IR.Function function) + { + if (!_functionCache.TryGetValue(function, out var result)) + result = _functionCache[function] = LoadFunction(function); + if (result is not IL.MethodInfo info) + throw new InvalidOperationException(); + + if (info.DeclaringType is IL.Emit.TypeBuilder typeBuilder) + info = info.DeclaringType.GetMethod( + info.Name, + [.. info.GetParameters().Select(p => p.ParameterType) ] + ) ?? throw new(); + + return info; + } + + public IL.MethodInfo ImportConstructedFunction(IR.ConstructedFunction constructedFunction) + { + var def = ImportFunction(constructedFunction.Function); + + return def.MakeGenericMethod([.. constructedFunction.Arguments.Select(ImportType)]); + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Global.cs b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Global.cs new file mode 100644 index 00000000..07920877 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Global.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public IL.FieldInfo ImportGlobal(IR.Global global) + { + if (!_globalCache.TryGetValue(global, out var result)) + throw new InvalidOperationException( + $"Global {global.Name} in module {global.Module?.Name ?? ""} is not loaded" + ); + + return result; + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Method.cs b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Method.cs new file mode 100644 index 00000000..bd7677fb --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Method.cs @@ -0,0 +1,41 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public IL.MethodInfo ImportMethod(IR.Method method) + => ImportFunction(method.UnderlyingFunction); + + public IL.MethodInfo ImportMethodReference(IR.MethodReference @ref) + { + var type = ImportType(@ref.OwningType); + + var def = ImportMethod(@ref.Method); + + if (type.IsGenericType) + if (type.GetGenericTypeDefinition() is IL.Emit.TypeBuilder typeBuilder) + { + if (!typeBuilder.IsCreated()) + def = Emit.TypeBuilder.GetMethod(type, def); + } + else + try + { + def = (IL.MethodInfo)(IL.MethodBase.GetMethodFromHandle( + def.MethodHandle, + type.TypeHandle + ) ?? throw new("Could not create method from method handle")); + } + catch (NotSupportedException) + { + def = Emit.TypeBuilder.GetMethod(type, def); + } + + if (@ref is IR.ConstructedMethod constructed) + def = def.MakeGenericMethod([ + .. constructed.Arguments.Select(ImportType) + ]); + + return def; + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Module.cs b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Module.cs new file mode 100644 index 00000000..8b7e4db1 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Module.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public IL.Module ImportModule(IR.Module module) + { + if (!_moduleCache.TryGetValue(module, out var result)) + result = _moduleCache[module] = LoadModule(module); + + return result; + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Type.Modified.cs b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Type.Modified.cs new file mode 100644 index 00000000..cdcd9cd4 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Type.Modified.cs @@ -0,0 +1,29 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + private Type ImportArrayType(IR.TypeReference @ref) + { + var con = (IR.ConstructedType)@ref; + var elementType = ImportType(con.Arguments[0]); + + return elementType.MakeArrayType(); + } + + private Type ImportPointerType(IR.TypeReference @ref) + { + var con = (IR.ConstructedType)@ref; + var elementType = ImportType(con.Arguments[0]); + + return elementType.MakePointerType(); + } + + private Type ImportReferenceType(IR.TypeReference @ref) + { + var con = (IR.ConstructedType)@ref; + var elementType = ImportType(con.Arguments[0]); + + return elementType.MakeByRefType(); + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Type.cs b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Type.cs new file mode 100644 index 00000000..b59bc175 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/import/Runtime.Import.Type.cs @@ -0,0 +1,54 @@ +using System.Reflection.Metadata; + +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + public Type ImportType(IR.IType type) + { + if (_typeCache.Cache(type, out var result)) return result; + + return type switch + { + IR.TypeReference reference => ImportTypeReference(reference), + _ => throw new NotImplementedException() + }; + } + + public Type ImportTypeDefinition(IR.TypeDefinition def) + { + if (!_typeDefCache.TryGetValue(def, out var result)) + result = _typeDefCache[def] = LoadType(def); + + return result; + } + + public Type ImportTypeReference(IR.TypeReference @ref) + { + if ( + @ref.Definition == TypeSystem.Array + ) return ImportArrayType(@ref); + if ( + @ref.Definition == TypeSystem.Pointer + ) return ImportPointerType(@ref); + if ( + @ref.Definition == TypeSystem.Reference + ) return ImportReferenceType(@ref); + + var type = ImportTypeDefinition(@ref.Definition); + + List genericArguments = []; + + if (@ref.OwningType is not null) + genericArguments.AddRange(ImportType(@ref.OwningType).GetGenericArguments()); + + if (@ref is IR.ConstructedType constructedType) + genericArguments.AddRange(constructedType.Arguments.Select(ImportType)); + + if (genericArguments.Count == 0) + return type; + + return type.MakeGenericType([.. genericArguments]); + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/load/Runtime.Load.Function.cs b/ZSharp.Platform.Runtime/runtime/load/Runtime.Load.Function.cs new file mode 100644 index 00000000..7bc0bdc9 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/load/Runtime.Load.Function.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + private IL.MethodInfo LoadFunction(IR.Function function) + { + if (function.Module is not null) + throw new InvalidOperationException( + $"Cannot directly load function {function.Name} owned by module {function.Module.Name}" + ); + + return Loader.LoadStandaloneFunction(function); + } + } +} diff --git a/ZSharp.Platform.Runtime/runtime/load/Runtime.Load.Module.cs b/ZSharp.Platform.Runtime/runtime/load/Runtime.Load.Module.cs new file mode 100644 index 00000000..73a70906 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/load/Runtime.Load.Module.cs @@ -0,0 +1,8 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + private IL.Module LoadModule(IR.Module module) + => Loader.LoadModule(module); + } +} diff --git a/ZSharp.Platform.Runtime/runtime/load/Runtime.Load.Type.cs b/ZSharp.Platform.Runtime/runtime/load/Runtime.Load.Type.cs new file mode 100644 index 00000000..7ef706b9 --- /dev/null +++ b/ZSharp.Platform.Runtime/runtime/load/Runtime.Load.Type.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Platform.Runtime +{ + partial class Runtime + { + private Type LoadType(IR.TypeDefinition type) + { + if (type.Module is not null) + throw new InvalidOperationException( + $"Cannot directly load type {type} owned by module {type.Module.Name}" + ); + + return Loader.LoadType(type); + } + } +} diff --git a/ZSharp.Platform.Runtime/tasks/TaskManager.cs b/ZSharp.Platform.Runtime/tasks/TaskManager.cs new file mode 100644 index 00000000..738e0744 --- /dev/null +++ b/ZSharp.Platform.Runtime/tasks/TaskManager.cs @@ -0,0 +1,20 @@ +namespace ZSharp.Platform.Runtime +{ + internal sealed class TaskManager(Action init) + { + private List thisTasks = [init], nextTasks = []; + + public void AddTask(Action task) + => nextTasks.Add(task); + + public void RunUntilComplete() + { + while (thisTasks.Count > 0) + { + foreach (var task in thisTasks) task(); + (thisTasks, nextTasks) = (nextTasks, thisTasks); + nextTasks.Clear(); + } + } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.Array.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.Array.cs new file mode 100644 index 00000000..5115ebdf --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.Array.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeDefinition Array { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.Boolean.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.Boolean.cs new file mode 100644 index 00000000..77e6b15c --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.Boolean.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeReference Boolean { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.Char.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.Char.cs new file mode 100644 index 00000000..b434b984 --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.Char.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeReference Char { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.Float.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.Float.cs new file mode 100644 index 00000000..689854ea --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.Float.cs @@ -0,0 +1,13 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeReference Float16 { get; init; } + + public required IR.TypeReference Float32 { get; init; } + + public required IR.TypeReference Float64 { get; init; } + + public required IR.TypeReference Float128 { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.Object.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.Object.cs new file mode 100644 index 00000000..672cec61 --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.Object.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeReference Object { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.Pointer.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.Pointer.cs new file mode 100644 index 00000000..8411cecd --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.Pointer.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeDefinition Pointer { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.Reference.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.Reference.cs new file mode 100644 index 00000000..f534e91b --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.Reference.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeDefinition Reference { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.SInt.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.SInt.cs new file mode 100644 index 00000000..ccdbaa30 --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.SInt.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeReference SInt8 { get; init; } + + public required IR.TypeReference SInt16 { get; init; } + + public required IR.TypeReference SInt32 { get; init; } + + public required IR.TypeReference SInt64 { get; init; } + + public required IR.TypeReference SIntNative { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.String.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.String.cs new file mode 100644 index 00000000..e5351c6f --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.String.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeReference String { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.UInt.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.UInt.cs new file mode 100644 index 00000000..6254412e --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.UInt.cs @@ -0,0 +1,15 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeReference UInt8 { get; init; } + + public required IR.TypeReference UInt16 { get; init; } + + public required IR.TypeReference UInt32 { get; init; } + + public required IR.TypeReference UInt64 { get; init; } + + public required IR.TypeReference UIntNative { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.Void.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.Void.cs new file mode 100644 index 00000000..cf7b41e4 --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.Void.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + partial class TypeSystem + { + public required IR.TypeReference Void { get; init; } + } +} diff --git a/ZSharp.Platform.Runtime/type system/TypeSystem.cs b/ZSharp.Platform.Runtime/type system/TypeSystem.cs new file mode 100644 index 00000000..822d67c5 --- /dev/null +++ b/ZSharp.Platform.Runtime/type system/TypeSystem.cs @@ -0,0 +1,7 @@ +namespace ZSharp.Platform.Runtime +{ + public sealed partial class TypeSystem + { + + } +} diff --git a/ZSharp.Runtime.IL/GlobalUsings.cs b/ZSharp.Runtime.IL/GlobalUsings.cs deleted file mode 100644 index 8ab48f04..00000000 --- a/ZSharp.Runtime.IL/GlobalUsings.cs +++ /dev/null @@ -1,2 +0,0 @@ -global using IL = System.Reflection; -global using IR = ZSharp.IR; diff --git a/ZSharp.Runtime.IL/Hooks.cs b/ZSharp.Runtime.IL/Hooks.cs deleted file mode 100644 index 5fcb3db8..00000000 --- a/ZSharp.Runtime.IL/Hooks.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Runtime.NET -{ - public sealed class Hooks - { - public IL.MethodInfo GetObject { get; set; } = null!; - } -} diff --git a/ZSharp.Runtime.IL/ICompileTime.cs b/ZSharp.Runtime.IL/ICompileTime.cs deleted file mode 100644 index 3276e52b..00000000 --- a/ZSharp.Runtime.IL/ICompileTime.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Runtime.NET -{ - public interface ICompileTime - { - public Objects.CompilerObject GetCO(); - } -} diff --git a/ZSharp.Runtime.IL/IRCodeEvaluator.cs b/ZSharp.Runtime.IL/IRCodeEvaluator.cs deleted file mode 100644 index f31d59bd..00000000 --- a/ZSharp.Runtime.IL/IRCodeEvaluator.cs +++ /dev/null @@ -1,74 +0,0 @@ -//using ZSharp.Interop.IR2IL; -using ZSharp.Objects; -using ZSharp.Runtime.NET.IR2IL; - -//using IL = System.Reflection.Emit; - - -namespace ZSharp.Runtime.NET -{ - internal sealed class IRCodeEvaluator(Runtime runtime) : Compiler.Evaluator - { - private readonly Runtime runtime = runtime; - - private Interpreter.Interpreter Interpreter => runtime.Interpreter; - - public override CompilerObject Evaluate(CompilerObject @object) - { - if (@object is not RawCode rawCode) - return @object; - - var code = rawCode.Code; - - var module = new IR.Module(""); - - var function = new IR.Function(Interpreter.Compiler.CompileIRType(code.RequireValueType())) - { - Name = "evaluate" - }; - - foreach (var m in code.Instructions - .Select(i => - i is IR.VM.IHasOperand hasOperand - && hasOperand.Operand is IR.IRObject ir - ? ir.Module : null) - .Where(i => i is not null) - ) - Interpreter.Runtime.Import(m!); - - function.Body.Instructions.AddRange([ - .. code.Instructions, - new IR.VM.Return() - ]); - - module.Functions.Add(function); - - var functionIL = runtime.Import(module).GetType("")!.GetMethod(function.Name)!; - var value = functionIL.Invoke(null, null); - - if (value is CompilerObject co) - return co; - - if (value is ICompileTime coObject) - return coObject.GetCO(); - - //if (value is Type type) - // return new RawType(interpreter.IRInterop.ImportILType(type), interpreter.Compiler.TypeSystem.Type); - - throw new NotImplementedException(); - } - - private void CompileGetObject(ICodeLoader loader, IR.VM.GetObject get) - { - - if (get.IR is IR.IType type) - { - loader.Output.Emit(IL.Emit.OpCodes.Ldtoken, runtime.Import(type)); - //loader.Output.Emit() - loader.Push(typeof(Type)); - } - - else throw new NotImplementedException(); - } - } -} diff --git a/ZSharp.Runtime.IL/Runtime.cs b/ZSharp.Runtime.IL/Runtime.cs deleted file mode 100644 index 5e7a90ae..00000000 --- a/ZSharp.Runtime.IL/Runtime.cs +++ /dev/null @@ -1,99 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.Runtime.NET -{ - public class Runtime - : Interpreter.IRuntime - , Interpreter.IHostLoader - { - private readonly IL2IR.ILLoader ilLoader; - private readonly IR2IL.IRLoader irLoader; - - private readonly Cache typeObjects = []; - - public Context Context { get; } = new(); - - public Interpreter.Interpreter Interpreter { get; } - - public Hooks Hooks { get; } = new(); - - public Runtime(Interpreter.Interpreter interpreter) - { - Interpreter = interpreter; - - ilLoader = new(Context, interpreter.RuntimeModule); - irLoader = new(Context, interpreter.RuntimeModule); - - interpreter.Compiler.Evaluators.Add(new IRCodeEvaluator(this)); - - irLoader.GetObjectFunction = (loader, get) => - { - if (get.IR is IR.IType type) - { - loader.Output.Emit(IL.Emit.OpCodes.Ldtoken, Import(type)); - loader.Output.Emit(IL.Emit.OpCodes.Call, Utils.GetMethod(Type.GetTypeFromHandle)); - loader.Output.Emit(IL.Emit.OpCodes.Call, Hooks.GetObject); - - loader.Push(typeof(object)); - } - }; - - foreach (var (ir, il) in new (IR.IType, Type)[] - { - (interpreter.RuntimeModule.TypeSystem.Type, typeof(TypeObject)), - - (interpreter.RuntimeModule.TypeSystem.Void, typeof(void)), - (interpreter.RuntimeModule.TypeSystem.Boolean, typeof(bool)), - - (interpreter.RuntimeModule.TypeSystem.Int32, typeof(int)), - - (interpreter.RuntimeModule.TypeSystem.Float32, typeof(float)), - - (interpreter.RuntimeModule.TypeSystem.Object, typeof(object)), - (interpreter.RuntimeModule.TypeSystem.String, typeof(string)), - }) - Context.Cache(ir, il); - } - - void Interpreter.IRuntime.Import(IR.Module module) - => Import(module); - - public IL.Module Import(IR.Module module) - { - if (!Context.Cache(module, out var result)) - Context.Cache(result = irLoader.LoadModule(module), module); - - return result; - } - - public Type Import(IR.IType type) - => irLoader.LoadType(type); - - public IR.Module Import(IL.Module module) - { - if (!Context.Cache(module, out var result)) - result = ilLoader.LoadModule(module); - - //foreach (var (ir, il) in loadedModule.MethodImplementations) - // irLoader.Context.Callables.Cache(ir, il); - - //irLoader.Context.Modules.Cache(loadedModule.Result, module); - - return result; - } - - public IR.Function Import(IL.MethodInfo method) - => Context.Cache(method)!; - - public object GetObject(Type type) - { - if (typeObjects.Cache(type, out var result)) - return result; - - var ir = ilLoader.LoadType(type); - var co = Interpreter.CompilerIRLoader.Import(ir); - - return typeObjects.Cache(type, new TypeObject(type, ir, co)); - } - } -} diff --git a/ZSharp.Runtime.IL/Utils.cs b/ZSharp.Runtime.IL/Utils.cs deleted file mode 100644 index e7057713..00000000 --- a/ZSharp.Runtime.IL/Utils.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace ZSharp.Runtime.NET -{ - public static class Utils - { - public static IL.MethodInfo GetMethod(T t) - where T : Delegate - => t.Method; - } -} diff --git a/ZSharp.Runtime.IL/context/Context.Cache.cs b/ZSharp.Runtime.IL/context/Context.Cache.cs deleted file mode 100644 index cb6fe045..00000000 --- a/ZSharp.Runtime.IL/context/Context.Cache.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace ZSharp.Runtime.NET -{ - partial class Context - { - private readonly ContextCacheIL2IR toIR = new(); - - private readonly ContextCacheIR2IL toIL = new(); - } -} diff --git a/ZSharp.Runtime.IL/context/Context.IL2IR.cs b/ZSharp.Runtime.IL/context/Context.IL2IR.cs deleted file mode 100644 index 82061072..00000000 --- a/ZSharp.Runtime.IL/context/Context.IL2IR.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace ZSharp.Runtime.NET -{ - partial class Context - { - public IR.Module? Cache(IL.Module il) - => toIR.Modules.Cache(il); - - public bool Cache(IL.Module il, [NotNullWhen(true)] out IR.Module? ir) - => toIR.Modules.Cache(il, out ir); - - public IR.Module Cache(IL.Module il, IR.Module ir) - { - if (!toIR.Modules.Contains(il)) - toIR.Modules.Cache(il, ir); - - if (!toIL.Modules.Contains(ir)) - toIL.Modules.Cache(ir, il); - - return ir; - } - - public IR.IType? Cache(Type il) - => toIR.Types.Cache(il); - - public bool Cache(Type il, [NotNullWhen(true)] out IR.IType? ir) - => toIR.Types.Cache(il, out ir); - - public bool Cache(Type il, [NotNullWhen(true)] out T? ir) - where T : class, IR.IType - => toIR.Types.Cache(il, out ir); - - public IR.IType Cache(Type il, IR.IType ir) - { - if (!toIR.Types.Contains(il)) - toIR.Types.Cache(il, ir); - - if (!toIL.Types.Contains(ir)) - toIL.Types.Cache(ir, il); - - return ir; - } - - public IR.ICallable? Cache(IL.MethodBase il) - => toIR.Callables.Cache(il); - - public T? Cache(IL.MethodBase il) - where T : class, IR.ICallable - => toIR.Callables.Cache(il); - - public bool Cache(IL.MethodBase il, [NotNullWhen(true)] out IR.ICallable? ir) - => toIR.Callables.Cache(il, out ir); - - public bool Cache(IL.MethodBase il, [NotNullWhen(true)] out T? ir) - where T : class, IR.ICallable - => toIR.Callables.Cache(il, out ir); - - public IR.ICallable Cache(IL.MethodBase il, IR.ICallable ir) - { - if (!toIR.Callables.Contains(il)) - toIR.Callables.Cache(il, ir); - - if (!toIL.Callables.Contains(ir)) - toIL.Callables.Cache(ir, il); - - return ir; - } - - public bool Cache(IL.FieldInfo il, [NotNullWhen(true)] out IR.Field? ir) - => toIR.Fields.Cache(il, out ir); - - public IR.Field Cache(IL.FieldInfo il, IR.Field ir) - { - if (!toIR.Fields.Contains(il)) - toIR.Fields.Cache(il, ir); - - if (!toIL.Fields.Contains(ir)) - toIL.Fields.Cache(ir, il); - - return ir; - } - - public bool Cache(IL.FieldInfo il, [NotNullWhen(true)] out IR.Global? ir) - => toIR.Globals.Cache(il, out ir); - - public IR.Global Cache(IL.FieldInfo il, IR.Global ir) - { - if (!toIR.Globals.Contains(il)) - toIR.Globals.Cache(il, ir); - - if (!toIL.Globals.Contains(ir)) - toIL.Globals.Cache(ir, il); - - return ir; - } - } -} diff --git a/ZSharp.Runtime.IL/context/ContextIR2IL.cs b/ZSharp.Runtime.IL/context/ContextIR2IL.cs deleted file mode 100644 index 58c34f46..00000000 --- a/ZSharp.Runtime.IL/context/ContextIR2IL.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace ZSharp.Runtime.NET -{ - partial class Context - { - public IL.Module? Cache(IR.Module ir) - => toIL.Modules.Cache(ir); - - public bool Cache(IR.Module ir, [NotNullWhen(true)] out IL.Module? il) - => toIL.Modules.Cache(ir, out il); - - public IL.Module Cache(IR.Module ir, IL.Module il) - { - if (!toIR.Modules.Contains(il)) - toIR.Modules.Cache(il, ir); - - if (!toIL.Modules.Contains(ir)) - toIL.Modules.Cache(ir, il); - - return il; - } - - public Type? Cache(IR.IType ir) - => toIL.Types.Cache(ir); - - public bool Cache(IR.IType ir, [NotNullWhen(true)] out Type? il) - => toIL.Types.Cache(ir, out il); - - public Type Cache(IR.IType ir, Type il) - { - if (!toIR.Types.Contains(il)) - toIR.Types.Cache(il, ir); - - if (!toIL.Types.Contains(ir)) - toIL.Types.Cache(ir, il); - - return il; - } - - public IL.MethodBase? Cache(IR.ICallable ir) - => toIL.Callables.Cache(ir); - - public T? Cache(IR.ICallable ir) - where T : IL.MethodBase - => toIL.Callables.Cache(ir); - - public bool Cache(IR.ICallable ir, [NotNullWhen(true)] out IL.MethodBase? il) - => toIL.Callables.Cache(ir, out il); - - public bool Cache(IR.ICallable ir, [NotNullWhen(true)] out T? il) - where T : IL.MethodBase - => toIL.Callables.Cache(ir, out il); - - public IL.MethodBase Cache(IR.ICallable ir, IL.MethodBase il) - { - if (!toIR.Callables.Contains(il)) - toIR.Callables.Cache(il, ir); - - if (!toIL.Callables.Contains(ir)) - toIL.Callables.Cache(ir, il); - - return il; - } - - public IL.FieldInfo? Cache(IR.Field ir) - => toIL.Fields.Cache(ir); - - public bool Cache(IR.Field ir, [NotNullWhen(true)] out IL.FieldInfo? il) - => toIL.Fields.Cache(ir, out il); - - public IL.FieldInfo Cache(IR.Field ir, IL.FieldInfo il) - { - if (!toIR.Fields.Contains(il)) - toIR.Fields.Cache(il, ir); - - if (!toIL.Fields.Contains(ir)) - toIL.Fields.Cache(ir, il); - - return il; - } - - public IL.FieldInfo? Cache(IR.Global ir) - => toIL.Globals.Cache(ir); - - public bool Cache(IR.Global ir, [NotNullWhen(true)] out IL.FieldInfo? il) - => toIL.Globals.Cache(ir, out il); - - public IL.FieldInfo Cache(IR.Global ir, IL.FieldInfo il) - { - if (!toIR.Globals.Contains(il)) - toIR.Globals.Cache(il, ir); - - if (!toIL.Globals.Contains(ir)) - toIL.Globals.Cache(ir, il); - - return il; - } - } -} diff --git a/ZSharp.Runtime.IL/context/caches/ContextCache.IL2IR.cs b/ZSharp.Runtime.IL/context/caches/ContextCache.IL2IR.cs deleted file mode 100644 index 796bac0d..00000000 --- a/ZSharp.Runtime.IL/context/caches/ContextCache.IL2IR.cs +++ /dev/null @@ -1,17 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.Runtime.NET -{ - internal sealed class ContextCacheIL2IR - { - public Cache Modules { get; } = []; - - public Cache Types { get; } = []; - - public Cache Callables { get; } = []; - - public Cache Fields { get; } = []; - - public Cache Globals { get; } = []; - } -} diff --git a/ZSharp.Runtime.IL/context/caches/ContextCache.IR2IL.cs b/ZSharp.Runtime.IL/context/caches/ContextCache.IR2IL.cs deleted file mode 100644 index de623a44..00000000 --- a/ZSharp.Runtime.IL/context/caches/ContextCache.IR2IL.cs +++ /dev/null @@ -1,17 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.Runtime.NET -{ - internal sealed class ContextCacheIR2IL - { - public Cache Modules { get; } = []; - - public Cache Types { get; } = []; - - public Cache Callables { get; } = []; - - public Cache Fields { get; } = []; - - public Cache Globals { get; } = []; - } -} diff --git a/ZSharp.Runtime.IL/il2ir/attributes/AliasAttribute.cs b/ZSharp.Runtime.IL/il2ir/attributes/AliasAttribute.cs deleted file mode 100644 index 078691ba..00000000 --- a/ZSharp.Runtime.IL/il2ir/attributes/AliasAttribute.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace ZSharp.Runtime.NET.IL2IR -{ - [AttributeUsage( - AttributeTargets.Module | - AttributeTargets.Class | - AttributeTargets.Struct | - AttributeTargets.Enum | - AttributeTargets.Constructor | - AttributeTargets.Method | - AttributeTargets.Property, - AllowMultiple = false)] - public sealed class AliasAttribute : Attribute - { - public required string Name { get; set; } - } -} diff --git a/ZSharp.Runtime.IL/il2ir/attributes/HideInIRAttribute.cs b/ZSharp.Runtime.IL/il2ir/attributes/HideInIRAttribute.cs deleted file mode 100644 index d7035a33..00000000 --- a/ZSharp.Runtime.IL/il2ir/attributes/HideInIRAttribute.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ZSharp.Runtime.NET.IL2IR -{ - public sealed class HideInIRAttribute : Attribute - { - } -} diff --git a/ZSharp.Runtime.IL/il2ir/attributes/ModuleGlobalsAttribute.cs b/ZSharp.Runtime.IL/il2ir/attributes/ModuleGlobalsAttribute.cs deleted file mode 100644 index 803bf033..00000000 --- a/ZSharp.Runtime.IL/il2ir/attributes/ModuleGlobalsAttribute.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.Runtime.NET.IL2IR -{ - [AttributeUsage(AttributeTargets.Class)] - public sealed class ModuleGlobalsAttribute : Attribute - { - } -} diff --git a/ZSharp.Runtime.IL/il2ir/core/BaseILLoader.cs b/ZSharp.Runtime.IL/il2ir/core/BaseILLoader.cs deleted file mode 100644 index 1280777a..00000000 --- a/ZSharp.Runtime.IL/il2ir/core/BaseILLoader.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace ZSharp.Runtime.NET.IL2IR -{ - internal abstract class BaseILLoader(ILLoader loader) - { - public ILLoader Loader { get; } = loader; - - public Context Context => Loader.Context; - } - - internal abstract class BaseILLoader(ILLoader loader, In @in, Out @out) - : BaseILLoader(loader) - { - public In Input { get; } = @in; - - public Out Output { get; } = @out; - - public abstract Out Load(); - } -} diff --git a/ZSharp.Runtime.IL/il2ir/core/ILLoader.cs b/ZSharp.Runtime.IL/il2ir/core/ILLoader.cs deleted file mode 100644 index c36bb6fb..00000000 --- a/ZSharp.Runtime.IL/il2ir/core/ILLoader.cs +++ /dev/null @@ -1,49 +0,0 @@ -using ZSharp.IR; - -namespace ZSharp.Runtime.NET.IL2IR -{ - public sealed class ILLoader(Context context, RuntimeModule? runtimeModule = null) - { - public RuntimeModule RuntimeModule { get; } = runtimeModule ?? RuntimeModule.Standard; - - public Context Context { get; } = context; - - public IType LoadType(Type type) - { - if (Context.Cache(type, out var result)) - return result; - - if (type.IsTypeDefinition) - { - if (type.IsClass) result = new ClassLoader(this, type).Load(); - //else if (type.IsInterface) result = new ILInterfaceLoader(this, type).Load(); - //else if (type.IsEnum) result = new ILEnumLoader(this, type).Load(); - //else if (type.IsValueType) result = new ILStructLoader(this, type).Load(); - else throw new ArgumentException("Type must be a type definition.", nameof(type)); - - return Context.Cache(type, result); - } - - if (type.IsArray) - throw new NotImplementedException(); - if (type.IsPointer) - throw new NotImplementedException(); - if (type.IsByRef) - throw new NotImplementedException(); - - if (type.IsConstructedGenericType) - throw new NotImplementedException(); - - throw new(); - } - - public T LoadType(Type type) - where T : IType - => (T)LoadType(type); - - public IR.Module LoadModule(IL.Module module) - { - return new ModuleLoader(this, module).Load(); - } - } -} diff --git a/ZSharp.Runtime.IL/il2ir/loaders/ClassLoader.cs b/ZSharp.Runtime.IL/il2ir/loaders/ClassLoader.cs deleted file mode 100644 index 94c9d4ed..00000000 --- a/ZSharp.Runtime.IL/il2ir/loaders/ClassLoader.cs +++ /dev/null @@ -1,173 +0,0 @@ -namespace ZSharp.Runtime.NET.IL2IR -{ - internal sealed class ClassLoader(ILLoader loader, Type input) - : BaseILLoader(loader, input, new(input.Name)) - { - public override IR.Class Load() - { - if (Context.Cache(Input, out var result)) - return result; - - Context.Cache(Input, Output); - - LoadBase(); - - LoadInterfaceImplementations(); - - LoadFields(); - - LoadProperties(); - - LoadConstructors(); - - LoadMethods(); - - LoadTypes(); - - return Output; - } - - private void LoadBase() - { - if (Input.BaseType is not null) - Output.Base = (IR.Class)Loader.LoadType(Input.BaseType); - } - - private void LoadInterfaceImplementations() - { - foreach (var @interface in Input.GetInterfaces()) - LoadInterfaceImplementation(@interface, Input.GetInterfaceMap(@interface)); - } - - private void LoadFields() - { - foreach (var field in Input.GetFields()) - LoadField(field); - } - - private void LoadProperties() - { - foreach (var property in Input.GetProperties()) - LoadProperty(property); - } - - private void LoadConstructors() - { - foreach (var constructor in Input.GetConstructors()) - LoadConstructor(constructor); - } - - private void LoadMethods() - { - foreach (var method in Input.GetMethods()) - LoadMethod(method); - } - - private void LoadTypes() - { - foreach (var nested in Input.GetNestedTypes()) - LoadTypeDefinition(nested); - } - - private void LoadInterfaceImplementation(Type @interface, IL.InterfaceMapping mapping) - { - if (mapping.InterfaceMethods.Length != mapping.TargetMethods.Length) - throw new InvalidOperationException("Interface mapping is invalid."); - - var implementation = new IR.InterfaceImplementation(Loader.LoadType(@interface)); - - for (int i = 0; i < mapping.InterfaceMethods.Length; i++) - { - var interfaceMethod = mapping.InterfaceMethods[i]; - var targetMethod = mapping.TargetMethods[i]; - - implementation.Implementations.Add( - LoadMethod(interfaceMethod), - LoadMethod(targetMethod) - ); - } - } - - private void LoadField(IL.FieldInfo field) - { - throw new NotImplementedException(); - - // TODO: implement this by adding a property, since it's impossible for the VM to access C# fields directly. - } - - private void LoadProperty(IL.PropertyInfo property) - { - var result = new IR.Property(property.Name, Loader.LoadType(property.PropertyType)) - { - Getter = property.GetMethod is null ? null : LoadMethod(property.GetMethod), - Setter = property.SetMethod is null ? null : LoadMethod(property.SetMethod), - }; - - Output.Properties.Add(result); - } - - private void LoadConstructor(IL.ConstructorInfo constructor) - { - var result = new IR.Constructor(null) - { - Method = new(Loader.RuntimeModule.TypeSystem.Void), - }; - - foreach (var parameter in constructor.GetParameters()) - result.Method.Signature.Args.Parameters.Add(new(parameter.Name ?? string.Empty, Loader.LoadType(parameter.ParameterType))); - - Output.Constructors.Add(result); - } - - private IR.Method LoadMethod(IL.MethodInfo method) - { - var result = new IR.Method(Loader.LoadType(method.ReturnType)); - - foreach (var parameter in method.GetParameters()) - result.Signature.Args.Parameters.Add(new(parameter.Name ?? string.Empty, Loader.LoadType(parameter.ParameterType))); - - Output.Methods.Add(result); - - return result; - } - - private void LoadTypeDefinition(Type type) - { - if (!type.IsTypeDefinition) - throw new ArgumentException("Type must be a type definition.", nameof(type)); - - var result = Context.Cache(type); - - if (result is not null) ; - else if (type.IsClass) result = LoadClass(type); - else if (type.IsInterface) result = LoadInterface(type); - else if (type.IsEnum) result = LoadEnum(type); - else if (type.IsValueType) result= LoadStruct(type); - else throw new NotImplementedException(); - - // TADA: | | | | | | | | | - // TODO: V V V V V V V V V - //Output.Types.Add(result); - } - - private IR.Class LoadClass(Type type) - { - throw new NotImplementedException(); - } - - private IR.Interface LoadInterface(Type type) - { - throw new NotImplementedException(); - } - - private IR.Enumclass LoadEnum(Type type) - { - throw new NotImplementedException(); - } - - private IR.ValueType LoadStruct(Type type) - { - throw new NotImplementedException(); - } - } -} diff --git a/ZSharp.Runtime.IL/il2ir/loaders/ModuleLoader.cs b/ZSharp.Runtime.IL/il2ir/loaders/ModuleLoader.cs deleted file mode 100644 index 5a923419..00000000 --- a/ZSharp.Runtime.IL/il2ir/loaders/ModuleLoader.cs +++ /dev/null @@ -1,111 +0,0 @@ -using static System.Reflection.CustomAttributeExtensions; - -namespace ZSharp.Runtime.NET.IL2IR -{ - internal sealed class ModuleLoader(ILLoader loader, IL.Module input) - : BaseILLoader(loader, input, new(input.Name)) - { - public override IR.Module Load() - { - if (Input.GetCustomAttribute() is AliasAttribute alias) - Output.Name = alias.Name; - - if (Context.Cache(Input, out var result)) - return result; - Context.Cache(Input, Output); - - LoadFields(); - - LoadMethods(); - - LoadTypes(); - - return Output; - } - - private void LoadFields() - { - foreach (var field in Input.GetFields()) - LoadField(field); - } - - private void LoadMethods() - { - foreach (var method in Input.GetMethods()) - LoadMethod(method); - } - - private void LoadTypes() - { - foreach (var type in Input.GetTypes()) - if (type.GetCustomAttribute() is null) - LoadTypeDefinition(type); - } - - private void LoadField(IL.FieldInfo field) - { - var global = new IR.Global(field.Name, Loader.LoadType(field.FieldType)) - { - //IsReadOnly = field.IsInitOnly, - }; - - Output.Globals.Add(global); - } - - private void LoadMethod(IL.MethodInfo method) - { - var function = new IR.Function(Loader.LoadType(method.ReturnType)) - { - Name = method.GetCustomAttribute() is AliasAttribute alias ? alias.Name : method.Name, - }; - - foreach (var parameter in method.GetParameters()) - function.Signature.Args.Parameters.Add(new(parameter.Name!, Loader.LoadType(parameter.ParameterType))); - - Output.Functions.Add(function); - - Context.Cache(function, method); - } - - private void LoadTypeDefinition(Type type) - { - if (!type.IsTypeDefinition) - throw new ArgumentException("Type must be a type definition.", nameof(type)); - - if (type.IsClass && type.IsSealed && type.IsAbstract && type.GetCustomAttribute() is not null) - LoadGlobals(type); - - else if (type.IsClass) LoadClass(type); - else if (type.IsInterface) LoadInterface(type); - else if (type.IsEnum) LoadEnum(type); - else if (type.IsValueType) LoadStruct(type); - - else throw new NotImplementedException(); - } - - private void LoadGlobals(Type type) - { - foreach (var method in type.GetMethods()) - if (method.IsStatic) - LoadMethod(method); - } - - private void LoadClass(Type type) - => Output.Types.Add(new ClassLoader(Loader, type).Load()); - - private void LoadInterface(Type type) - { - throw new NotImplementedException(); - } - - private void LoadEnum(Type type) - { - throw new NotImplementedException(); - } - - private void LoadStruct(Type type) - { - throw new NotImplementedException(); - } - } -} diff --git a/ZSharp.Runtime.IL/ir2il/SignatureExtensions.cs b/ZSharp.Runtime.IL/ir2il/SignatureExtensions.cs deleted file mode 100644 index 7fafc80f..00000000 --- a/ZSharp.Runtime.IL/ir2il/SignatureExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace ZSharp.Runtime.NET.IR2IL -{ - internal static class SignatureExtensions - { - public static IR.Parameter[] GetParameters(this IR.Signature signature) - => [ - ..signature.Args.Parameters, - ..(signature.IsVarArgs ? new IR.Parameter[] { signature.Args.Var! } : []), - ..signature.KwArgs.Parameters, - ..(signature.IsVarKwArgs ? new IR.Parameter[] { signature.KwArgs.Var! } : []) - ]; - } -} diff --git a/ZSharp.Runtime.IL/ir2il/core/BaseIRLoader.cs b/ZSharp.Runtime.IL/ir2il/core/BaseIRLoader.cs deleted file mode 100644 index 7886dea9..00000000 --- a/ZSharp.Runtime.IL/ir2il/core/BaseIRLoader.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace ZSharp.Runtime.NET.IR2IL -{ - internal abstract class BaseIRLoader(IRLoader loader) - { - public IRLoader Loader { get; } = loader; - - public Context Context => Loader.Context; - } - - internal abstract class BaseIRLoader(IRLoader loader, In @in, Out @out) - : BaseIRLoader(loader) - { - public In Input { get; } = @in; - - public Out Output { get; } = @out; - } -} diff --git a/ZSharp.Runtime.IL/ir2il/core/IRLoader.cs b/ZSharp.Runtime.IL/ir2il/core/IRLoader.cs deleted file mode 100644 index d69e138f..00000000 --- a/ZSharp.Runtime.IL/ir2il/core/IRLoader.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace ZSharp.Runtime.NET.IR2IL -{ - /// - /// Wraps an IR module in a C# module. - /// - public class IRLoader(Context context, IR.RuntimeModule? runtimeModule = null) - { - private List thisPass = [], nextPass = []; - - public Context Context { get; } = context; - - public IR.RuntimeModule RuntimeModule { get; } = runtimeModule ?? IR.RuntimeModule.Standard; - - public Action GetObjectFunction { get; set; } = (_, __) => throw new NotImplementedException(); - - public IL.Module LoadModule(IR.Module module) - { - if (Context.Cache(module, out var result)) - return result; - - var assemblybuilder = IL.Emit.AssemblyBuilder.DefineDynamicAssembly( - new IL.AssemblyName(module.Name ?? ""), - IL.Emit.AssemblyBuilderAccess.RunAndCollect); - - result = new ModuleLoader(this, module, assemblybuilder.DefineDynamicModule(module.Name ?? "")).Load(); - - if (module.HasSubmodules) - foreach (var submodule in module.Submodules) - new ModuleLoader(this, submodule, assemblybuilder.DefineDynamicModule(result.Name + '.' + (module.Name ?? ""))).Load(); - - while (nextPass.Count > 0) - { - (thisPass, nextPass) = (nextPass, thisPass); - - foreach (var action in thisPass) - action(); - - thisPass.Clear(); - } - - return result; - } - - public Type LoadType(IR.IType type) - { - if (Context.Cache(type, out var result)) - return result; - - return type switch - { - _ => throw new NotImplementedException() - }; - } - - internal void AddToNextPass(Action action) - => nextPass.Add(action); - } -} diff --git a/ZSharp.Runtime.IL/ir2il/loaders/ModuleLoader.cs b/ZSharp.Runtime.IL/ir2il/loaders/ModuleLoader.cs deleted file mode 100644 index d699ce81..00000000 --- a/ZSharp.Runtime.IL/ir2il/loaders/ModuleLoader.cs +++ /dev/null @@ -1,127 +0,0 @@ -namespace ZSharp.Runtime.NET.IR2IL -{ - internal sealed class ModuleLoader(IRLoader loader, IR.Module input, IL.Emit.ModuleBuilder output) - : BaseIRLoader(loader, input, output) - { - private IL.Emit.TypeBuilder globals = null!; - private IL.Emit.MethodBuilder cctor = null!; - - public IL.Module Load() - { - Context.Cache(Input, Output); - - globals = Output.DefineType( - "", - IL.TypeAttributes.Public | - IL.TypeAttributes.Abstract | - IL.TypeAttributes.Sealed - ); - //cctor = globals.DefineMethod( - // ".cctor", - // IL.MethodAttributes.Static | - // IL.MethodAttributes.SpecialName | - // IL.MethodAttributes.RTSpecialName | - // IL.MethodAttributes.PrivateScope - //); - - LoadGlobals(); - - LoadFunctions(); - - LoadTypes(); - - Loader.AddToNextPass(() => globals.CreateType()); - - return Output; - } - - private void LoadGlobals() - { - if (Input.HasGlobals) - foreach (var global in Input.Globals) - LoadGlobal(global); - } - - private void LoadFunctions() - { - if (Input.HasFunctions) - foreach (var function in Input.Functions) - LoadFunction(function); - } - - private void LoadTypes() - { - if (Input.HasTypes) - foreach (var type in Input.Types) - LoadType(type); - } - - private Type LoadType(IR.IType type) - { - if (Context.Cache(type, out var result)) - return result; - - return type switch - { - IR.Class @class => LoadClass(@class), - _ => throw new NotImplementedException() - }; - } - - private Type LoadClass(IR.Class @class) - { - var type = Output.DefineType(@class.Name ?? string.Empty, IL.TypeAttributes.Public); - - return type; - } - - private IL.FieldInfo LoadGlobal(IR.Global global) - { - var result = globals.DefineField( - global.Name ?? string.Empty, - Loader.LoadType(global.Type), - IL.FieldAttributes.Public | IL.FieldAttributes.Static - ); - - Context.Cache(global, result); - - return result; - } - - private IL.MethodInfo LoadFunction(IR.Function function) - { - var irParams = function.Signature.GetParameters(); - - var attributes = IL.MethodAttributes.Public | IL.MethodAttributes.Static; - - var parameters = irParams.Select(p => new Parameter() - { - Name = p.Name, - Type = Loader.LoadType(p.Type), - Position = p.Index, - }); - - var result = globals.DefineMethod( - function.Name ?? string.Empty, - attributes, - Loader.LoadType(function.ReturnType), - parameters.Select(p => p.Type).ToArray() - ); - - Context.Cache(function, result); - - var ilGen = result.GetILGenerator(); - var codeLoader = new CodeLoader(Loader, function, ilGen); - - foreach (var (ir, parameter) in irParams.Zip(parameters)) - codeLoader.Args[ir] = parameter; - - foreach (var local in function.Body.Locals) - codeLoader.Locals[local] = ilGen.DeclareLocal(Loader.LoadType(local.Type)); - - Loader.AddToNextPass(codeLoader.Load); - - return result; - } - } -} diff --git a/ZSharp.Runtime.IL/ir2il/loaders/TypeLoader.cs b/ZSharp.Runtime.IL/ir2il/loaders/TypeLoader.cs deleted file mode 100644 index a71f46da..00000000 --- a/ZSharp.Runtime.IL/ir2il/loaders/TypeLoader.cs +++ /dev/null @@ -1,135 +0,0 @@ -namespace ZSharp.Runtime.NET.IR2IL -{ - internal sealed class ClassLoader(IRLoader loader, IR.Class input, IL.Emit.TypeBuilder output) - : BaseIRLoader(loader, input, output) - { - public void Load() - { - //LoadNestedTypes(); - - LoadBase(); - - //LoadInterfaces(); - - LoadConstructors(); - - LoadFields(); - - //LoadEvents(); - - LoadMethods(); - - //LoadProperties(); - } - - private void LoadNestedTypes() - { - throw new NotImplementedException(); - } - - private void LoadBase() - { - if (Input.Base != null) - Output.SetParent(Loader.LoadType(Input.Base)); - } - - private void LoadInterfaces() - { - throw new NotImplementedException(); - } - - private void LoadConstructors() - { - foreach (var constructor in Input.Constructors) - LoadConstructor(constructor); - } - - private void LoadFields() - { - foreach (var field in Input.Fields) - LoadField(field); - } - - private void LoadEvents() - { - throw new NotImplementedException(); - } - - private void LoadMethods() - { - foreach (var method in Input.Methods) - LoadMethod(method); - } - - private void LoadProperties() - { - throw new NotImplementedException(); - } - - private void LoadConstructor(IR.Constructor constructor) - { - var irParams = constructor.Method.Signature.GetParameters(); - - var parameters = irParams.Select(p => new Parameter() - { - Name = p.Name, - Type = Loader.LoadType(p.Type), - Position = p.Index - }); - - var result = Output.DefineConstructor(IL.MethodAttributes.Public, IL.CallingConventions.HasThis, irParams.Select(p => Loader.LoadType(p.Type)).ToArray()); - - Context.Cache(constructor.Method, result); - - var ilGen = result.GetILGenerator(); - var codeLoader = new CodeLoader(Loader, constructor.Method, ilGen); - - foreach (var (ir, parameter) in irParams.Zip(parameters)) - codeLoader.Args[ir] = parameter; - - foreach (var local in constructor.Method.Body.Locals) - codeLoader.Locals[local] = ilGen.DeclareLocal(Loader.LoadType(local.Type)); - - codeLoader.Load(); - } - - private void LoadField(IR.Field field) - { - var il = Output.DefineField(field.Name, Loader.LoadType(field.Type), IL.FieldAttributes.Public); - - Context.Cache(field, il); - } - - private void LoadMethod(IR.Method method) - { - var irParams = method.Signature.GetParameters(); - - var parameters = irParams.Select(p => new Parameter() - { - Name = p.Name, - Type = Loader.LoadType(p.Type), - Position = p.Index, - }); - - var attributes = IL.MethodAttributes.Public; - - if (method.IsStatic) - attributes |= IL.MethodAttributes.Static; - - var result = Output.DefineMethod(method.Name ?? string.Empty, attributes, Loader.LoadType(method.ReturnType), parameters.Select(p => p.Type).ToArray()); - - Context.Cache(method, result); - - var ilGen = result.GetILGenerator(); - var codeLoader = new CodeLoader(Loader, method, ilGen); - - foreach (var (ir, parameter) in irParams.Zip(parameters)) - codeLoader.Args[ir] = parameter; - - foreach (var local in method.Body.Locals) - codeLoader.Locals[local] = ilGen.DeclareLocal(Loader.LoadType(local.Type)); - - codeLoader.Load(); - } - } -} diff --git a/ZSharp.Runtime.IL/ir2il/loaders/code/CodeLoader.Compile.cs b/ZSharp.Runtime.IL/ir2il/loaders/code/CodeLoader.Compile.cs deleted file mode 100644 index 9eac2b54..00000000 --- a/ZSharp.Runtime.IL/ir2il/loaders/code/CodeLoader.Compile.cs +++ /dev/null @@ -1,271 +0,0 @@ -using VM = ZSharp.IR.VM; - -namespace ZSharp.Runtime.NET.IR2IL -{ - partial class CodeLoader - { - private readonly Stack _stack = []; - - private void Compile(VM.Call call) - { - if (!Context.Cache(call.Callable, out var callable)) - throw new(); - - foreach (var _ in call.Callable.Signature.GetParameters()) - _stack.Pop(); - - if (callable is IL.MethodInfo method) - { - Output.Emit(IL.Emit.OpCodes.Call, method); - - if (method.ReturnType != typeof(void)) - _stack.Push(method.ReturnType); - } - else if (callable is IL.ConstructorInfo constructor) - Output.Emit(IL.Emit.OpCodes.Call, constructor); - else throw new($"Unknown callable type: {callable.GetType()}"); - } - - private void Compile(VM.CallIndirect callIndirect) - { - throw new NotImplementedException(); - } - - private void Compile(VM.CallInternal callInternal) - { - throw new($"Use {nameof(VM.Call)} instead!"); - } - - private void Compile(VM.CallVirtual callVirtual) - { - if (!Context.Cache(callVirtual.Method, out var method)) - throw new(); - - if (!method.IsVirtual && !method.IsAbstract) - throw new($"Method {method} is not virtual or abstract!"); - - Output.Emit(IL.Emit.OpCodes.Callvirt, method); - - if (method.ReturnType != typeof(void)) - _stack.Push(method.ReturnType); - } - - private void Compile(VM.CreateInstance createInstance) - { - if (!Context.Cache(createInstance.Constructor.Method, out var constructor)) - throw new(); - - Output.Emit(IL.Emit.OpCodes.Newobj, constructor); - - _stack.Push(constructor.DeclaringType ?? throw new()); - } - - private void Compile(VM.Dup _) - { - Output.Emit(IL.Emit.OpCodes.Dup); - - _stack.Push(_stack.Peek()); - } - - private void Compile(VM.GetArgument getArgument) - { - var p = Args[getArgument.Argument]; - var index = p.Position; - - if (index == 0) - Output.Emit(IL.Emit.OpCodes.Ldarg_0); - else if (index == 1) - Output.Emit(IL.Emit.OpCodes.Ldarg_1); - else if (index == 2) - Output.Emit(IL.Emit.OpCodes.Ldarg_2); - else if (index == 3) - Output.Emit(IL.Emit.OpCodes.Ldarg_3); - else if (index <= byte.MaxValue) - Output.Emit(IL.Emit.OpCodes.Ldarg_S, (byte)index); - else - Output.Emit(IL.Emit.OpCodes.Ldarg, index); - - _stack.Push(p.Type); - } - - private void Compile(VM.GetField getField) - { - if (!Context.Cache(getField.Field, out var field)) - throw new(); - - Output.Emit(field.IsStatic ? IL.Emit.OpCodes.Ldsfld : IL.Emit.OpCodes.Ldfld, field); - - _stack.Push(field.FieldType); - } - - private void Compile(VM.GetGlobal getGlobal) - { - if (!Context.Cache(getGlobal.Global, out var global)) - throw new(); - - Output.Emit(IL.Emit.OpCodes.Ldsfld, global); - - _stack.Push(global.FieldType); - } - - private void Compile(VM.GetLocal getLocal) - { - var l = Locals[getLocal.Local]; - var index = l.LocalIndex; - - if (index == 0) - Output.Emit(IL.Emit.OpCodes.Ldloc_0); - else if (index == 1) - Output.Emit(IL.Emit.OpCodes.Ldloc_1); - else if (index == 2) - Output.Emit(IL.Emit.OpCodes.Ldloc_2); - else if (index == 3) - Output.Emit(IL.Emit.OpCodes.Ldloc_3); - else if (index <= byte.MaxValue) - Output.Emit(IL.Emit.OpCodes.Ldloc_S, (byte)index); - else - Output.Emit(IL.Emit.OpCodes.Ldloc, index); - - _stack.Push(l.LocalType); - } - - private void Compile(VM.GetObject getObject) - { - Loader.GetObjectFunction(this, getObject); - } - - private void Compile(VM.Jump jump) - { - Output.Emit(IL.Emit.OpCodes.Br, labels[jump.Target]); - } - - private void Compile(VM.JumpIfTrue jumpIfTrue) - { - Output.Emit(IL.Emit.OpCodes.Brtrue, labels[jumpIfTrue.Target]); - - _stack.Pop(); - } - - private void Compile(VM.JumpIfFalse jumpIfFalse) - { - Output.Emit(IL.Emit.OpCodes.Brfalse, labels[jumpIfFalse.Target]); - - _stack.Pop(); - } - - private void Compile(VM.Nop _) - { - Output.Emit(IL.Emit.OpCodes.Nop); - } - - private void Compile(VM.Pop _) - { - Output.Emit(IL.Emit.OpCodes.Pop); - - _stack.Pop(); - } - - private void Compile(VM.PutBoolean putBoolean) - { - Output.Emit(putBoolean.Value ? IL.Emit.OpCodes.Ldc_I4_1 : IL.Emit.OpCodes.Ldc_I4_0); - - _stack.Push(typeof(bool)); - } - - private void Compile(VM.PutFloat32 putFloat32) - { - Output.Emit(IL.Emit.OpCodes.Ldc_R4, putFloat32.Value); - - _stack.Push(typeof(float)); - } - - private void Compile(VM.PutInt32 putInt32) - { - Output.Emit(IL.Emit.OpCodes.Ldc_I4, putInt32.Value); - - _stack.Push(typeof(int)); - } - - private void Compile(VM.PutNull _) - { - Output.Emit(IL.Emit.OpCodes.Ldnull); - - _stack.Push(typeof(object)); - } - - private void Compile(VM.PutString putString) - { - Output.Emit(IL.Emit.OpCodes.Ldstr, putString.Value); - - _stack.Push(typeof(string)); - } - - private void Compile(VM.Return _) - { - Output.Emit(IL.Emit.OpCodes.Ret); - } - - private void Compile(VM.SetArgument setArgument) - { - var index = Args[setArgument.Argument].Position; - - if (index <= byte.MaxValue) - Output.Emit(IL.Emit.OpCodes.Starg_S, (byte)index); - else - Output.Emit(IL.Emit.OpCodes.Starg, index); - - _stack.Pop(); - } - - private void Compile(VM.SetField setField) - { - if (!Context.Cache(setField.Field, out var field)) - throw new(); - - Output.Emit(field.IsStatic ? IL.Emit.OpCodes.Stsfld : IL.Emit.OpCodes.Stfld, field); - - _stack.Pop(); - } - - private void Compile(VM.SetGlobal setGlobal) - { - if (!Context.Cache(setGlobal.Global, out var global)) - throw new(); - - Output.Emit(IL.Emit.OpCodes.Stsfld, global); - - _stack.Pop(); - } - - private void Compile(VM.SetLocal setLocal) - { - var index = Locals[setLocal.Local].LocalIndex; - - if (index <= byte.MaxValue) - Output.Emit(IL.Emit.OpCodes.Stloc_S, (byte)index); - else - Output.Emit(IL.Emit.OpCodes.Stloc, index); - - _stack.Pop(); - } - - private void Compile(VM.Swap _) - { - var tmp1 = Output.DeclareLocal(_stack.Peek()); - Output.Emit(IL.Emit.OpCodes.Stloc, tmp1.LocalIndex); - var tp1 = _stack.Pop(); - - var tmp2 = Output.DeclareLocal(_stack.Peek()); - Output.Emit(IL.Emit.OpCodes.Stloc, tmp2.LocalIndex); - var tp2 = _stack.Pop(); - - Output.Emit(IL.Emit.OpCodes.Ldloc, tmp1.LocalIndex); - - _stack.Push(tp1); - - Output.Emit(IL.Emit.OpCodes.Ldloc, tmp2.LocalIndex); - - _stack.Push(tp2); - } - } -} diff --git a/ZSharp.Runtime.IL/ir2il/loaders/code/CodeLoader.cs b/ZSharp.Runtime.IL/ir2il/loaders/code/CodeLoader.cs deleted file mode 100644 index fac696ab..00000000 --- a/ZSharp.Runtime.IL/ir2il/loaders/code/CodeLoader.cs +++ /dev/null @@ -1,88 +0,0 @@ -namespace ZSharp.Runtime.NET.IR2IL -{ - internal sealed partial class CodeLoader(IRLoader loader, IR.ICallable code, IL.Emit.ILGenerator method) - : BaseIRLoader(loader, code, method) - , ICodeLoader - { - private readonly Dictionary labels = []; - - public Stack Stack => _stack; - - public Dictionary Args { get; } = []; - - public Dictionary Locals { get; } = []; - - public void Load() - { - CompileCode(); - } - - private void CompileCode() - { - if (!Input.HasBody || !Input.Body.HasInstructions) return; - - foreach (var instruction in Input.Body.Instructions) - labels[instruction] = Output.DefineLabel(); - - - foreach (var instruction in Input.Body.Instructions) - Compile(instruction); - } - - public void Push(Type type) - => _stack.Push(type); - - public void Pop() - => _stack.Pop(); - - public void Pop(Type type) - { - if (_stack.Pop() != type) - throw new($"Expected type {type} on the stack!"); - } - - public void Pop(params Type[] types) - { - foreach (var type in types.Reverse()) - Pop(type); - } - - private void Compile(IR.VM.Instruction instruction) - { - Output.MarkLabel(labels[instruction]); - - switch (instruction) - { - case IR.VM.Call call: Compile(call); break; - case IR.VM.CallIndirect callIndirect: Compile(callIndirect); break; - case IR.VM.CallInternal callInternal: Compile(callInternal); break; - case IR.VM.CallVirtual callVirtual: Compile(callVirtual); break; - case IR.VM.CreateInstance createInstance: Compile(createInstance); break; - case IR.VM.Dup dup: Compile(dup); break; - case IR.VM.GetArgument getArgument: Compile(getArgument); break; - case IR.VM.GetField getField: Compile(getField); break; - case IR.VM.GetGlobal getGlobal: Compile(getGlobal); break; - case IR.VM.GetLocal getLocal: Compile(getLocal); break; - case IR.VM.GetObject getObject: Compile(getObject); break; - case IR.VM.Jump jump: Compile(jump); break; - case IR.VM.JumpIfTrue jumpIfTrue: Compile(jumpIfTrue); break; - case IR.VM.JumpIfFalse jumpIfFalse: Compile(jumpIfFalse); break; - case IR.VM.Nop nop: Compile(nop); break; - case IR.VM.Pop pop: Compile(pop); break; - case IR.VM.PutBoolean putBoolean: Compile(putBoolean); break; - case IR.VM.PutFloat32 putFloat32: Compile(putFloat32); break; - case IR.VM.PutInt32 putInt32: Compile(putInt32); break; - case IR.VM.PutNull putNull: Compile(putNull); break; - case IR.VM.PutString putString: Compile(putString); break; - case IR.VM.Return @return: Compile(@return); break; - case IR.VM.SetArgument setArgument: Compile(setArgument); break; - case IR.VM.SetField setField: Compile(setField); break; - case IR.VM.SetGlobal setGlobal: Compile(setGlobal); break; - case IR.VM.SetLocal setLocal: Compile(setLocal); break; - case IR.VM.Swap swap: Compile(swap); break; - - default: throw new NotImplementedException(); - } - } - } -} diff --git a/ZSharp.Runtime.IL/ir2il/loaders/code/ICodeLoader.cs b/ZSharp.Runtime.IL/ir2il/loaders/code/ICodeLoader.cs deleted file mode 100644 index 4003409d..00000000 --- a/ZSharp.Runtime.IL/ir2il/loaders/code/ICodeLoader.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace ZSharp.Runtime.NET.IR2IL -{ - public interface ICodeLoader - { - public IL.Emit.ILGenerator Output { get; } - - public void Push(Type type); - - public void Pop(); - - public void Pop(Type type); - - public void Pop(params Type[] types); - } -} diff --git a/ZSharp.Runtime.IL/ir2il/loaders/code/Parameter.cs b/ZSharp.Runtime.IL/ir2il/loaders/code/Parameter.cs deleted file mode 100644 index 8d5f8a5e..00000000 --- a/ZSharp.Runtime.IL/ir2il/loaders/code/Parameter.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace ZSharp.Runtime.NET.IR2IL -{ - internal sealed class Parameter - { - public required string Name { get; set; } - - public required Type Type { get; set; } - - public int Position { get; set; } - } -} diff --git a/ZSharp.Runtime.IL/ir2il/loaders/code/ThisParameter.cs b/ZSharp.Runtime.IL/ir2il/loaders/code/ThisParameter.cs deleted file mode 100644 index a0e224d3..00000000 --- a/ZSharp.Runtime.IL/ir2il/loaders/code/ThisParameter.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace ZSharp.Runtime.NET.IR2IL -{ - internal class ThisParameter(Type declaringType) : IL.ParameterInfo - { - public override Type ParameterType => declaringType; - - public override string Name => "this"; - - public override int Position => 0; - - public override IL.ParameterAttributes Attributes => IL.ParameterAttributes.None; - - public override object? DefaultValue => null; - - public override bool HasDefaultValue => false; - } -} diff --git a/ZSharp.Runtime.IL/objects/TypeObject.cs b/ZSharp.Runtime.IL/objects/TypeObject.cs deleted file mode 100644 index 6426de40..00000000 --- a/ZSharp.Runtime.IL/objects/TypeObject.cs +++ /dev/null @@ -1,17 +0,0 @@ -using ZSharp.Objects; - -namespace ZSharp.Runtime.NET -{ - internal sealed class TypeObject(Type il, IR.IType ir, CompilerObject co) - : ICompileTime - { - public Type IL { get; } = il; - - public IR.IType IR { get; } = ir; - - public CompilerObject CO { get; } = co; - - public CompilerObject GetCO() - => CO; - } -} diff --git a/ZSharp.SourceCompiler.Common/CompileExpression.cs b/ZSharp.SourceCompiler.Common/CompileExpression.cs new file mode 100644 index 00000000..415f7356 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/CompileExpression.cs @@ -0,0 +1,4 @@ +namespace ZSharp.SourceCompiler +{ + public delegate IResult CompileExpression(AST.Expression expression); +} diff --git a/ZSharp.SourceCompiler.Common/GlobalUsings.cs b/ZSharp.SourceCompiler.Common/GlobalUsings.cs new file mode 100644 index 00000000..e7d94052 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/GlobalUsings.cs @@ -0,0 +1,4 @@ +global using ZSharp.Compiler; + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.SourceCompiler.Common/TaskManager.cs b/ZSharp.SourceCompiler.Common/TaskManager.cs new file mode 100644 index 00000000..a66a4bd8 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/TaskManager.cs @@ -0,0 +1,20 @@ +namespace ZSharp.SourceCompiler +{ + public sealed class TaskManager(Action init) + { + private List thisTasks = [init], nextTasks = []; + + public void AddTask(Action task) + => nextTasks.Add(task); + + public void RunUntilComplete() + { + while (thisTasks.Count > 0) + { + foreach (var task in thisTasks) task(); + (thisTasks, nextTasks) = (nextTasks, thisTasks); + nextTasks.Clear(); + } + } + } +} diff --git a/ZSharp.SourceCompiler.Common/ZSharp.SourceCompiler.Common.csproj b/ZSharp.SourceCompiler.Common/ZSharp.SourceCompiler.Common.csproj new file mode 100644 index 00000000..f7aac97a --- /dev/null +++ b/ZSharp.SourceCompiler.Common/ZSharp.SourceCompiler.Common.csproj @@ -0,0 +1,14 @@ + + + + net9.0 + enable + enable + + + + + + + + diff --git a/ZSharp.SourceCompiler.Common/expression compiler/ExpressionCompiler.Compile.cs b/ZSharp.SourceCompiler.Common/expression compiler/ExpressionCompiler.Compile.cs new file mode 100644 index 00000000..72d94b1a --- /dev/null +++ b/ZSharp.SourceCompiler.Common/expression compiler/ExpressionCompiler.Compile.cs @@ -0,0 +1,19 @@ +namespace ZSharp.SourceCompiler +{ + public delegate IResult PostProcess(IResult result); + + partial class ExpressionCompiler + { + public PostProcess PostProcess { get; init; } = r => r; + + public IResult Compile(AST.Expression expression) + => PostProcess(expression switch + { + AST.BinaryExpression binary => Compile(binary), + AST.CallExpression call => Compile(call), + AST.IdentifierExpression identifier => Compile(identifier), + AST.LiteralExpression literal => Compile(literal), + _ => Result.Error($"Invalid expression type: {expression.GetType().Name}"), + }); + } +} diff --git a/ZSharp.SourceCompiler.Common/expression compiler/ExpressionCompiler.T.cs b/ZSharp.SourceCompiler.Common/expression compiler/ExpressionCompiler.T.cs new file mode 100644 index 00000000..ff8ea125 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/expression compiler/ExpressionCompiler.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + partial class ExpressionCompiler + { + + } +} diff --git a/ZSharp.SourceCompiler.Common/expression compiler/ExpressionCompiler.cs b/ZSharp.SourceCompiler.Common/expression compiler/ExpressionCompiler.cs new file mode 100644 index 00000000..00d42a42 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/expression compiler/ExpressionCompiler.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + public sealed partial class ExpressionCompiler(Interpreter.Interpreter interpreter) + { + public Interpreter.Interpreter Interpreter { get; } = interpreter; + } +} diff --git a/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Binary.cs b/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Binary.cs new file mode 100644 index 00000000..d9a9bf86 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Binary.cs @@ -0,0 +1,31 @@ +namespace ZSharp.SourceCompiler +{ + partial class ExpressionCompiler + { + private IResult Compile(AST.BinaryExpression binary) + { + if ( + Compile(binary.Left) + .When(out var left) + .Error(out var error) + ) return Result.Error(error); + + if (binary.Operator == ".") // Special case ??? :( + { + if (binary.Right is AST.IdentifierExpression identifier) + return Interpreter.Compiler.CG.Member(left!, identifier.Name); + } + + if ( + Compile(binary.Right) + .When(out var right) + .Error(out error) + ) return Result.Error(error); + + if (!Interpreter.Operators.Op(binary.Operator, out var @operator)) + return Result.Error($"Unknown operator '{binary.Operator}'"); + + return Interpreter.Compiler.CG.Call(@operator, [ new(left!), new(right!) ]); + } + } +} diff --git a/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Call.cs b/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Call.cs new file mode 100644 index 00000000..659163f0 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Call.cs @@ -0,0 +1,45 @@ +namespace ZSharp.SourceCompiler +{ + partial class ExpressionCompiler + { + private IResult Compile(AST.CallExpression call) + { + var calleeResult = Compile(call.Callee); + + if ( + calleeResult + .When(out var callee) + .Error(out var errorMessage) + ) return Result.Error( + $"Failed to compile callee: {errorMessage}" + ); + + var argumentResults = call.Arguments + .Select>(arg => + { + if ( + Compile(arg.Value) + .When(out var argValue) + .Error(out var error) + ) return Result.Error(error); + + return Result.Ok( + new( + arg.Name, + argValue! + ) + ); + }) + .ToList(); + + if (argumentResults.Any(r => r.IsError)) + return Result.Error( + $"Failed to compile arguments: { + (string.Join(", ", Enumerable.Where(argumentResults, (r => r.IsError)).Select(r => r.UnwrapError()))) + }" + ); + + return Interpreter.Compiler.CG.Call(callee!, [.. argumentResults.Select(r => r.Unwrap())]); + } + } +} diff --git a/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Identifier.cs b/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Identifier.cs new file mode 100644 index 00000000..fd1bac64 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Identifier.cs @@ -0,0 +1,16 @@ +namespace ZSharp.SourceCompiler +{ + partial class ExpressionCompiler + { + private IResult Compile(AST.IdentifierExpression identifier) + { + foreach (var scope in Interpreter.Compiler.CurrentContext.FindContext()) + if (scope.Get(identifier.Name).Ok(out var result)) + return Result.Ok(result); + + return Result.Error( + $"Identifier '{identifier.Name}' not found." + ); + } + } +} diff --git a/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Literal.cs b/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Literal.cs new file mode 100644 index 00000000..13d2e017 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/expression compiler/compile/ExpressionCompiler.Compile.Literal.cs @@ -0,0 +1,13 @@ +namespace ZSharp.SourceCompiler +{ + partial class ExpressionCompiler + { + private IResult Compile(AST.LiteralExpression literal) + { + if (literal.UnitType is not null) + Interpreter.Log.Warning($"Literal has a unit type '{literal.UnitType}' which will be ignored.", new NodeLogOrigin(literal)); + + return new LiteralCompiler(Interpreter).Compile(literal); + } + } +} diff --git a/ZSharp.SourceCompiler.Common/extensions/LoggerExtensions.cs b/ZSharp.SourceCompiler.Common/extensions/LoggerExtensions.cs new file mode 100644 index 00000000..b2577c70 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/extensions/LoggerExtensions.cs @@ -0,0 +1,10 @@ +using ZSharp.Logging; + +namespace ZSharp.SourceCompiler +{ + public static class LoggerExtensions + { + public static void Error(this Logger logger, T message, AST.Node node) + => logger.Error(message, new NodeLogOrigin(node)); + } +} diff --git a/ZSharp.SourceCompiler.Common/importers/CoreLibraryImporter.cs b/ZSharp.SourceCompiler.Common/importers/CoreLibraryImporter.cs new file mode 100644 index 00000000..547e954b --- /dev/null +++ b/ZSharp.SourceCompiler.Common/importers/CoreLibraryImporter.cs @@ -0,0 +1,19 @@ +namespace ZSharp.SourceCompiler +{ + public sealed class CoreLibraryImporter + : IStringImporter + { + private readonly Dictionary libraries = []; + + public void Add(string name, CompilerObject obj) + => libraries.Add(name, obj); + + IResult IStringImporter.Import(string source) + { + if (libraries.TryGetValue(source, out var result)) + return Result.Ok(result); + + return Result.Error($"Could not find core library '{source}'"); + } + } +} diff --git a/ZSharp.SourceCompiler.Common/importers/StandardLibraryImporter.cs b/ZSharp.SourceCompiler.Common/importers/StandardLibraryImporter.cs new file mode 100644 index 00000000..3eec364c --- /dev/null +++ b/ZSharp.SourceCompiler.Common/importers/StandardLibraryImporter.cs @@ -0,0 +1,19 @@ +namespace ZSharp.SourceCompiler +{ + public sealed class StandardLibraryImporter + : IStringImporter + { + private readonly Dictionary libraries = []; + + public void Add(string name, CompilerObject obj) + => libraries.Add(name, obj); + + IResult IStringImporter.Import(string source) + { + if (libraries.TryGetValue(source, out var result)) + return Result.Ok(result); + + return Result.Error($"Could not find standard library '{source}'"); + } + } +} diff --git a/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.Compile.Boolean.cs b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.Compile.Boolean.cs new file mode 100644 index 00000000..0202c2d6 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.Compile.Boolean.cs @@ -0,0 +1,11 @@ +namespace ZSharp.SourceCompiler +{ + partial class LiteralCompiler + { + private IResult CompileFalse(AST.LiteralExpression expression) + => Result.Ok(new BooleanLiteral(false)); + + private IResult CompileTrue(AST.LiteralExpression expression) + => Result.Ok(new BooleanLiteral(true)); + } +} diff --git a/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.Compile.String.cs b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.Compile.String.cs new file mode 100644 index 00000000..687f184e --- /dev/null +++ b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.Compile.String.cs @@ -0,0 +1,10 @@ +namespace ZSharp.SourceCompiler +{ + partial class LiteralCompiler + { + private IResult CompileString(AST.LiteralExpression expression) + { + return Interpreter.RTLoader.Load(expression.Value); + } + } +} diff --git a/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.Compile.cs b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.Compile.cs new file mode 100644 index 00000000..6505153f --- /dev/null +++ b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.Compile.cs @@ -0,0 +1,20 @@ +namespace ZSharp.SourceCompiler +{ + partial class LiteralCompiler + { + public IResult Compile(AST.LiteralExpression expression) + => expression.Type switch + { + AST.LiteralType.String => CompileString(expression), + AST.LiteralType.Number => NotImplemented(expression), + AST.LiteralType.Decimal => NotImplemented(expression), + AST.LiteralType.Null => NotImplemented(expression), + AST.LiteralType.True => CompileTrue(expression), + AST.LiteralType.False => CompileFalse(expression), + _ => Result.Error($"Invalid literal type: {expression.Type}"), + }; + + private IResult NotImplemented(AST.LiteralExpression expression) + => Result.Error($"Literal type not implemented: {expression.Type}"); + } +} diff --git a/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.T.cs b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.T.cs new file mode 100644 index 00000000..82076324 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + partial class LiteralCompiler + { + + } +} diff --git a/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.cs b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.cs new file mode 100644 index 00000000..c54aec01 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/literal compiler/LiteralCompiler.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + public sealed partial class LiteralCompiler(Interpreter.Interpreter interpreter) + { + public Interpreter.Interpreter Interpreter { get; } = interpreter; + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/code/block/CodeBlock.Content.cs b/ZSharp.SourceCompiler.Common/objects/code/block/CodeBlock.Content.cs new file mode 100644 index 00000000..7a813844 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/code/block/CodeBlock.Content.cs @@ -0,0 +1,9 @@ +using CommonZ.Utils; + +namespace ZSharp.SourceCompiler +{ + partial class CodeBlock + { + public Collection Content { get; } = []; + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/code/block/CodeBlock.IR.cs b/ZSharp.SourceCompiler.Common/objects/code/block/CodeBlock.IR.cs new file mode 100644 index 00000000..276db0e0 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/code/block/CodeBlock.IR.cs @@ -0,0 +1,25 @@ + +namespace ZSharp.SourceCompiler +{ + partial class CodeBlock + : ICompileIRCode + { + IResult ICompileIRCode.CompileIRCode(Compiler.Compiler compiler, object? target) + { + var code = new IRCode(); + + foreach (var statement in Content) + { + if ( + compiler.IR.CompileCode(statement, target) + .When(out var statementCode) + .Error(out var error) + ) return Result.Error(error); + code.Instructions.AddRange(statementCode!.Instructions); + code.Types.AddRange(statementCode.Types); + } + + return Result.Ok(code); + } + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/code/block/CodeBlock.cs b/ZSharp.SourceCompiler.Common/objects/code/block/CodeBlock.cs new file mode 100644 index 00000000..3583e87d --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/code/block/CodeBlock.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + public sealed partial class CodeBlock + : CompilerObject + { + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/code/return/Return.IR.cs b/ZSharp.SourceCompiler.Common/objects/code/return/Return.IR.cs new file mode 100644 index 00000000..6639e749 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/code/return/Return.IR.cs @@ -0,0 +1,25 @@ + +namespace ZSharp.SourceCompiler +{ + partial class Return + : ICompileIRCode + { + IResult ICompileIRCode.CompileIRCode(Compiler.Compiler compiler, object? target) + { + var code = new IRCode(); + + if (Value is not null) + if ( + compiler.IR.CompileCode(Value, target) + .When(out var valueCode) + .Error(out var error) + ) return Result.Error(error); + else code.Append(valueCode!); + + code.Instructions.Add(new IR.VM.Return()); + code.Types.Clear(); + + return Result.Ok(code); + } + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/code/return/Return.Value.cs b/ZSharp.SourceCompiler.Common/objects/code/return/Return.Value.cs new file mode 100644 index 00000000..859cd2d6 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/code/return/Return.Value.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + partial class Return + { + public CompilerObject? Value { get; set; } + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/code/return/Return.cs b/ZSharp.SourceCompiler.Common/objects/code/return/Return.cs new file mode 100644 index 00000000..ff92a9e4 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/code/return/Return.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + public sealed partial class Return + : CompilerObject + { + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/literals/bool/BooleanLiteral.IR.cs b/ZSharp.SourceCompiler.Common/objects/literals/bool/BooleanLiteral.IR.cs new file mode 100644 index 00000000..ffb5c731 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/literals/bool/BooleanLiteral.IR.cs @@ -0,0 +1,16 @@ +namespace ZSharp.SourceCompiler +{ + partial class BooleanLiteral + : ICompileIRCode + { + IResult ICompileIRCode.CompileIRCode(Compiler.Compiler compiler, object? target) + => Result.Ok( + new([ + new IR.VM.PutBoolean(value) + ]) + { + Types = [compiler.IR.RuntimeModule.TypeSystem.Boolean] + } + ); + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/literals/bool/BooleanLiteral.cs b/ZSharp.SourceCompiler.Common/objects/literals/bool/BooleanLiteral.cs new file mode 100644 index 00000000..00790db3 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/literals/bool/BooleanLiteral.cs @@ -0,0 +1,8 @@ +namespace ZSharp.SourceCompiler +{ + internal sealed partial class BooleanLiteral(bool value) + : CompilerObject + { + private readonly bool value = value; + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/literals/string/StringLiteral.IR.cs b/ZSharp.SourceCompiler.Common/objects/literals/string/StringLiteral.IR.cs new file mode 100644 index 00000000..8199121b --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/literals/string/StringLiteral.IR.cs @@ -0,0 +1,16 @@ +namespace ZSharp.SourceCompiler +{ + partial class StringLiteral + : ICompileIRCode + { + IResult ICompileIRCode.CompileIRCode(Compiler.Compiler compiler, object? target) + => Result.Ok( + new([ + new IR.VM.PutString(value) + ]) + { + Types = [compiler.IR.RuntimeModule.TypeSystem.String] + } + ); + } +} diff --git a/ZSharp.SourceCompiler.Common/objects/literals/string/StringLiteral.cs b/ZSharp.SourceCompiler.Common/objects/literals/string/StringLiteral.cs new file mode 100644 index 00000000..529a2471 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/objects/literals/string/StringLiteral.cs @@ -0,0 +1,8 @@ +namespace ZSharp.SourceCompiler +{ + internal sealed partial class StringLiteral(string value) + : CompilerObject + { + private readonly string value = value; + } +} diff --git a/ZSharp.SourceCompiler.Common/top-level expression compiler/TopLevelExpressionCompiler.cs b/ZSharp.SourceCompiler.Common/top-level expression compiler/TopLevelExpressionCompiler.cs new file mode 100644 index 00000000..06f660e8 --- /dev/null +++ b/ZSharp.SourceCompiler.Common/top-level expression compiler/TopLevelExpressionCompiler.cs @@ -0,0 +1,14 @@ +namespace ZSharp.SourceCompiler +{ + public sealed class TopLevelExpressionCompiler(Interpreter.Interpreter interpreter) + { + public Interpreter.Interpreter Interpreter { get; } = interpreter; + + public Func CompileExpression { get; init; } = new ExpressionCompiler(interpreter).Compile; + + public Func LoadCO { get; init; } = interpreter.RTLoader.Load; + + public IResult Compile(AST.Expression expression) + => CompileExpression(expression); + } +} diff --git a/ZSharp.SourceCompiler.Core/GlobalUsings.cs b/ZSharp.SourceCompiler.Core/GlobalUsings.cs new file mode 100644 index 00000000..d2fb58a6 --- /dev/null +++ b/ZSharp.SourceCompiler.Core/GlobalUsings.cs @@ -0,0 +1,3 @@ +global using ZSharp.Compiler; + +global using IResult = IResult; diff --git a/ZSharp.SourceCompiler.Core/NodeLogOrigin.cs b/ZSharp.SourceCompiler.Core/NodeLogOrigin.cs new file mode 100644 index 00000000..75ad82b8 --- /dev/null +++ b/ZSharp.SourceCompiler.Core/NodeLogOrigin.cs @@ -0,0 +1,12 @@ +namespace ZSharp.SourceCompiler +{ + public sealed class NodeLogOrigin(AST.Node origin) : Logging.LogOrigin + { + public AST.Node Origin { get; } = origin; + + public override string? ToString() + { + return Origin.TokenInfo?.ToString(); + } + } +} diff --git a/ZSharp.SourceCompiler.Core/ZSharp.SourceCompiler.Core.csproj b/ZSharp.SourceCompiler.Core/ZSharp.SourceCompiler.Core.csproj new file mode 100644 index 00000000..332419c5 --- /dev/null +++ b/ZSharp.SourceCompiler.Core/ZSharp.SourceCompiler.Core.csproj @@ -0,0 +1,15 @@ + + + + net9.0 + enable + enable + ZSharp.SourceCompiler + + + + + + + + diff --git a/ZSharp.SourceCompiler.Core/context/Context.ImportSystem.cs b/ZSharp.SourceCompiler.Core/context/Context.ImportSystem.cs new file mode 100644 index 00000000..26733d0d --- /dev/null +++ b/ZSharp.SourceCompiler.Core/context/Context.ImportSystem.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + partial class Context + { + public ImportSystem ImportSystem { get; init; } = new(); + } +} diff --git a/ZSharp.SourceCompiler.Core/context/Context.Operators.cs b/ZSharp.SourceCompiler.Core/context/Context.Operators.cs new file mode 100644 index 00000000..64aaa8d4 --- /dev/null +++ b/ZSharp.SourceCompiler.Core/context/Context.Operators.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + partial class Context + { + + } +} diff --git a/ZSharp.SourceCompiler.Core/context/Context.T.cs b/ZSharp.SourceCompiler.Core/context/Context.T.cs new file mode 100644 index 00000000..e7ab9d35 --- /dev/null +++ b/ZSharp.SourceCompiler.Core/context/Context.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + partial class Context + { + + } +} diff --git a/ZSharp.Runtime.IL/context/Context.cs b/ZSharp.SourceCompiler.Core/context/Context.cs similarity index 56% rename from ZSharp.Runtime.IL/context/Context.cs rename to ZSharp.SourceCompiler.Core/context/Context.cs index 458a9d91..2e32d7bf 100644 --- a/ZSharp.Runtime.IL/context/Context.cs +++ b/ZSharp.SourceCompiler.Core/context/Context.cs @@ -1,7 +1,7 @@ -namespace ZSharp.Runtime.NET +namespace ZSharp.SourceCompiler { public sealed partial class Context { - + } } diff --git a/ZSharp.SourceCompiler.Core/custom importer/string importer/IStringImporter.cs b/ZSharp.SourceCompiler.Core/custom importer/string importer/IStringImporter.cs new file mode 100644 index 00000000..2f5ecea0 --- /dev/null +++ b/ZSharp.SourceCompiler.Core/custom importer/string importer/IStringImporter.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler +{ + public interface IStringImporter + { + public IResult Import(string source); + } +} diff --git a/ZSharp.SourceCompiler.Core/custom importer/string importer/StringImporter.cs b/ZSharp.SourceCompiler.Core/custom importer/string importer/StringImporter.cs new file mode 100644 index 00000000..6f57ed7b --- /dev/null +++ b/ZSharp.SourceCompiler.Core/custom importer/string importer/StringImporter.cs @@ -0,0 +1,47 @@ +using CommonZ.Utils; +using ZSharp.Compiler; + +namespace ZSharp.SourceCompiler +{ + public sealed class StringImporter + : IStringImporter + { + private readonly Mapping customStringImporters = []; + + public IStringImporter? DefaultImporter { get; set; } + + public IResult Import(string source) + { + var parts = source.Split(':', count: 2, options: StringSplitOptions.TrimEntries); + if (parts.Length > 1) + { + if (!customStringImporters.TryGetValue(parts[0], out var importer)) + return Result.Error( + $"No string importer registered for prefix '{parts[0]}'." + ); + + return importer.Import(parts[1]); + } + + if (parts.Length == 0) + return Result.Error("Source string is empty."); + + if (DefaultImporter is null) + return Result.Error("No default string importer is set."); + + if (DefaultImporter == this) + return Result.Error("Default string importer cannot be itself."); + + return DefaultImporter.Import(parts[0]); + } + + public void RegisterImporter(string prefix, IStringImporter importer) + { + if (string.IsNullOrWhiteSpace(prefix)) + throw new ArgumentException("Prefix cannot be null or whitespace.", nameof(prefix)); + if (importer is null) + throw new ArgumentNullException(nameof(importer), "Importer cannot be null."); + customStringImporters[prefix] = importer; + } + } +} diff --git a/ZSharp.SourceCompiler.Core/import system/ImportSystem.cs b/ZSharp.SourceCompiler.Core/import system/ImportSystem.cs new file mode 100644 index 00000000..9f66eb77 --- /dev/null +++ b/ZSharp.SourceCompiler.Core/import system/ImportSystem.cs @@ -0,0 +1,9 @@ +using ZSharp.Compiler; + +namespace ZSharp.SourceCompiler +{ + public sealed class ImportSystem + { + public CompilerObject? ImportFunction { get; set; } + } +} diff --git a/ZSharp.SourceCompiler.Core/operator table/OperatorTable.cs b/ZSharp.SourceCompiler.Core/operator table/OperatorTable.cs new file mode 100644 index 00000000..6fb38ca2 --- /dev/null +++ b/ZSharp.SourceCompiler.Core/operator table/OperatorTable.cs @@ -0,0 +1,34 @@ +global using Operator = string; + +using CommonZ.Utils; +using System.Diagnostics.CodeAnalysis; + +using CompilerObject = ZSharp.Compiler.CompilerObject; + +namespace ZSharp.SourceCompiler +{ + public sealed class OperatorTable() + { + private readonly Cache operators = new(); + + internal OperatorTable(OperatorTable? parent = null) + : this() + { + operators = new() + { + Parent = parent?.operators + }; + } + + public void Op(Operator op, CompilerObject obj) + => operators.Cache(op, obj); // TODO: on add + + public CompilerObject? Op(Operator op) + => operators.Cache(op); + + public bool Op(Operator op, [NotNullWhen(true)] out CompilerObject? obj) + => (obj = Op(op)) is not null; + + public OperatorTable CreateChild() => new(this); + } +} diff --git a/ZSharp.SourceCompiler.Module/GlobalUsings.cs b/ZSharp.SourceCompiler.Module/GlobalUsings.cs new file mode 100644 index 00000000..f923ef3b --- /dev/null +++ b/ZSharp.SourceCompiler.Module/GlobalUsings.cs @@ -0,0 +1,8 @@ +global using ZSharp.Compiler; + +global using MemberName = string; +global using MemberIndex = int; + + +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.SourceCompiler.Module/ZSharp.SourceCompiler.Module.csproj b/ZSharp.SourceCompiler.Module/ZSharp.SourceCompiler.Module.csproj new file mode 100644 index 00000000..6c620a58 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/ZSharp.SourceCompiler.Module.csproj @@ -0,0 +1,34 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ZSharp.SourceCompiler.Module/capabilities/IModuleMember.cs b/ZSharp.SourceCompiler.Module/capabilities/IModuleMember.cs new file mode 100644 index 00000000..d1f6de54 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/capabilities/IModuleMember.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module +{ + public interface IModuleMember + { + public CompilerObject Module { get; } + } +} diff --git a/ZSharp.SourceCompiler.Module/capabilities/functional/IParameter.cs b/ZSharp.SourceCompiler.Module/capabilities/functional/IParameter.cs new file mode 100644 index 00000000..a94b479a --- /dev/null +++ b/ZSharp.SourceCompiler.Module/capabilities/functional/IParameter.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module +{ + public interface IParameter + { + + } +} diff --git a/ZSharp.SourceCompiler.Module/capabilities/functional/ISignature.cs b/ZSharp.SourceCompiler.Module/capabilities/functional/ISignature.cs new file mode 100644 index 00000000..f604d198 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/capabilities/functional/ISignature.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZSharp.SourceCompiler.Module +{ + internal interface ISignature + { + } +} diff --git a/ZSharp.SourceCompiler.Module/class compiler/ClassCompiler.Log.cs b/ZSharp.SourceCompiler.Module/class compiler/ClassCompiler.Log.cs new file mode 100644 index 00000000..4263f406 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/class compiler/ClassCompiler.Log.cs @@ -0,0 +1,18 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ClassCompiler + { + private readonly List> logs = []; + + public void Error(string message, Logging.LogOrigin origin) + => logs.Add(new() + { + Level = Logging.LogLevel.Error, + Message = message, + Origin = origin + }); + + public void Error(string message, AST.Node node) + => Error(message, new NodeLogOrigin(node)); + } +} diff --git a/ZSharp.SourceCompiler.Module/class compiler/ClassCompiler.Tasks.cs b/ZSharp.SourceCompiler.Module/class compiler/ClassCompiler.Tasks.cs new file mode 100644 index 00000000..208118be --- /dev/null +++ b/ZSharp.SourceCompiler.Module/class compiler/ClassCompiler.Tasks.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ClassCompiler + { + private readonly TaskManager tasks; + } +} diff --git a/ZSharp.SourceCompiler.Module/class compiler/ClassCompiler.cs b/ZSharp.SourceCompiler.Module/class compiler/ClassCompiler.cs new file mode 100644 index 00000000..dfb644b7 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/class compiler/ClassCompiler.cs @@ -0,0 +1,24 @@ +namespace ZSharp.SourceCompiler.Module +{ + public sealed partial class ClassCompiler + { + private Objects.Module Object { get; } + + private Interpreter.Interpreter Interpreter { get; } + + private AST.Module Node { get; } + + private CompileExpression CompileExpression { get; } + + public ClassCompiler(Interpreter.Interpreter interpreter, AST.Module module) + { + Interpreter = interpreter; + Node = module; + Object = new(); + + CompileExpression = new TopLevelExpressionCompiler(interpreter).Compile; + + tasks = new(InitCompile); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/class compiler/compile/Compile.cs b/ZSharp.SourceCompiler.Module/class compiler/compile/Compile.cs new file mode 100644 index 00000000..2bfc8a8f --- /dev/null +++ b/ZSharp.SourceCompiler.Module/class compiler/compile/Compile.cs @@ -0,0 +1,43 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ClassCompiler + { + public IResult Declare() + { + tasks.RunUntilComplete(); + + if (logs.Count > 0) + { + // TODO: Aggregate errors properly + + var sb = new System.Text.StringBuilder(); + + foreach (var log in logs) + sb.AppendLine(log.ToString()); + + return Result.Error(sb.ToString()); + } + + + return Result.Ok(Object); + } + + private void InitCompile() + { + foreach (var statement in Node.Body) + if (Compile(statement).Error(out var error)) + Error( + $"Failed to compile statement: {error}", + new NodeLogOrigin(statement) + ); + } + + private IResult Compile(AST.Statement statement) + => statement switch + { + AST.DefinitionStatement definitionStatement => Compile(definitionStatement), + AST.ExpressionStatement expressionStatement => Compile(expressionStatement), + _ => Result.Error($"Unknown statement type: {statement.GetType().Name}") + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/class compiler/compile/expr/Call.cs b/ZSharp.SourceCompiler.Module/class compiler/compile/expr/Call.cs new file mode 100644 index 00000000..6e1f835e --- /dev/null +++ b/ZSharp.SourceCompiler.Module/class compiler/compile/expr/Call.cs @@ -0,0 +1,45 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ClassCompiler + { + private IResult Compile(AST.CallExpression call) + { + var calleeResult = Compile(call.Callee); + + if ( + calleeResult + .When(out var callee) + .Error(out var errorMessage) + ) return Result.Error( + $"Failed to compile callee: {errorMessage}" + ); + + var argumentResults = call.Arguments + .Select>(arg => + { + if ( + Compile(arg.Value) + .When(out var argValue) + .Error(out var error) + ) return Result.Error(error); + + return Result.Ok( + new( + arg.Name, + argValue! + ) + ); + }) + .ToList(); + + if (argumentResults.Any(r => r.IsError)) + return Result.Error( + $"Failed to compile arguments: { + (string.Join(", ", Enumerable.Where(argumentResults, (r => r.IsError)).Select(r => r.UnwrapError()))) + }" + ); + + return Interpreter.Compiler.CG.Call(callee!, [.. argumentResults.Select(r => r.Unwrap())]); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/class compiler/compile/expr/Expression.cs b/ZSharp.SourceCompiler.Module/class compiler/compile/expr/Expression.cs new file mode 100644 index 00000000..5837c534 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/class compiler/compile/expr/Expression.cs @@ -0,0 +1,12 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ClassCompiler + { + private IResult Compile(AST.Expression expression) + => expression switch + { + AST.Function function => Compile(function), + _ => CompileExpression(expression) + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/class compiler/compile/expr/Function.cs b/ZSharp.SourceCompiler.Module/class compiler/compile/expr/Function.cs new file mode 100644 index 00000000..1c88924e --- /dev/null +++ b/ZSharp.SourceCompiler.Module/class compiler/compile/expr/Function.cs @@ -0,0 +1,24 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ClassCompiler + { + private IResult Compile(AST.Function function) + { + var compiler = new FunctionCompiler(Interpreter, function); + + var result = compiler.Declare(); + + tasks.AddTask(() => + { + compiler.CompileSignature(); + + tasks.AddTask(() => + { + compiler.CompileBody(); + }); + }); + + return result; + } + } +} diff --git a/ZSharp.SourceCompiler.Module/class compiler/compile/stmt/Definition.cs b/ZSharp.SourceCompiler.Module/class compiler/compile/stmt/Definition.cs new file mode 100644 index 00000000..506d6b12 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/class compiler/compile/stmt/Definition.cs @@ -0,0 +1,12 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ClassCompiler + { + private IResult Compile(AST.DefinitionStatement definitionStatement) + => definitionStatement.Definition switch + { + AST.Function function => Compile(function), + _ => Result.Error($"Unknown definition type: {definitionStatement.Definition.GetType().Name}") + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/class compiler/compile/stmt/Expression.cs b/ZSharp.SourceCompiler.Module/class compiler/compile/stmt/Expression.cs new file mode 100644 index 00000000..3bc8d570 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/class compiler/compile/stmt/Expression.cs @@ -0,0 +1,8 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ClassCompiler + { + private IResult Compile(AST.ExpressionStatement expressionStatement) + => CompileExpression(expressionStatement.Expression); + } +} diff --git a/ZSharp.SourceCompiler.Module/contexts/modular/FunctionContext.cs b/ZSharp.SourceCompiler.Module/contexts/modular/FunctionContext.cs new file mode 100644 index 00000000..11433591 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/contexts/modular/FunctionContext.cs @@ -0,0 +1,11 @@ +namespace ZSharp.SourceCompiler.Module.Contexts +{ + internal sealed class FunctionContext(Objects.Function function) + : IContext + , IObjectContext + { + public IContext? Parent { get; set; } + + public Objects.Function Object { get; } = function; + } +} diff --git a/ZSharp.SourceCompiler.Module/contexts/modular/ModuleContext.cs b/ZSharp.SourceCompiler.Module/contexts/modular/ModuleContext.cs new file mode 100644 index 00000000..31c45f88 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/contexts/modular/ModuleContext.cs @@ -0,0 +1,6 @@ +namespace ZSharp.SourceCompiler.Module.Contexts +{ + internal sealed class ModuleContext + { + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/FunctionBodyCompiler.T.cs b/ZSharp.SourceCompiler.Module/function body compiler/FunctionBodyCompiler.T.cs new file mode 100644 index 00000000..01c990dd --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/FunctionBodyCompiler.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionBodyCompiler + { + + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/FunctionBodyCompiler.cs b/ZSharp.SourceCompiler.Module/function body compiler/FunctionBodyCompiler.cs new file mode 100644 index 00000000..35207b07 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/FunctionBodyCompiler.cs @@ -0,0 +1,19 @@ +namespace ZSharp.SourceCompiler.Module +{ + internal sealed partial class FunctionBodyCompiler + { + private Interpreter.Interpreter Interpreter { get; } + + private AST.Statement Node { get; } + + private CompileExpression CompileExpression { get; } + + public FunctionBodyCompiler(Interpreter.Interpreter interpreter, AST.Statement body) + { + Interpreter = interpreter; + Node = body; + + CompileExpression = new ExpressionCompiler(interpreter).Compile; + } + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/compile/FunctionBodyCompiler.Compile.cs b/ZSharp.SourceCompiler.Module/function body compiler/compile/FunctionBodyCompiler.Compile.cs new file mode 100644 index 00000000..c11455a8 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/compile/FunctionBodyCompiler.Compile.cs @@ -0,0 +1,8 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionBodyCompiler + { + public IResult Compile() + => Compile(Node); + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/compile/expr/FunctionBodyCompiler.Compile.Function.cs b/ZSharp.SourceCompiler.Module/function body compiler/compile/expr/FunctionBodyCompiler.Compile.Function.cs new file mode 100644 index 00000000..ec6e7787 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/compile/expr/FunctionBodyCompiler.Compile.Function.cs @@ -0,0 +1,16 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionBodyCompiler + { + private IResult Compile(AST.Function function) + { + var compiler = new FunctionCompiler(Interpreter, function); + + var result = compiler.Declare(); + compiler.CompileSignature(); + compiler.CompileBody(); + + return result; + } + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/compile/expr/FunctionBodyCompiler.Compile.cs b/ZSharp.SourceCompiler.Module/function body compiler/compile/expr/FunctionBodyCompiler.Compile.cs new file mode 100644 index 00000000..446b7be6 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/compile/expr/FunctionBodyCompiler.Compile.cs @@ -0,0 +1,12 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionBodyCompiler + { + private IResult Compile(AST.Expression expression) + => expression switch + { + AST.Function function => Compile(function), + _ => CompileExpression(expression), + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.Block.cs b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.Block.cs new file mode 100644 index 00000000..6ff70b39 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.Block.cs @@ -0,0 +1,17 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionBodyCompiler + { + private IResult Compile(AST.BlockStatement block) + { + var result = new CodeBlock(); + + foreach (var statement in block.Statements ?? []) + if (Compile(statement).When(out var @object).Error(out var error)) + Interpreter.Log.Error($"{error}", statement); + else result.Content.Add(@object!); + + return Result.Ok(result); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.Definition.cs b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.Definition.cs new file mode 100644 index 00000000..75115bb9 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.Definition.cs @@ -0,0 +1,8 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionBodyCompiler + { + private IResult Compile(AST.DefinitionStatement definitionStatement) + => Compile(definitionStatement.Definition); + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.Expression.cs b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.Expression.cs new file mode 100644 index 00000000..e022b452 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.Expression.cs @@ -0,0 +1,8 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionBodyCompiler + { + private IResult Compile(AST.ExpressionStatement expressionStatement) + => CompileExpression(expressionStatement.Expression); + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.cs b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.cs new file mode 100644 index 00000000..417e74a0 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Compile.cs @@ -0,0 +1,15 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionBodyCompiler + { + private IResult Compile(AST.Statement statement) + => statement switch + { + AST.BlockStatement block => Compile(block), + AST.DefinitionStatement definition => Compile(definition), + AST.ExpressionStatement expression => Compile(expression), + AST.Return @return => Compile(@return), + _ => Result.Error($"Unknown statement type: {statement.GetType().Name}"), + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Return.cs b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Return.cs new file mode 100644 index 00000000..64cf2da3 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function body compiler/compile/stmt/FunctionBodyCompiler.Return.cs @@ -0,0 +1,19 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionBodyCompiler + { + private IResult Compile(AST.Return @return) + { + CompilerObject? value = null; + + if ( + @return.Value is not null && + CompileExpression(@return.Value) + .When(out value) + .Error(out var error) + ) return Result.Error(error); + + return Result.Ok(new Return() { Value = value } ); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/function compiler/FunctionCompiler.Compile.cs b/ZSharp.SourceCompiler.Module/function compiler/FunctionCompiler.Compile.cs new file mode 100644 index 00000000..dab4aa9e --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function compiler/FunctionCompiler.Compile.cs @@ -0,0 +1,79 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionCompiler + { + public IResult Declare() + { + Error? error = null; + + if (Object.Name != string.Empty) + if (!Interpreter + .Compiler + .CurrentContext + .PerformOperation( + scope => !scope.Add(Object.Name, Object).Error(out error) + ) + ) + return Result.Error($"Could not bind function {Node.Name}: {error}"); + + return Result.Ok(Object); + } + + public void CompileSignature() + { + if (Node.ReturnType is null) + Interpreter.Log.Error($"Function {Node.Name} must have a return type.", Node); + else if ( + CompileExpression(Node.ReturnType) + .When(out var returnType) + .Error(out var error) + ) Interpreter.Log.Error($"{error}", Node.ReturnType); + else if ( + Interpreter.Compiler.CG.Get(returnType!) + .When(out returnType) + .Error(out error) + ) Interpreter.Log.Error($"{error}", Node.ReturnType); + else if ( + Interpreter.Compiler.Evaluator.Evaluate(returnType!) + .When(out returnType) + .Error(out error) + ) Interpreter.Log.Error($"{error}", Node.ReturnType); + else Object.ReturnType = returnType; + + if (Node.Signature.VarArgs is not null) + Interpreter.Log.Error("VarArgs functions are obsolete and should not be used.", Node.Signature.VarArgs); + if (Node.Signature.VarKwArgs is not null) + Interpreter.Log.Error("VarKwArgs functions are obsolete and should not be used.", Node.Signature.VarKwArgs); + + foreach (var param in Node.Signature.Args ?? []) + if (Compile(param).When(out var co).Error(out var error)) + Interpreter.Log.Error(error.ToString()!, param); + //else result.Signature.Args.Add(co!); + + foreach (var param in Node.Signature.KwArgs ?? []) + if (Compile(param).When(out var co).Error(out var error)) + Interpreter.Log.Error(error.ToString()!, param); + //else result.Signature.KwArgs.Add(co!); + } + + public void CompileBody() + { + if (Node.Body is null) + return; + + if ( + new FunctionBodyCompiler(Interpreter, Node.Body).Compile() + .When(out var body) + .Error(out var error) + ) + Interpreter.Log.Error(error.ToString()!, Node.Body); + else + Object.Body = body; + } + + private IResult Compile(AST.Parameter parameter) + { + return Result.Error($"Parameter {parameter.Name} did not compile because parameter compilation is not implemented."); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/function compiler/FunctionCompiler.T.cs b/ZSharp.SourceCompiler.Module/function compiler/FunctionCompiler.T.cs new file mode 100644 index 00000000..e4952955 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function compiler/FunctionCompiler.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class FunctionCompiler + { + + } +} diff --git a/ZSharp.SourceCompiler.Module/function compiler/FunctionCompiler.cs b/ZSharp.SourceCompiler.Module/function compiler/FunctionCompiler.cs new file mode 100644 index 00000000..1fec9c91 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/function compiler/FunctionCompiler.cs @@ -0,0 +1,25 @@ +namespace ZSharp.SourceCompiler.Module +{ + internal sealed partial class FunctionCompiler + { + private Interpreter.Interpreter Interpreter { get; } + + private AST.Function Node { get; } + + private Objects.Function Object { get; } + + private CompileExpression CompileExpression { get; } + + public FunctionCompiler(Interpreter.Interpreter interpreter, AST.Function function) + { + Interpreter = interpreter; + Node = function; + Object = new() + { + Name = function.Name, + }; + + CompileExpression = new ExpressionCompiler(interpreter).Compile; + } + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.Log.cs b/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.Log.cs new file mode 100644 index 00000000..4d97a4ea --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.Log.cs @@ -0,0 +1,18 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ModuleCompiler + { + private readonly List> logs = []; + + public void Error(string message, Logging.LogOrigin origin) + => logs.Add(new() + { + Level = Logging.LogLevel.Error, + Message = message, + Origin = origin + }); + + public void Error(string message, AST.Node node) + => Error(message, new NodeLogOrigin(node)); + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.T.cs b/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.T.cs new file mode 100644 index 00000000..d44f86f6 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ModuleCompiler + { + + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.Tasks.cs b/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.Tasks.cs new file mode 100644 index 00000000..9696929b --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.Tasks.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ModuleCompiler + { + private readonly TaskManager tasks; + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.cs b/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.cs new file mode 100644 index 00000000..b78d3640 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/ModuleCompiler.cs @@ -0,0 +1,29 @@ +namespace ZSharp.SourceCompiler.Module +{ + public sealed partial class ModuleCompiler + { + private Objects.Module Object { get; } + + private Interpreter.Interpreter Interpreter { get; } + + private AST.Module Node { get; } + + private CompileExpression CompileExpression { get; } + + public ModuleCompiler(Interpreter.Interpreter interpreter, AST.Module module) + { + Interpreter = interpreter; + Node = module; + Object = new() + { + Name = module.Name + }; + + CompileExpression = new TopLevelExpressionCompiler(interpreter).Compile; + + tasks = new(InitCompile); + } + + public CompilerObject GetObject() => Object; + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/compile/ModuleCompiler.Compile.cs b/ZSharp.SourceCompiler.Module/module compiler/compile/ModuleCompiler.Compile.cs new file mode 100644 index 00000000..53190771 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/compile/ModuleCompiler.Compile.cs @@ -0,0 +1,43 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ModuleCompiler + { + public IResult Compile() + { + tasks.RunUntilComplete(); + + if (logs.Count > 0) + { + // TODO: Aggregate errors properly + + var sb = new System.Text.StringBuilder(); + + foreach (var log in logs) + sb.AppendLine(log.ToString()); + + return Result.Error(sb.ToString()); + } + + + return Result.Ok(Object); + } + + private void InitCompile() + { + foreach (var statement in Node.Body) + if (Compile(statement).Error(out var error)) + Error( + $"Failed to compile statement: {error}", + new NodeLogOrigin(statement) + ); + } + + private IResult Compile(AST.Statement statement) + => statement switch + { + AST.DefinitionStatement definitionStatement => Compile(definitionStatement), + AST.ExpressionStatement expressionStatement => Compile(expressionStatement), + _ => Result.Error($"Unknown statement type: {statement.GetType().Name}") + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/compile/def/ModuleCompiler.Compile.Function.cs b/ZSharp.SourceCompiler.Module/module compiler/compile/def/ModuleCompiler.Compile.Function.cs new file mode 100644 index 00000000..7231ef7c --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/compile/def/ModuleCompiler.Compile.Function.cs @@ -0,0 +1,26 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ModuleCompiler + { + private IResult Compile(AST.Function function) + { + var compiler = new FunctionCompiler(Interpreter, function); + + var result = compiler.Declare(); + + if (result.Ok(out var definition)) + Object.Content.Add(definition); + if ( + function.Name != string.Empty + && (result = Object.AddMember(function.Name, definition!)) + .IsError + ) + return result; + + tasks.AddTask(compiler.CompileSignature); + tasks.AddTask(compiler.CompileBody); + + return result; + } + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/compile/expr/ModuleCompiler.Compile.Call.cs b/ZSharp.SourceCompiler.Module/module compiler/compile/expr/ModuleCompiler.Compile.Call.cs new file mode 100644 index 00000000..74d737bc --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/compile/expr/ModuleCompiler.Compile.Call.cs @@ -0,0 +1,45 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ModuleCompiler + { + private IResult Compile(AST.CallExpression call) + { + var calleeResult = Compile(call.Callee); + + if ( + calleeResult + .When(out var callee) + .Error(out var errorMessage) + ) return Result.Error( + $"Failed to compile callee: {errorMessage}" + ); + + var argumentResults = call.Arguments + .Select>(arg => + { + if ( + Compile(arg.Value) + .When(out var argValue) + .Error(out var error) + ) return Result.Error(error); + + return Result.Ok( + new( + arg.Name, + argValue! + ) + ); + }) + .ToList(); + + if (argumentResults.Any(r => r.IsError)) + return Result.Error( + $"Failed to compile arguments: { + (string.Join(", ", Enumerable.Where(argumentResults, (r => r.IsError)).Select(r => r.UnwrapError()))) + }" + ); + + return Interpreter.Compiler.CG.Call(callee!, [.. argumentResults.Select(r => r.Unwrap())]); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/compile/expr/ModuleCompiler.Compile.Expression.cs b/ZSharp.SourceCompiler.Module/module compiler/compile/expr/ModuleCompiler.Compile.Expression.cs new file mode 100644 index 00000000..cf7d4f9b --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/compile/expr/ModuleCompiler.Compile.Expression.cs @@ -0,0 +1,12 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ModuleCompiler + { + private IResult Compile(AST.Expression expression) + => expression switch + { + AST.Function function => Compile(function), + _ => CompileExpression(expression) + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/compile/stmt/ModuleCompiler.Compile.Definition.cs b/ZSharp.SourceCompiler.Module/module compiler/compile/stmt/ModuleCompiler.Compile.Definition.cs new file mode 100644 index 00000000..0dfb379b --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/compile/stmt/ModuleCompiler.Compile.Definition.cs @@ -0,0 +1,12 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ModuleCompiler + { + private IResult Compile(AST.DefinitionStatement definitionStatement) + => definitionStatement.Definition switch + { + AST.Function function => Compile(function), + _ => Result.Error($"Unknown definition type: {definitionStatement.Definition.GetType().Name}") + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/module compiler/compile/stmt/ModuleCompiler.Compile.Expression.cs b/ZSharp.SourceCompiler.Module/module compiler/compile/stmt/ModuleCompiler.Compile.Expression.cs new file mode 100644 index 00000000..2577fa33 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/module compiler/compile/stmt/ModuleCompiler.Compile.Expression.cs @@ -0,0 +1,23 @@ +namespace ZSharp.SourceCompiler.Module +{ + partial class ModuleCompiler + { + private IResult Compile(AST.ExpressionStatement expressionStatement) + { + var valueObjectResult = Compile(expressionStatement.Expression); + + if ( + valueObjectResult + .When(out var valueObject) + .Error(out var error) + ) + return Result.Error(error); + + Interpreter.Compiler.Evaluator.Evaluate(valueObject!); + return Result.Ok(Objects.EmptyObject.Empty); // it's most likely that the evaluator itself needs + // to return the empty object, although we do need to first cast to void. right now it returns null + // but we can't trust the evaluator saying that null is not valid because it's the only valid value + // for void type. + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/EmptyObject.cs b/ZSharp.SourceCompiler.Module/objects/EmptyObject.cs new file mode 100644 index 00000000..1507a952 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/EmptyObject.cs @@ -0,0 +1,10 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + internal sealed class EmptyObject + : CompilerObject + { + public static CompilerObject Empty { get; } = new EmptyObject(); + + private EmptyObject() { } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/forward reference/EmptyReference.cs b/ZSharp.SourceCompiler.Module/objects/forward reference/EmptyReference.cs new file mode 100644 index 00000000..4311e45f --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/forward reference/EmptyReference.cs @@ -0,0 +1,8 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + internal sealed class EmptyReference + : CompilerObject + { + public static CompilerObject Instance { get; } = new EmptyReference(); + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/forward reference/ForwardReference.cs b/ZSharp.SourceCompiler.Module/objects/forward reference/ForwardReference.cs new file mode 100644 index 00000000..26a682fa --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/forward reference/ForwardReference.cs @@ -0,0 +1,17 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.SourceCompiler.Module.Objects +{ + internal sealed class ForwardReference + : CompilerObject + , IProxy + { + public CompilerObject Inner { get; set; } = EmptyReference.Instance; + + bool CompilerObject.Is([NotNullWhen(true)] out T? result) where T : class + => Inner.Is(out result); + + IResult IProxy.Apply(Func> fn) + => fn(Inner); + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/function/Function.Build.cs b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.Build.cs new file mode 100644 index 00000000..cd99d2dd --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.Build.cs @@ -0,0 +1,20 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Function + { + [Flags] + private enum BuildState + { + Owner = 1 << 0, + Signature = 1 << 1, + Body = 1 << 2, + } + + private readonly ObjectBuildState state = new(); + + [MemberNotNullWhen(true, nameof(IR))] + public bool IsBuilt => IR is not null; + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/function/Function.Call.cs b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.Call.cs new file mode 100644 index 00000000..7f353d9b --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.Call.cs @@ -0,0 +1,35 @@ +using ZSharp.Objects; + +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Function + : ICTCallable + { + IResult ICTCallable.Call(Compiler.Compiler compiler, Argument[] arguments) + { + IRCode result = new(); + + foreach (var argument in arguments) + { + if ( + compiler.IR.CompileCode(argument.Object, null) + .When(out var argumentCode) + .Error(out var error) + ) + return Result.Error(error); + + result.Instructions.AddRange(argumentCode!.Instructions); + } + + if (IR is null) + if (CompileIR(compiler, null).When(out var ir).Error(out var error)) + return Result.Error(error); + else IR = ir!; + + result.Instructions.Add(new IR.VM.Call(IR)); + result.Types.Add(IR.ReturnType); + + return Result.Ok(new RawIRCode(result)); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/function/Function.IR.cs b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.IR.cs new file mode 100644 index 00000000..0699e1d3 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.IR.cs @@ -0,0 +1,69 @@ + + +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Function + : ICompileIRDefinitionAs + , ICompileIRDefinitionIn + { + public IR.Function? IR { get; private set; } + + void ICompileIRDefinitionIn.CompileIRDefinition(Compiler.Compiler compiler, IR.Module owner, object? target) + { + if ( + CompileIR(compiler, target) + .When(out var ir) + .Error(out var error) + ) throw new InvalidOperationException(error.ToString()); + + if (!state[BuildState.Owner]) + { + state[BuildState.Owner] = true; + + owner.Functions.Add(ir!); + } + } + + IResult ICompileIRDefinitionAs.CompileIRDefinition(Compiler.Compiler compiler, object? target) + => CompileIR(compiler, target); + + private IResult CompileIR(Compiler.Compiler compiler, object? target) + { + if (ReturnType is null) + return Result.Error( + $"Function {Name} does not have a return type" + ); + if ( + compiler.IR.CompileType(ReturnType) + .When(out var returnType) + .Error(out var error) + ) return Result.Error(error); + + IR ??= new(returnType!) + { + Name = Name + }; + + if (!state[BuildState.Body]) + { + state[BuildState.Body] = true; + + if (Body is not null) + if ( + compiler.IR.CompileCode(Body, target) + .When(out var body) + .Error(out error) + ) return Result.Error(error); + else + { + IR.Body.Instructions.AddRange(body!.Instructions); + IR.Body.StackSize = body.MaxStackSize; + } + } + + return Result.Ok(IR); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/function/Function.ModuleMember.cs b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.ModuleMember.cs new file mode 100644 index 00000000..0b4f6c10 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.ModuleMember.cs @@ -0,0 +1,10 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Function + : IModuleMember + { + public Module Module { get; internal set; } + + CompilerObject IModuleMember.Module => Module; + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/function/Function.Name.cs b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.Name.cs new file mode 100644 index 00000000..19f70d37 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.Name.cs @@ -0,0 +1,18 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Function + { + public string _name; + + public string Name + { + get => _name; + set + { + if (IsBuilt) throw new InvalidOperationException("Cannot change name after the function object is built."); + if (value is null) throw new ArgumentNullException(nameof(value), "Name cannot be null."); + _name = value; + } + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/function/Function.ReturnType.cs b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.ReturnType.cs new file mode 100644 index 00000000..babeca55 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.ReturnType.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Function + { + public CompilerObject? ReturnType { get; set; } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/function/Function.T.cs b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.T.cs new file mode 100644 index 00000000..8d820eae --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Function + { + + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/function/Function.cs b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.cs new file mode 100644 index 00000000..ba6e1fde --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/function/Function.cs @@ -0,0 +1,8 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + internal sealed partial class Function + : CompilerObject + { + public CompilerObject? Body { get; set; } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/global/Global.Build.cs b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.Build.cs new file mode 100644 index 00000000..52b65d52 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.Build.cs @@ -0,0 +1,19 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Global + { + [Flags] + private enum BuildState + { + Owner = 1 << 0, + + } + + private readonly ObjectBuildState state = new(); + + [MemberNotNullWhen(true, nameof(IR))] + public bool IsBuilt => IR is not null; + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/global/Global.IR.cs b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.IR.cs new file mode 100644 index 00000000..f40f638c --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.IR.cs @@ -0,0 +1,43 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Global + : ICompileIRDefinitionAs + , ICompileIRDefinitionIn + { + public IR.Global? IR { get; private set; } + + IResult ICompileIRDefinitionAs.CompileIRDefinition(Compiler.Compiler compiler, object? target) + { + if (IR is null) + { + var typeResult = compiler.IR.CompileType(Type); + + if ( + typeResult + .When(out var type) + .IsError + ) return typeResult.When(_ => (null as IR.Global)!); + + IR = new(Name, type!); + } + + + + return Result.Ok(IR); + } + + void ICompileIRDefinitionIn.CompileIRDefinition(Compiler.Compiler compiler, IR.Module owner, object? target) + { + var result = compiler.IR.CompileDefinition(this, target); + + if (result.IsError) return; + + if (!state[BuildState.Owner]) + { + owner.Globals.Add(IR!); + + state.Set(BuildState.Owner); + } + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/global/Global.ModuleMember.cs b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.ModuleMember.cs new file mode 100644 index 00000000..46e3395f --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.ModuleMember.cs @@ -0,0 +1,11 @@ + +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Global + : IModuleMember + { + public Module Module { get; internal set; } + + CompilerObject IModuleMember.Module => Module; + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/global/Global.Name.cs b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.Name.cs new file mode 100644 index 00000000..efa2835b --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.Name.cs @@ -0,0 +1,20 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Global + { + private string _name; + + public string Name + { + get => _name; + set + { + if (IsBuilt) throw new InvalidOperationException("Cannot change name after the global object is built."); + + if (value is null) throw new ArgumentNullException(nameof(value), "Name cannot be null."); + + _name = value; + } + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/global/Global.T.cs b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.T.cs new file mode 100644 index 00000000..a9c753e2 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Global + { + + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/global/Global.Type.cs b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.Type.cs new file mode 100644 index 00000000..6bbf2e03 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.Type.cs @@ -0,0 +1,20 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Global + : ITyped + { + private CompilerObject _type; + + public CompilerObject Type + { + get => _type; + set { + if (IsBuilt) throw new InvalidOperationException("Cannot change type after the global object is built."); + + if (value is null) throw new ArgumentNullException(nameof(value), "Type cannot be null."); + + _type = value; + } + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/global/Global.cs b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.cs new file mode 100644 index 00000000..efff0c61 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/global/Global.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + internal sealed partial class Global + : CompilerObject + { + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Build.cs b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Build.cs new file mode 100644 index 00000000..50eebb20 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Build.cs @@ -0,0 +1,20 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Module + { + [Flags] + private enum BuildState + { + Content = 1 << 0, + EntryPoint = 1 << 1, + Initializer = 1 << 2, + } + + private readonly ObjectBuildState state = new(); + + [MemberNotNullWhen(true, nameof(IR))] + public bool IsBuilt => IR is not null; + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Content.cs b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Content.cs new file mode 100644 index 00000000..3aba1257 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Content.cs @@ -0,0 +1,9 @@ +using CommonZ.Utils; + +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Module + { + public Collection Content { get; } = []; + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/module/Module.EntryPoint.cs b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.EntryPoint.cs new file mode 100644 index 00000000..023aa982 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.EntryPoint.cs @@ -0,0 +1,17 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Module + { + private CompilerObject? entryPoint; + + public CompilerObject? EntryPoint + { + get => entryPoint; + set { + if (state[BuildState.EntryPoint]) + throw new InvalidOperationException($"Cannot set entrypoint on an already built module"); + entryPoint = value; + } + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/module/Module.IR.cs b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.IR.cs new file mode 100644 index 00000000..04b2d614 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.IR.cs @@ -0,0 +1,49 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Module + : ICompileIRDefinitionAs + { + public IR.Module? IR { get; private set; } + + IResult ICompileIRDefinitionAs.CompileIRDefinition(Compiler.Compiler compiler, object? target) + { + IR ??= new(Name); + + if (!state[BuildState.Content]) + { + state[BuildState.Content] = true; + + foreach (var item in Content) + compiler.IR.CompileDefinition(item, IR, target); + } + + if (!state[BuildState.EntryPoint]) + { + if (EntryPoint is not null) + if ( + compiler.IR.CompileDefinition(EntryPoint, target) + .When(out var entryPoint) + .Error(out var error) + ) return Result.Error(error); + else IR.EntryPoint = entryPoint; + + state[BuildState.EntryPoint] = true; + } + + if (!state[BuildState.Initializer]) + { + if (Initializer is not null) + if ( + compiler.IR.CompileDefinition(Initializer, target) + .When(out var initializer) + .Error(out var error) + ) return Result.Error(error); + else IR.Initializer = initializer; + + state[BuildState.Initializer] = true; + } + + return Result.Ok(IR); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Initializer.cs b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Initializer.cs new file mode 100644 index 00000000..633a5357 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Initializer.cs @@ -0,0 +1,17 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Module + { + private CompilerObject? initializer; + + public CompilerObject? Initializer + { + get => initializer; + set { + if (state[BuildState.Initializer]) + throw new InvalidOperationException($"Cannot set initializer on an already built module"); + initializer = value; + } + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Member.cs b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Member.cs new file mode 100644 index 00000000..a8aed1bc --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Member.cs @@ -0,0 +1,26 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Module + : ICTGetMember + { + private readonly Dictionary members = []; + + public IResult AddMember(string name, CompilerObject member) + { + if (members.ContainsKey(name)) + return Result.Error($"Member '{name}' is already defined in module '{Name}'."); + else + members[name] = member; + + return Result.Ok(member); + } + + IResult ICTGetMember.Member(Compiler.Compiler compiler, string member) + { + if (members.TryGetValue(member, out var obj)) + return Result.Ok(obj); + + return Result.Error($"Member '{member}' not found in module '{Name}'."); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Name.cs b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Name.cs new file mode 100644 index 00000000..8aeb06a1 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.Name.cs @@ -0,0 +1,17 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Module + { + private string _name = string.Empty; + + public string Name { + get => _name; + set + { + if (IsBuilt) throw new InvalidOperationException("Cannot change name after the module object is built."); + if (value is null) throw new ArgumentNullException(nameof(value), "Name cannot be null."); + _name = value; + } + } + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/module/Module.T.cs b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.T.cs new file mode 100644 index 00000000..a1eed453 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + partial class Module + { + + } +} diff --git a/ZSharp.SourceCompiler.Module/objects/modular/module/Module.cs b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.cs new file mode 100644 index 00000000..7eccbac4 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/objects/modular/module/Module.cs @@ -0,0 +1,8 @@ +namespace ZSharp.SourceCompiler.Module.Objects +{ + internal sealed partial class Module + : CompilerObject + { + + } +} diff --git a/ZSharp.SourceCompiler.Module/old/GlobalUsings.cs b/ZSharp.SourceCompiler.Module/old/GlobalUsings.cs new file mode 100644 index 00000000..5840b125 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/GlobalUsings.cs @@ -0,0 +1,15 @@ +//global using CompilerObject = ZSharp.Objects.CompilerObject; +//global using ZSharp.AST; + +//global using ObjectResult = +// ZSharp.Compiler.Result< +// ZSharp.Objects.CompilerObject, +// ZSharp.ZSSourceCompiler.Error +// >; +//global using TypeResult = +// ZSharp.Compiler.Result< +// ZSharp.Compiler.IType, +// ZSharp.ZSSourceCompiler.Error +// >; + +//global using static ZSharp.ZSSourceCompiler.HelperFunctions; diff --git a/ZSharp.SourceCompiler.Module/old/HelperFunctions.cs b/ZSharp.SourceCompiler.Module/old/HelperFunctions.cs new file mode 100644 index 00000000..d1ea5c7e --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/HelperFunctions.cs @@ -0,0 +1,31 @@ +using System.Diagnostics.CodeAnalysis; +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + internal static class HelperFunctions + { + public static bool CombineErrorResults( + IEnumerable> results, + [NotNullWhen(true)] out CombinedCompilationError? error + ) + where T : class + { + var errors = + results + .Where(r => r.IsError) + .Select(r => r.Error(out var e) ? e : throw new()) + .SelectMany(e => e switch + { + CompilationError compilationError => [compilationError], + CombinedCompilationError combined => combined.Errors, + _ => throw new("Unknown error type: " + e.GetType().Name) + }) + .ToArray(); + + error = errors.Length > 0 ? new(errors) : null; + + return errors.Length > 0; + } + } +} diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/capabilities/IMultipassCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/capabilities/IMultipassCompiler.cs similarity index 100% rename from ZSharp.ZSSourceCompiler/builtin-compilers/capabilities/IMultipassCompiler.cs rename to ZSharp.SourceCompiler.Module/old/builtin-compilers/capabilities/IMultipassCompiler.cs diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/class body/ClassBodyCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/class body/ClassBodyCompiler.cs new file mode 100644 index 00000000..5238e351 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/class body/ClassBodyCompiler.cs @@ -0,0 +1,230 @@ +using ZSharp.Objects; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class ClassBodyCompiler(ZSSourceCompiler compiler, OOPDefinition oop, Class @class) + : CompilerBase(compiler) + , IMultipassCompiler + { + private List currentPass = [], nextPass = []; + + public OOPDefinition Node { get; } = oop; + + public Class Class { get; } = @class; + + public void AddToNextPass(Action action) + => nextPass.Add(action); + + public void Compile() + { + if (Node.Content is null) + return; + + currentPass = [.. Node.Content.Statements.Select(Compile)]; + } + + public bool CompileSinglePass() + { + using (Context.Compiler(this)) + return CompileSinglePassImpl(); + } + + public void CompileUntilComplete() + { + using (Context.Compiler(this)) + while (CompileSinglePassImpl()) ; + } + + private bool CompileSinglePassImpl() + { + foreach (var item in currentPass) + item(); + + (currentPass, nextPass) = (nextPass, currentPass); + nextPass.Clear(); + + return currentPass.Count > 0; + } + + private Action Compile(Statement statement) + => statement switch + { + ExpressionStatement expression => Compile(expression), + _ => throw new(), // TODO: could not compile node ... + }; + + private Action Compile(ExpressionStatement expression) + => expression.Expression switch + { + AST.Constructor constructor => Compile(constructor), + AST.Function function => Compile(function), + LetExpression let => Compile(let), + //OOPDefinition oop => Compile(oop), + VarExpression var => Compile(var), + _ => throw new() // TODO: Throw a proper exception of UnknownNodeType + }; + + private Action Compile(AST.Constructor constructor) + { + var compiler = new ConstructorCompiler(this, constructor); + + compiler.Object.Owner = Class; + + Class.Content.Add(compiler.Object); + + if (constructor.Name is not null && constructor.Name != string.Empty) + { + Context.CurrentScope.Set(constructor.Name, compiler.Object); + Class.Members.Add(constructor.Name, compiler.Object); + } else + { + if (Class.Constructor is null) + Class.Constructor = new OverloadGroup(string.Empty); + if (Class.Constructor is not OverloadGroup group) + throw new("???"); + + group.Overloads.Add(compiler.Object); + } + + return () => compiler.Compile(); + } + + private Action Compile(AST.Function function) + { + var compiler = new MethodCompiler(this, function, Class, Class); + + Class.Content.Add(compiler.Object); + + if (function.Name != string.Empty) + { + MethodOverloadGroup? group = null; + if (!Compiler.Compiler.CurrentContext.PerformOperation( + scope => scope.Get(function.Name, out group) + )) + Context.CurrentScope.Set(function.Name, group = new(function.Name)); + + group!.Overloads.Add(compiler.Object); + + if (!Class.Members.TryGetValue(function.Name, out var _)) + Class.Members.Add(function.Name, group); + } + + return () => compiler.Compile(); + } + + private Action Compile(LetExpression let) + { + var field = new Field(let.Name) + { + IsReadOnly = true, + }; + + Class.Content.Add(field); + + Context.CurrentScope.Set(let.Name, field); + Class.Members.Add(let.Name, field); + + return () => + { + if (Compiler.CompileNode(let.Value).Ok(out var initializer)) + field.Initializer = initializer; + + if ( + let.Type is not null && + Compiler.CompileType(let.Type).Ok(out var type) + ) + field.Type = type; + else if ( + field.Initializer is not null && + Compiler.Compiler.TypeSystem.IsTyped(field.Initializer, out type) + ) + field.Type = type; + + if (field.Type is null) + { + Compiler.LogError($"Field type could not be inferred", let); + return; + } + + if ( + Compiler.Compiler.IR.CompileDefinition(field, null) + .When(ir => field.IR = ir) + .Else(error => Compiler.LogError( + $"Could not compile IR for field {let.Name}: {error}", let + ) + ).IsError + ) + return; + + if (field.Initializer is not null && + Compiler.Compiler.CG.ImplicitCast(field.Initializer, field.Type) + .When(init => field.Initializer = init) + .Else(error => Compiler.LogError( + $"Could not initialize field {let.Name}: {error}", let + ) + ).IsError + ) + return; + }; + } + + private Action Compile(VarExpression var) + { + var field = new Field(var.Name) + { + IsReadOnly = false, + }; + + Class.Content.Add(field); + + Context.CurrentScope.Set(var.Name, field); + Class.Members.Add(var.Name, field); + + return () => + { + if ( + var.Value is not null && + Compiler.CompileNode(var.Value).Ok(out var initializer) + ) + field.Initializer = initializer; + + if ( + var.Type is not null && + Compiler.CompileType(var.Type).Ok(out var type) + ) + field.Type = type; + else if ( + field.Initializer is not null && + Compiler.Compiler.TypeSystem.IsTyped(field.Initializer, out type) + ) + field.Type = type; + + if (field.Type is null) + { + Compiler.LogError($"Field type could not be inferred", var); + return; + } + + if ( + Compiler.Compiler.IR.CompileDefinition(field, null) + .When(ir => field.IR = ir) + .Else(error => Compiler.LogError( + $"Could not compile IR for field {var.Name}: {error}", var + ) + ).IsError + ) + return; + + if (field.Initializer is not null && + Compiler.Compiler.CG.ImplicitCast(field.Initializer, field.Type) + .When(init => field.Initializer = init) + .Else(error => Compiler.LogError( + $"Could not initialize field {var.Name}: {error}", var + ) + ).IsError + ) + return; + }; + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/class body/ConstructorCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/class body/ConstructorCompiler.cs new file mode 100644 index 00000000..c80d9296 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/class body/ConstructorCompiler.cs @@ -0,0 +1,116 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class ConstructorCompiler(ClassBodyCompiler compiler, Constructor node) + : ContextCompiler(compiler.Compiler, node, new(node.Name)) + , IOverrideCompileExpression + { + public Objects.Parameter This { get; private set; } = null!; + + public override Objects.Constructor Compile() + { + using (Context.Compiler(this)) + using (Context.Scope(Object)) + CompileConstructor(); + + return base.Compile(); + } + + private void CompileConstructor() + { + if (Node.Signature.Args is not null) + foreach (var parameter in Node.Signature.Args) + Object.Signature.Args.Add(Compile(parameter)); + + if (Node.Signature.VarArgs is not null) + //Object.Signature.VarArgs = Compile(Node.Signature.VarArgs); + throw new NotImplementedException(); + + if (Node.Signature.KwArgs is not null) + foreach (var parameter in Node.Signature.KwArgs) + Object.Signature.KwArgs.Add(Compile(parameter)); + + if (Node.Signature.VarKwArgs is not null) + //Object.Signature.VarKwArgs = Compile(Node.Signature.VarKwArgs); + throw new NotImplementedException(); + + if (Object.Signature.Args.Count == 0) + Object.Signature.Args.Add(new("this")); + + (This = Object.Signature.Args[0]).Type ??= Object.Owner; + + compiler.AddToNextPass(() => + { + using (Context.Compiler(this)) + using (Context.Scope(Object)) + using (Context.Scope()) + CompileConstructorBody(); + }); + } + + private void CompileConstructorBody() + { + if (Node.Body is not null) + Object.Body = Compiler.CompileNode(Node.Body).Unwrap(); + + Object.IR = Compiler.Compiler.CompileIRObject(Object, null!); + + Object.IR.Method.Body.Instructions.Add(new IR.VM.Return()); + } + + private Objects.Parameter Compile(Parameter parameter) + { + var result = new Objects.Parameter(parameter.Name); + + Context.CurrentScope.Set(parameter.Alias ?? parameter.Name, result); + + if (parameter.Type is not null) + result.Type = Compiler.CompileType(parameter.Type).Unwrap(); + + if (parameter.Initializer is not null) + Compiler.LogError("Parameter initializers are not supported yet.", parameter); + + return result; + } + + private ObjectResult? Compile(IdentifierExpression identifier) + { + CompilerObject? member = null; + + Compiler.Compiler.CurrentContext.PerformOperation( + scope => + { + return scope.Get(identifier.Name, out member); + }, + new UntilContextTypeStrategy>( + new ParentContextStrategy() + ) + ); + + if (member is null) + return null; + + if (member is Objects.IRTBoundMember boundMember) + return ObjectResult.Ok(boundMember.Bind(Compiler.Compiler, This)); + + if (member is Objects.OverloadGroup group) + return ObjectResult.Ok(new Objects.OverloadGroup(group.Name) + { + Overloads = [.. group.Overloads.Select( + overload => overload is Objects.IRTBoundMember boundMember ? + boundMember.Bind(Compiler.Compiler, This) : overload + )], + }); + + return ObjectResult.Ok(member); + } + + ObjectResult? IOverrideCompileNode.CompileNode(ZSSourceCompiler compiler, Expression node) + => node switch + { + IdentifierExpression identifier => Compile(identifier), + _ => null, + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/class body/MethodCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/class body/MethodCompiler.cs new file mode 100644 index 00000000..986ba1a5 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/class body/MethodCompiler.cs @@ -0,0 +1,199 @@ +namespace ZSharp.ZSSourceCompiler +{ + public sealed class MethodCompiler(ClassBodyCompiler compiler, Function node, CompilerObject owner, Compiler.IType self) + : ContextCompiler(compiler.Compiler, node, new(node.Name) + { + Owner = owner + }) + , IOverrideCompileStatement + { + public Objects.Parameter? This { get; private set; } = null; + + public override Objects.Method Compile() + { + using (Context.Compiler(this)) + using (Context.Scope(Object)) + CompileMethod(); + + return base.Compile(); + } + + private void CompileMethod() + { + if (Node.Signature.Args is not null) + foreach (var parameter in Node.Signature.Args) + Object.Signature.Args.Add(Compile(parameter)); + + if (Node.Signature.VarArgs is not null) + //Object.Signature.VarArgs = Compile(Node.Signature.VarArgs); + throw new NotImplementedException(); + + if (Node.Signature.KwArgs is not null) + foreach (var parameter in Node.Signature.KwArgs) + Object.Signature.KwArgs.Add(Compile(parameter)); + + if (Node.Signature.VarKwArgs is not null) + //Object.Signature.VarKwArgs = Compile(Node.Signature.VarKwArgs); + throw new NotImplementedException(); + + if (Node.ReturnType is not null) + if ( + Compiler.CompileType(Node.ReturnType) + .When(out var returnType) + .Error(out var error) + ) + { + return; + } + else Object.ReturnType = returnType; + else + { + return; + } + + (This = Object.Signature.Args[0]).Type ??= self; + + //Object.IR = Compiler.Compiler.CompileIRObject(Object, null); + + compiler.AddToNextPass(() => + { + using (Context.Compiler(this)) + using (Context.Scope(Object)) + using (Context.Scope()) + CompileMethodBody(); + }); + } + + private Objects.Parameter Compile(Parameter parameter) + { + var result = new Objects.Parameter(parameter.Name); + + Context.CurrentScope.Set(parameter.Alias ?? parameter.Name, result); + + if ( + parameter.Type is not null && + Compiler.CompileType(parameter.Type).Ok(out var type) + ) + result.Type = type; + + if (parameter.Initializer is not null) + Compiler.LogError("Parameter initializers are not supported yet.", parameter); + + return result; + } + + private void CompileMethodBody() + { + if ( + Node.Body is not null && + Compiler.CompileNode(Node.Body).Ok(out var body) + ) + Object.Body = body; + + Object.IR = Compiler.Compiler.CompileIRObject(Object, null); + } + + public ObjectResult? CompileNode(ZSSourceCompiler compiler, Statement node) + { + if (node is not Return @return) + return null; + + if (@return.Value is null) + return ObjectResult.Ok(new Objects.RawCode(new([ + new IR.VM.Return() + ]))); + + var valueResult = Compiler.CompileNode(@return.Value); + + if ( + valueResult + .When(out var returnValue) + .IsError + ) + return valueResult; + + if ( + Compiler.Compiler.IR.CompileCode(returnValue!) + .When(out var valueCode) + .Error(out var error) + ) + return Compiler.CompilationError(error, @return.Value); + + valueCode!.Instructions.Add(new IR.VM.Return()); + valueCode.RequireValueType(); + valueCode.Types.Clear(); + + return ObjectResult.Ok(new Objects.RawCode(valueCode)); + } + + public CompilerObject? CompileNode(ZSSourceCompiler compiler, Expression node) + => node switch + { + LetExpression let => CompileNode(let), + VarExpression var => CompileNode(var), + _ => null + }; + + private CompilerObject CompileNode(LetExpression let) + { + var local = new Objects.Local + { + Name = let.Name, + Initializer = Compiler.CompileNode(let.Value).Unwrap(), + }; + + Context.CurrentScope.Set(let.Name, local); + + local.Type = let.Type is not null + ? Compiler.CompileType(let.Type).Unwrap() + : Compiler.Compiler.TypeSystem.IsTyped(local.Initializer, out var type) + ? type + : null; + + if (local.Type is null) + Compiler.LogError("Could not infer type of local variable.", let); + + local.IR = Compiler.Compiler.CompileIRObject(local, Object.IR!.Body); + + if (local.IR.Initializer is not null) + return new Objects.RawCode(new(local.IR.Initializer) + { + Types = [local.Type] + }); + + return new Objects.RawCode(new()); + } + + private CompilerObject CompileNode(VarExpression var) + { + var local = new Objects.Local + { + Name = var.Name, + Initializer = var.Value is null ? null : Compiler.CompileNode(var.Value).Unwrap(), + }; + + Context.CurrentScope.Set(var.Name, local); + + local.Type = var.Type is not null + ? Compiler.CompileType(var.Type).Unwrap() + : local.Initializer is null + ? null + : Compiler.Compiler.TypeSystem.IsTyped(local.Initializer, out var type) + ? type + : null; + + if (local.Type is null) + Compiler.LogError("Could not infer type of local variable.", var); + + local.IR = Compiler.Compiler.CompileIRObject(local, Object.IR!.Body); + + if (local.IR.Initializer is not null) + return new Objects.RawCode(new(local.IR.Initializer) + { + Types = [local.Type] + }); + + return new Objects.RawCode(new()); + } + } +} diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/document/compiler/DocumentCompiler.Compile.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/document/compiler/DocumentCompiler.Compile.cs similarity index 100% rename from ZSharp.ZSSourceCompiler/builtin-compilers/document/compiler/DocumentCompiler.Compile.cs rename to ZSharp.SourceCompiler.Module/old/builtin-compilers/document/compiler/DocumentCompiler.Compile.cs diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/document/compiler/DocumentCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/document/compiler/DocumentCompiler.cs new file mode 100644 index 00000000..b9352719 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/document/compiler/DocumentCompiler.cs @@ -0,0 +1,54 @@ + +using ZSharp.AST; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class DocumentCompiler(ZSSourceCompiler compiler, AST.Document node, Document document) + : ContextCompiler(compiler, node, document) + , IOverrideCompileExpression + , IOverrideCompileStatement + { + public override Document Compile() + { + using (Context.Compiler(this)) + using (Compiler.Compiler.ContextScope(new ObjectContext(Object))) + using (Context.Scope(Object)) + CompileDocument(); + + return base.Compile(); + } + + private void CompileDocument() + { + foreach (var item in Node.Statements) + Compiler.CompileNode(item); + } + + public ObjectResult? CompileNode(ZSSourceCompiler compiler, Statement statement) + { + if (statement is ExpressionStatement expressionStatement) + return expressionStatement.Expression switch + { + Module => null, + Expression expression => + Compiler.Interpreter.Evaluate( + expression + ).When(out var result).Error(out var error) + ? Compiler.CompilationError(error, expression) + : ObjectResult.Ok(Interpreter.CTServices.InfoOf(result!)) + }; + + return null; + // if the statement is a definition, compile it + } + + public ObjectResult? CompileNode(ZSSourceCompiler compiler, Expression node) + => node switch + { + Module module => Compile(module), + _ => null, + } is CompilerObject result + ? ObjectResult.Ok(result) + : null; + } +} diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/document/objects/Document.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/document/objects/Document.cs similarity index 100% rename from ZSharp.ZSSourceCompiler/builtin-compilers/document/objects/Document.cs rename to ZSharp.SourceCompiler.Module/old/builtin-compilers/document/objects/Document.cs diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/module/ClassCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/module/ClassCompiler.cs new file mode 100644 index 00000000..62856e54 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/module/ClassCompiler.cs @@ -0,0 +1,74 @@ +using ZSharp.Objects; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class ClassCompiler( + ZSSourceCompiler compiler, + OOPDefinition node, + ClassMetaClass metaClass + ) + : ContextCompiler( + compiler, node, new() + { + Name = node.Name + } + ) + { + public override Class Compile() + { + if (Node.Bases is not null) + { + var bases = Node.Bases.Select(Compiler.CompileType).Select(result => result.Unwrap()).ToArray(); + + if (bases.Length > 0) + { + int interfacesIndex = 0; + if (bases[0] is IClass @base) + Object.Base = (IClass)bases[interfacesIndex++]; + + for (; interfacesIndex < bases.Length; interfacesIndex++) + Object.Interfaces.Add(bases[interfacesIndex]); + } + } + + var bodyCompiler = new ClassBodyCompiler(Compiler, Node, Object); + + using (Context.Compiler(this)) + using (Compiler.Compiler.ContextScope(new ClassContext(Object))) + using (Context.Scope(Object)) + { + bodyCompiler.Compile(); + bodyCompiler.CompileSinglePass(); + } + + foreach (var @interface in Object.Interfaces) + if (@interface is IAbstraction abstraction) + ResolveImplementation(abstraction); + + using (Context.Compiler(this)) + using (Compiler.Compiler.ContextScope(new ClassContext(Object))) + using (Context.Scope(Object)) + bodyCompiler.CompileUntilComplete(); + + return base.Compile(); + } + + private void ResolveImplementation(IAbstraction abstraction) + { + if (Object is not IImplementsAbstraction implementsAbstraction) + throw new(); + + Implementation? result = null; + foreach (var implementationInfo in Object.InterfaceImplementations) + if (implementationInfo.Abstract == abstraction) + { + result = implementationInfo; + break; + } + if (result is null) + Object.InterfaceImplementations.Add(result = new(abstraction, Object)); + + implementsAbstraction.ImplementAbstraction(Compiler.Compiler, abstraction, result); + } + } +} diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/module/FunctionCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/module/FunctionCompiler.cs similarity index 57% rename from ZSharp.ZSSourceCompiler/builtin-compilers/module/FunctionCompiler.cs rename to ZSharp.SourceCompiler.Module/old/builtin-compilers/module/FunctionCompiler.cs index ae37197f..ff1e1ec8 100644 --- a/ZSharp.ZSSourceCompiler/builtin-compilers/module/FunctionCompiler.cs +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/module/FunctionCompiler.cs @@ -1,13 +1,14 @@ namespace ZSharp.ZSSourceCompiler { - public sealed class FunctionCompiler(ZSSourceCompiler compiler, Function node) - : ContextCompiler(compiler, node, new(node.Name)) + public sealed class FunctionCompiler(ModuleCompiler moduleCompiler, Function node) + : ContextCompiler(moduleCompiler.Compiler, node, new(node.Name)) , IOverrideCompileStatement - ,IOverrideCompileExpression + , IOverrideCompileExpression { public override Objects.RTFunction Compile() { using (Context.Compiler(this)) + using (Compiler.Compiler.ContextScope(new FunctionContext(Compiler.Compiler, Object))) using (Context.Scope(Object)) CompileFunction(); @@ -21,31 +22,31 @@ private void CompileFunction() Object.Signature.Args.Add(Compile(parameter)); if (Node.Signature.VarArgs is not null) - Object.Signature.VarArgs = Compile(Node.Signature.VarArgs); + //Object.Signature.VarArgs = Compile(Node.Signature.VarArgs); + throw new NotImplementedException(); if (Node.Signature.KwArgs is not null) foreach (var parameter in Node.Signature.KwArgs) Object.Signature.KwArgs.Add(Compile(parameter)); if (Node.Signature.VarKwArgs is not null) - Object.Signature.VarKwArgs = Compile(Node.Signature.VarKwArgs); + //Object.Signature.VarKwArgs = Compile(Node.Signature.VarKwArgs); + throw new NotImplementedException(); if (Node.ReturnType is not null) - Object.ReturnType = Compiler.CompileType(Node.ReturnType); + Object.ReturnType = Compiler.CompileType(Node.ReturnType).Unwrap(); else throw new(); // TODO: Implement Infer type Object.IR = Compiler.Compiler.CompileIRObject(Object, null); - if (Context.ParentCompiler(out var multipassCompiler)) - multipassCompiler.AddToNextPass(() => - { - using (Context.Compiler(this)) - using (Context.Scope(Object)) - using (Context.Scope()) - CompileFunctionBody(); - }); - else using (Context.Scope()) - CompileFunctionBody(); + moduleCompiler.AddToNextPass(() => + { + using (Context.Compiler(this)) + using (Compiler.Compiler.ContextScope(new FunctionContext(Compiler.Compiler, Object))) + using (Context.Scope(Object)) + using (Context.Scope()) + CompileFunctionBody(); + }); } private Objects.Parameter Compile(Parameter parameter) @@ -55,7 +56,7 @@ private Objects.Parameter Compile(Parameter parameter) Context.CurrentScope.Set(parameter.Alias ?? parameter.Name, result); if (parameter.Type is not null) - result.Type = Compiler.CompileType(parameter.Type); + result.Type = Compiler.CompileType(parameter.Type).Unwrap(); if (parameter.Initializer is not null) Compiler.LogError("Parameter initializers are not supported yet.", parameter); @@ -66,57 +67,55 @@ private Objects.Parameter Compile(Parameter parameter) private void CompileFunctionBody() { if (Node.Body is not null) - Object.Body = Compiler.CompileNode(Node.Body); + Object.Body = Compiler.CompileNode(Node.Body).Unwrap(); } - public CompilerObject? CompileNode(ZSSourceCompiler compiler, Statement node) + public ObjectResult? CompileNode(ZSSourceCompiler compiler, Statement node) { - if (node is ExpressionStatement es && es.Expression is WhileExpression @while) - return new WhileLoopCompiler(compiler, @while).Compile(); - if (node is not Return @return) return null; if (@return.Value is null) - return new Objects.RawCode(new([ + return ObjectResult.Ok(new Objects.RawCode(new([ new IR.VM.Return() - ])); + ]))); - var valueObject = Compiler.CompileNode(@return.Value); - var valueCode = Compiler.Compiler.CompileIRCode(valueObject); + var valueObject = Compiler.CompileNode(@return.Value).Unwrap(); + var valueCodeResult = Compiler.Compiler.IR.CompileCode(valueObject); - if (valueCode is null) - { - Compiler.LogError("Return expression could not be compiled.", node); - return null; - } + if ( + valueCodeResult + .When(out var valueCode) + .Error(out var error) + ) + return Compiler.CompilationError(error, @return.Value); - valueCode.Instructions.Add(new IR.VM.Return()); + valueCode!.Instructions.Add(new IR.VM.Return()); valueCode.Types.Clear(); - return new Objects.RawCode(valueCode); + return ObjectResult.Ok(new Objects.RawCode(valueCode)); } - public CompilerObject? CompileNode(ZSSourceCompiler compiler, Expression node) + public ObjectResult? CompileNode(ZSSourceCompiler compiler, Expression node) => node switch { LetExpression let => CompileNode(let), VarExpression var => CompileNode(var), - _ => null + _ => null, }; - private CompilerObject CompileNode(LetExpression let) + private ObjectResult CompileNode(LetExpression let) { var local = new Objects.Local { Name = let.Name, - Initializer = Compiler.CompileNode(let.Value), + Initializer = Compiler.CompileNode(let.Value).Unwrap(), }; Context.CurrentScope.Set(let.Name, local); local.Type = let.Type is not null - ? Compiler.CompileNode(let.Type) + ? Compiler.CompileType(let.Type).Unwrap() : Compiler.Compiler.TypeSystem.IsTyped(local.Initializer, out var type) ? type : null; @@ -126,26 +125,27 @@ private CompilerObject CompileNode(LetExpression let) local.IR = Compiler.Compiler.CompileIRObject(local, Object.IR!.Body); - var code = Compiler.Compiler.CompileIRCode(local.Initializer); - - code.Instructions.Add(new IR.VM.Dup()); - code.Instructions.Add(new IR.VM.SetLocal(local.IR)); + if (local.IR.Initializer is not null) + return ObjectResult.Ok(new Objects.RawCode(new(local.IR.Initializer) + { + Types = [local.Type] + })); - return new Objects.RawCode(code); + return ObjectResult.Ok(new Objects.RawCode(new())); } - private CompilerObject CompileNode(VarExpression var) + private ObjectResult CompileNode(VarExpression var) { var local = new Objects.Local { Name = var.Name, - Initializer = var.Value is null ? null : Compiler.CompileNode(var.Value), + Initializer = var.Value is null ? null : Compiler.CompileNode(var.Value).Unwrap(), }; Context.CurrentScope.Set(var.Name, local); local.Type = var.Type is not null - ? Compiler.CompileNode(var.Type) + ? Compiler.CompileType(var.Type).Unwrap() : local.Initializer is null ? null : Compiler.Compiler.TypeSystem.IsTyped(local.Initializer, out var type) @@ -157,17 +157,13 @@ private CompilerObject CompileNode(VarExpression var) local.IR = Compiler.Compiler.CompileIRObject(local, Object.IR!.Body); - if (local.Initializer is not null) - { - var code = Compiler.Compiler.CompileIRCode(local.Initializer); - - code.Instructions.Add(new IR.VM.Dup()); - code.Instructions.Add(new IR.VM.SetLocal(local.IR)); - - return new Objects.RawCode(code); - } + if (local.IR.Initializer is not null) + return ObjectResult.Ok(new Objects.RawCode(new(local.IR.Initializer) + { + Types = [local.Type] + })); - return new Objects.RawCode(new()); + return ObjectResult.Ok(new Objects.RawCode(new())); } } } diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/module/ModuleCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/module/ModuleCompiler.cs similarity index 88% rename from ZSharp.ZSSourceCompiler/builtin-compilers/module/ModuleCompiler.cs rename to ZSharp.SourceCompiler.Module/old/builtin-compilers/module/ModuleCompiler.cs index 6afaabcf..38fb332b 100644 --- a/ZSharp.ZSSourceCompiler/builtin-compilers/module/ModuleCompiler.cs +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/module/ModuleCompiler.cs @@ -10,12 +10,15 @@ public sealed class ModuleCompiler(ZSSourceCompiler compiler, Module node) public readonly Mapping> oopTypesCompilers = []; + public required Objects.ClassMetaClass DefaultMetaClass { get; set; } + public void AddToNextPass(Action action) => nextPass.Add(action); public override Objects.Module Compile() { using (Context.Compiler(this)) + using (Compiler.Compiler.ContextScope(new ObjectContext(Object))) using (Context.Scope(Object)) CompileModule(); @@ -58,7 +61,7 @@ private Action Compile(ExpressionStatement expression) private Action Compile(Function function) { - var compiler = new FunctionCompiler(Compiler, function); + var compiler = new FunctionCompiler(this, function); Object.Content.Add(compiler.Object); @@ -82,10 +85,10 @@ private Action Compile(LetExpression let) return () => { - global.Initializer = Compiler.CompileNode(let.Value); + global.Initializer = Compiler.CompileNode(let.Value).Unwrap(); if (let.Type is not null) - global.Type = Compiler.CompileType(let.Type); + global.Type = Compiler.CompileType(let.Type).Unwrap(); else if (Compiler.Compiler.TypeSystem.IsTyped(global.Initializer, out var type)) global.Type = type; @@ -94,13 +97,16 @@ private Action Compile(LetExpression let) global.IR = Compiler.Compiler.CompileIRObject(global, null); if (global.Initializer is not null) - global.Initializer = Compiler.Compiler.Cast(global.Initializer, global.Type); + global.Initializer = Compiler.Compiler.TypeSystem.ImplicitCast(global.Initializer, global.Type).Unwrap(); }; } private Action Compile(Module module) { - var compiler = new ModuleCompiler(Compiler, module); + var compiler = new ModuleCompiler(Compiler, module) + { + DefaultMetaClass = DefaultMetaClass, + }; Object.Content.Add(compiler.Object); @@ -143,10 +149,10 @@ private Action Compile(VarExpression var) return () => { if (var.Value is not null) - global.Initializer = Compiler.CompileNode(var.Value); + global.Initializer = Compiler.CompileNode(var.Value).Unwrap(); if (var.Type is not null) - global.Type = Compiler.CompileType(var.Type); + global.Type = Compiler.CompileType(var.Type).Unwrap(); else if (global.Initializer is not null) if (Compiler.Compiler.TypeSystem.IsTyped(global.Initializer, out var type)) global.Type = type; @@ -156,7 +162,7 @@ private Action Compile(VarExpression var) global.IR = Compiler.Compiler.CompileIRObject(global, null); if (global.Initializer is not null) - global.Initializer = Compiler.Compiler.Cast(global.Initializer, global.Type); + global.Initializer = Compiler.Compiler.TypeSystem.ImplicitCast(global.Initializer, global.Type).Unwrap(); }; } } diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/for/ForLoopCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/for/ForLoopCompiler.cs new file mode 100644 index 00000000..078b4fee --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/for/ForLoopCompiler.cs @@ -0,0 +1,120 @@ + +namespace ZSharp.ZSSourceCompiler +{ + public class ForStatementCompiler(ZSSourceCompiler compiler, ForStatement node) + : ContextCompiler(compiler, node, new()) + , IOverrideCompileStatement + { + private CompilerObject Iterator { get; set; } + + private CompilerObject MoveNext { get; set; } + + private CompilerObject Current { get; set; } + + public override ForLoop Compile() + { + var source = Object.Source = Compiler.CompileNode(Node.Source).Unwrap(); + + Iterator = Compiler.Compiler.Member(source, "getIterator"); + Iterator = Compiler.Compiler.Call(Iterator, []); + if (!Compiler.Compiler.TypeSystem.IsTyped(Iterator, out var iteratorType)) + { + Compiler.LogError($"For loop source must provide a valid iterator", Node); + return Object; + } + + MoveNext = Compiler.Compiler.Member(new Objects.RawCode(new([ + new IR.VM.Dup() + ]) + { + Types = [iteratorType] + }), "moveNext"); + MoveNext = Compiler.Compiler.Call(MoveNext, []); + MoveNext = Compiler.Compiler.Cast(MoveNext, Compiler.Compiler.TypeSystem.Boolean); + + Current = Compiler.Compiler.Member(new Objects.RawCode(new([ + new IR.VM.Dup() + ]) + { + Types = [iteratorType] + }), "getCurrent"); + Current = Compiler.Compiler.Call(Current, []); + + Object.Iterator = Iterator; + Object.MoveNext = MoveNext; + Object.Current = Current; + + using (Context.Compiler(this)) + using (Context.Scope()) + { + CompileForValue(); + Object.For = Compiler.CompileNode(Node.Body).Unwrap(); + } + + if (Node.Else is not null) + using (Context.Scope()) + Object.Else = CompileElse(); + + return base.Compile(); + } + + protected ObjectResult CompileBreak(BreakStatement @break) + { + // TODO: add support for 'break from' statement + + if (@break.Value is not null) + Compiler.LogError("Break statement in a for statement must not have a value", @break); + + return ObjectResult.Ok(new Objects.RawCode( + new([ + new IR.VM.Jump(Object.EndLabel) + ]) + )); + } + + protected CompilerObject CompileElse() + => Compiler.CompileNode(Node.Else!).Unwrap(); + + public ObjectResult? CompileNode(ZSSourceCompiler compiler, Statement node) + => node switch + { + BreakStatement @break => CompileBreak(@break), + _ => null + }; + + private void CompileForValue() + { + Object.Value = (Node.Value switch { + LetForValue let => CompileLetForValue(let), + _ => throw new() + }).Unwrap(); + } + + private ObjectResult CompileLetForValue(LetForValue let) + { + var allocator = Compiler.Compiler.CurrentContext.FindContext(); + if (allocator is null) + return Compiler.CompilationError($"Could not find memory allocator in context chain", Node); + + var local = allocator.Allocate( + let.Name, + let.Type is not null + ? Compiler.CompileType(let.Type).Unwrap() + : Compiler.Compiler.TypeSystem.IsTyped(Current, out var type) + ? type + : throw new(), + Current + ); + + if (local is not Objects.Local local1) + throw new NotImplementedException(); + + Compiler.Context.CurrentScope.Set(let.Name, local); + + return ObjectResult.Ok(new Objects.RawCode(new(local1.IR?.Initializer!) + { + Types = [local1.Type] + })); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/while/WhileExpressionCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/while/WhileExpressionCompiler.cs new file mode 100644 index 00000000..00040be2 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/while/WhileExpressionCompiler.cs @@ -0,0 +1,45 @@ +namespace ZSharp.ZSSourceCompiler +{ + public sealed class WhileExpressionCompiler(ZSSourceCompiler compiler, WhileExpression node, Compiler.IType type) + : WhileLoopCompiler(compiler, node, type) + { + protected override ObjectResult CompileBreak(BreakStatement @break) + { + if (@break.Value is null) + return Compiler.CompilationError("Break statement in a while expression must have a value", @break); + + var valueResult = Compiler.CompileNode(@break.Value); + if ( + valueResult + .When(out var value) + .Error(out var error) + ) + return ObjectResult.Error(error); + if (!Compiler.Compiler.TypeSystem.IsTyped(value!, out var type)) + return Compiler.CompilationError("Value must be a valid RT value!", @break.Value); + + Object.Type ??= type; + + if (!Compiler.Compiler.TypeSystem.ImplicitCast(value, Object.Type).Ok(out var breakValue)) + return Compiler.CompilationError("Could not cast break value to while expression type", @break.Value); + + var code = Compiler.Compiler.IR.CompileCode(breakValue).Unwrap(); + + return ObjectResult.Ok(new Objects.RawCode( + new([ + .. code.Instructions, + + new IR.VM.Jump(Object.EndLabel) + ]) + )); + } + + protected override ObjectResult CompileElse() + { + if (Object.Type is null) + return Compiler.CompilationError("While expression must have a type", Node); + + return ObjectResult.Ok(Compiler.Compiler.TypeSystem.ImplicitCast(Compiler.CompileNode(Node.Else!).Unwrap(), Object.Type).Unwrap()); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/while/WhileLoopCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/while/WhileLoopCompiler.cs new file mode 100644 index 00000000..687dfa12 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/while/WhileLoopCompiler.cs @@ -0,0 +1,38 @@ + +namespace ZSharp.ZSSourceCompiler +{ + public abstract class WhileLoopCompiler(ZSSourceCompiler compiler, WhileExpression node, Compiler.IType type) + : ContextCompiler, WhileLoop>(compiler, node, new() + { + Type = type + }) + , IOverrideCompileStatement + where TElse : Node + { + public override WhileLoop Compile() + { + Object.Condition = Compiler.CompileNode(Node.Condition).Unwrap(); + + using (Context.Compiler(this)) + using (Context.Scope()) + Object.While = Compiler.CompileNode(Node.Body).Unwrap(); + + if (Node.Else is not null) + using (Context.Scope()) + Object.Else = CompileElse().Unwrap(); + + return base.Compile(); + } + + protected abstract ObjectResult CompileBreak(BreakStatement @break); + + protected abstract ObjectResult CompileElse(); + + public ObjectResult? CompileNode(ZSSourceCompiler compiler, Statement node) + => node switch + { + BreakStatement @break => CompileBreak(@break), + _ => null + }; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/while/WhileStatementCompiler.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/while/WhileStatementCompiler.cs new file mode 100644 index 00000000..1f9074c2 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/loops/while/WhileStatementCompiler.cs @@ -0,0 +1,23 @@ +namespace ZSharp.ZSSourceCompiler +{ + public sealed class WhileStatementCompiler(ZSSourceCompiler compiler, WhileExpression node) + : WhileLoopCompiler(compiler, node, compiler.Compiler.TypeSystem.Void) + { + protected override ObjectResult CompileBreak(BreakStatement @break) + { + // TODO: add support for 'break from' statement + + if (@break.Value is not null) + return Compiler.CompilationError("Break statement in a while statement must not have a value", @break); + + return ObjectResult.Ok(new Objects.RawCode( + new([ + new IR.VM.Jump(Object.EndLabel) + ]) + )); + } + + protected override ObjectResult CompileElse() + => Compiler.CompileNode(Node.Else!); + } +} diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/Case.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/Case.cs new file mode 100644 index 00000000..cd27b855 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/Case.cs @@ -0,0 +1,87 @@ +using ZSharp.Compiler; + +namespace ZSharp.Objects +{ + public sealed class Case + : CompilerObject + , ICompileIRCode + { + public sealed class When + : CompilerObject + { + public required CompilerObject Value { get; set; } + + public required CompilerObject Body { get; set; } + } + + public required CompilerObject Value { get; set; } + + public required CompilerObject Of { get; set; } + + public List Clauses { get; init; } = []; + + public CompilerObject? Else { get; set; } + + public IRCode CompileIRCode(Compiler.Compiler compiler) + { + IRCode result = new(); + + var caseEnd = new IR.VM.Nop(); + + var valueCode = compiler.CompileIRCode(Value); + result.Append(valueCode); + + IRCode clauseBodies = new(); + + foreach (var clause in Clauses) + { + var entry = new IR.VM.Pop(); + + clauseBodies.Instructions.AddRange([ + entry, + //new IR.VM.Pop(), + ..compiler.CompileIRCode(clause.Body).Instructions, + new IR.VM.Jump(caseEnd) + ]); + + var condition = compiler.Call(Of, [ + new(new RawCode( + new([ + new IR.VM.Dup() + ]) { + Types = [valueCode.RequireValueType()] + } + //compiler.CompileIRCode(Value) + )), + new(clause.Value) + ]); + + result.Instructions.AddRange([ + ..compiler.CompileIRCode(condition).Instructions, + new IR.VM.JumpIfTrue(entry) + ]); + } + + result.Instructions.Add(new IR.VM.Pop()); + result.Types.RemoveAt(result.Types.Count - 1); + + if (Else is not null) + { + var entry = new IR.VM.Nop(); + + var elseCode = compiler.CompileIRCode(Else); + + clauseBodies.Instructions.Add(entry); + clauseBodies.Append(elseCode); + + result.Instructions.Add(new IR.VM.Jump(entry)); + } + + result.Append(clauseBodies); + + result.Instructions.Add(caseEnd); + + return result; + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/ForLoop.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/ForLoop.cs new file mode 100644 index 00000000..2d033bc5 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/ForLoop.cs @@ -0,0 +1,65 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class ForLoop + : CompilerObject + , ICompileIRCode + { + public CompilerObject Iterator { get; set; } + + public CompilerObject MoveNext { get; set; } + + public CompilerObject Current { get; set; } + + public CompilerObject Value { get; set; } + + public CompilerObject Source { get; set; } + + public IR.VM.Instruction NextLabel { get; } = new IR.VM.Nop(); + + public CompilerObject For { get; set; } + + public IR.VM.Instruction ElseLabel { get; } = new IR.VM.Nop(); + + public CompilerObject? Else { get; set; } + + public IR.VM.Instruction EndLabel { get; } = new IR.VM.Nop(); + + public IRCode CompileIRCode(Compiler.Compiler compiler) + { + return new([ + .. compiler.CompileIRCode( + Iterator + ).Instructions, + + NextLabel, + + .. compiler.CompileIRCode( + MoveNext + ).Instructions, + + new IR.VM.JumpIfFalse(ElseLabel), + + .. compiler.CompileIRCode( + compiler.Cast( + Value, + compiler.TypeSystem.Void + ) + ).Instructions, + + .. compiler.CompileIRCode(For).Instructions, + + new IR.VM.Jump(NextLabel), + + ElseLabel, + .. Else is null ? [] : compiler.CompileIRCode(Else).Instructions, + + EndLabel, + + new IR.VM.Pop() // Iterator + ] + ); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/If.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/If.cs new file mode 100644 index 00000000..1bfcd95c --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/If.cs @@ -0,0 +1,38 @@ +using ZSharp.Compiler; + +namespace ZSharp.Objects +{ + public sealed class If + : CompilerObject + , ICompileIRCode + { + public CompilerObject Body { get; set; } + + public CompilerObject Condition { get; set; } + + public IR.VM.Nop ElseLabel { get; } = new(); + + public CompilerObject? Else { get; set; } + + public IR.VM.Nop EndLabel { get; } = new(); + + public IRCode CompileIRCode(Compiler.Compiler compiler) + => new([ + .. compiler.CompileIRCode(compiler.TypeSystem.ImplicitCast(Condition, compiler.TypeSystem.Boolean).Unwrap()).Instructions, + + new IR.VM.JumpIfFalse(ElseLabel), + + .. compiler.CompileIRCode(Body).Instructions, + + new IR.VM.Jump(EndLabel), + + ElseLabel, + .. Else is null ? [] : compiler.CompileIRCode(Else).Instructions, + + EndLabel, + ]) + { + + }; + } +} diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/runtime code/objects/WhileLoop.cs b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/WhileLoop.cs similarity index 58% rename from ZSharp.ZSSourceCompiler/builtin-compilers/runtime code/objects/WhileLoop.cs rename to ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/WhileLoop.cs index 5e5a791d..e61750eb 100644 --- a/ZSharp.ZSSourceCompiler/builtin-compilers/runtime code/objects/WhileLoop.cs +++ b/ZSharp.SourceCompiler.Module/old/builtin-compilers/runtime code/objects/WhileLoop.cs @@ -19,40 +19,33 @@ public sealed class WhileLoop public IR.VM.Instruction EndLabel { get; } = new IR.VM.Nop(); - public CompilerObject Type => throw new(); + public required IType Type { get; set; } public IRCode CompileIRCode(Compiler.Compiler compiler) { return new([ ConditionLabel, .. compiler.CompileIRCode( - compiler.Cast(Condition, compiler.TypeSystem.Boolean) + compiler.TypeSystem.ImplicitCast(Condition, compiler.TypeSystem.Boolean).Unwrap() ).Instructions, new IR.VM.JumpIfFalse(ElseLabel), - - .. compiler.CompileIRCode( - compiler.Cast(While, compiler.TypeSystem.Void) - ).Instructions, + + .. compiler.CompileIRCode(While).Instructions, new IR.VM.Jump(ConditionLabel), ElseLabel, - .. Else is null ? [] : compiler.CompileIRCode( - compiler.Cast(Else, compiler.TypeSystem.Void) - ).Instructions, + .. Else is null ? [] : compiler.CompileIRCode(Else).Instructions, EndLabel ] - ); - } - - CompilerObject ITyped.GetType(Compiler.Compiler compiler) - { - if (compiler.TypeSystem.IsTyped(While, out var type)) - return type; - - throw new(); + ) + { + Types = Type == compiler.TypeSystem.Void + ? [] + : [Type] + }; } } } diff --git a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Compilers.cs b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Compilers.cs similarity index 77% rename from ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Compilers.cs rename to ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Compilers.cs index 7486646a..22530dc5 100644 --- a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Compilers.cs +++ b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Compilers.cs @@ -9,7 +9,10 @@ public DocumentCompiler CreateDocumentCompiler(AST.Document document, string pat public ModuleCompiler CreateModuleCompiler(Module module) { - var compiler = new ModuleCompiler(this, module); + var compiler = new ModuleCompiler(this, module) + { + DefaultMetaClass = DefaultMetaClass, + }; compiler.oopTypesCompilers.Add("class", (c, oop) => { @@ -17,14 +20,11 @@ public ModuleCompiler CreateModuleCompiler(Module module) // for C# types, we should create an uninitialized object via System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject // ConstructorInfo.Invoke has an overload which takes `this` as the first parameter (for late initialization). - if (metaClass is not null) c.LogError("Metaclasses are not supported yet.", oop); + if (metaClass is not null) c.LogError("Metaclasses are not supported yet.", oop); - var @object = new Objects.Class() - { - Name = oop.Name, - }; + // TODO: if has generic, return generic class compiler - return new ClassCompiler(c, oop, @object); + return new ClassCompiler(c, oop, compiler.DefaultMetaClass); }); compiler.oopTypesCompilers.Add("interface", (c, oop) => diff --git a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.ImportSystem.cs b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.ImportSystem.cs similarity index 62% rename from ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.ImportSystem.cs rename to ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.ImportSystem.cs index 6c40c2fd..f18fc68b 100644 --- a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.ImportSystem.cs +++ b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.ImportSystem.cs @@ -4,10 +4,10 @@ public partial class ZSSourceCompiler { public ImportSystem ImportSystem { get; } = new(); - public StringImporter StringImporter { get; } = new(); + public StringImporter StringImporter { get; } - public StandardLibraryImporter StandardLibraryImporter { get; } = new(); + public StandardLibraryImporter StandardLibraryImporter { get; } - public ZSImporter ZSImporter { get; } = new(); + public ZSImporter ZSImporter { get; } } } diff --git a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Initialize.cs b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Initialize.cs similarity index 100% rename from ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Initialize.cs rename to ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Initialize.cs diff --git a/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Logging.cs b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Logging.cs new file mode 100644 index 00000000..64c2e08b --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Logging.cs @@ -0,0 +1,14 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class ZSSourceCompiler + { + public void LogError(string message, Node origin) + where T : class + => Compiler.Log.Error(message, new NodeLogOrigin(origin)); + + public void LogError(string message, Node origin) + => LogError(message, origin); + } +} diff --git a/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.OOP.cs b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.OOP.cs new file mode 100644 index 00000000..ed59c06b --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.OOP.cs @@ -0,0 +1,7 @@ +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class ZSSourceCompiler + { + public Objects.ClassMetaClass DefaultMetaClass { get; set; } = new(); + } +} diff --git a/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Operators.cs b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Operators.cs new file mode 100644 index 00000000..fb26c5c1 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.Operators.cs @@ -0,0 +1,7 @@ +namespace ZSharp.ZSSourceCompiler +{ + public partial class ZSSourceCompiler + { + public Compiler.Ops Operators { get; } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.ResultTools.cs b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.ResultTools.cs new file mode 100644 index 00000000..78cdc826 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.ResultTools.cs @@ -0,0 +1,23 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class ZSSourceCompiler + { + public bool UnpackResult( + Compiler.Result result, + [NotNullWhen(true)] out T? value, + Node origin + ) + where T : class + { + if (result.Error(out var error)) { + value = null; + LogError(error, origin); + return false; + } + value = result.Unwrap(); + return true; + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.cs b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.cs new file mode 100644 index 00000000..842a3a09 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/compiler/ZSSourceCompiler.cs @@ -0,0 +1,94 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class ZSSourceCompiler + { + public Interpreter.Interpreter Interpreter { get; } + + public Compiler.Compiler Compiler => Interpreter.Compiler; + + public ExpressionCompiler ExpressionCompiler { get; } + + public StatementCompiler StatementCompiler { get; } + + public Context Context { get; } + + public ZSSourceCompiler(Interpreter.Interpreter interpreter) + { + Interpreter = interpreter; + + Context = new(this); + + ExpressionCompiler = new(this); + StatementCompiler = new(this); + + Operators = Compiler.Feature(); + + StringImporter = new(interpreter); + StandardLibraryImporter = new(interpreter); + ZSImporter = new(interpreter); + + Initialize(); + } + + public ObjectResult CompileNode(Expression expression) + => CompileNode(expression); + + public ObjectResult CompileNode(Statement statement) + => CompileNode(statement); + + private ObjectResult CompileNode(T node) + where T : Node + { + foreach (var compiler in (IEnumerable)[ + Context.CurrentCompiler, + Context.DefaultCompiler, + ]) + { + if (compiler is not IOverrideCompileNode compileNode) + continue; + + var result = compileNode.CompileNode(this, node); + + if (result is null) continue; + + return result; + } + + return CompilationError( + "Could not compile node", node + ); + } + + public TypeResult CompileType(Expression expression) + { + if ( + CompileNode(expression) + .When(out var typeObject) + .Error(out var error) + ) + return TypeResult.Error(error); + + if (typeObject is IType type) + return TypeResult.Ok(type); + + return CompilationError( + "Dynamic type evaluation is not implemented yet", expression + ); + } + + public Result CompilationError( + string error, + Node node + ) + where T : class + => Result.Error(new CompilationError(node, error)); + + public ObjectResult CompilationError( + string error, + Node node + ) + => CompilationError(error, node); + } +} diff --git a/ZSharp.SourceCompiler.Module/old/context/Context.Compilers.cs b/ZSharp.SourceCompiler.Module/old/context/Context.Compilers.cs new file mode 100644 index 00000000..04158474 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/context/Context.Compilers.cs @@ -0,0 +1,20 @@ +using CommonZ.Utils; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class Context + { + private CompilerBase currentCompiler; + + public CompilerBase CurrentCompiler => currentCompiler; + + public DefaultContextCompiler DefaultCompiler { get; } + + public ContextManager Compiler(CompilerBase compiler) + { + (currentCompiler, compiler) = (compiler, currentCompiler); + + return new(() => currentCompiler = compiler); + } + } +} diff --git a/ZSharp.ZSSourceCompiler/context/Context.Nodes.cs b/ZSharp.SourceCompiler.Module/old/context/Context.Nodes.cs similarity index 76% rename from ZSharp.ZSSourceCompiler/context/Context.Nodes.cs rename to ZSharp.SourceCompiler.Module/old/context/Context.Nodes.cs index ade5361a..490f0e5d 100644 --- a/ZSharp.ZSSourceCompiler/context/Context.Nodes.cs +++ b/ZSharp.SourceCompiler.Module/old/context/Context.Nodes.cs @@ -6,8 +6,6 @@ public sealed partial class Context { private readonly Mapping nodes = []; - public Node CurrentNode => Compiler()?.ContextNode ?? throw new InvalidOperationException(); - public Node? Node(CompilerObject @object) => nodes.GetValueOrDefault(@object); diff --git a/ZSharp.SourceCompiler.Module/old/context/Context.Scopes.cs b/ZSharp.SourceCompiler.Module/old/context/Context.Scopes.cs new file mode 100644 index 00000000..1c80b446 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/context/Context.Scopes.cs @@ -0,0 +1,44 @@ +using CommonZ.Utils; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class Context + { + private readonly Mapping objectContainerScopes = []; + private readonly Mapping objectContainedScopes = []; + + public IScopeContext GlobalScope { get; } + + public IScopeContext CurrentScope { get; private set; } + + public ScopeContext CreateScope() + => new(); + + public ContextManager Scope() + => Scope(CreateScope()); + + public ContextManager Scope(IScopeContext scope) + { + (CurrentScope, scope) = (scope, CurrentScope); + var revert = CurrentCompiler.Compiler.Compiler.UseContext(CurrentScope); + + return new(() => + { + CurrentScope = scope; + revert(); + }); + } + + public ContextManager Scope(CompilerObject @object) + => Scope(ContainedScope(@object) ?? ContainedScope(@object, CreateScope())); // TODO: proper exception: could not find scope for object + + public ScopeContext? ContainerScope(CompilerObject @object) + => objectContainerScopes.GetValueOrDefault(@object); + + public ScopeContext? ContainedScope(CompilerObject @object) + => objectContainedScopes.GetValueOrDefault(@object); + + public ScopeContext ContainedScope(CompilerObject @object, ScopeContext scope) + => objectContainedScopes[@object] = scope; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/context/Context.cs b/ZSharp.SourceCompiler.Module/old/context/Context.cs new file mode 100644 index 00000000..a322a408 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/context/Context.cs @@ -0,0 +1,17 @@ +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class Context + { + public ZSSourceCompiler SourceCompiler { get; } + + public Context(ZSSourceCompiler compiler, ScopeContext? globalScope = null) + { + SourceCompiler = compiler; + + GlobalScope = globalScope ?? new(); + compiler.Compiler.UseContext(CurrentScope = GlobalScope); + + currentCompiler = DefaultCompiler = new DefaultContextCompiler(compiler); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/capabilities/IMemoryAllocator.cs b/ZSharp.SourceCompiler.Module/old/contexts/capabilities/IMemoryAllocator.cs new file mode 100644 index 00000000..29e00f80 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/capabilities/IMemoryAllocator.cs @@ -0,0 +1,14 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public interface IMemoryAllocator + : IContext + { + public CompilerObject Allocate( + string name, + IType type, + CompilerObject? initializer = null + ); + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/capabilities/IObjectContext.cs b/ZSharp.SourceCompiler.Module/old/contexts/capabilities/IObjectContext.cs new file mode 100644 index 00000000..5692bd58 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/capabilities/IObjectContext.cs @@ -0,0 +1,20 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public interface IObjectContext + : IContext + { + public CompilerObject Object { get; } + } + + public interface IObjectContext + : IContext + , IObjectContext + where T : CompilerObject + { + public new T Object { get; } + + CompilerObject IObjectContext.Object => Object; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/capabilities/scope/ILookupContext.cs b/ZSharp.SourceCompiler.Module/old/contexts/capabilities/scope/ILookupContext.cs new file mode 100644 index 00000000..219fecc8 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/capabilities/scope/ILookupContext.cs @@ -0,0 +1,22 @@ +using System.Diagnostics.CodeAnalysis; +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public interface ILookupContext + : IContext + { + public CompilerObject? Get(string name); + + public T? Get(string name) + where T : class, CompilerObject + => Get(name) is T value ? value : null; + + public bool Get(string name, [NotNullWhen(true)] out CompilerObject? result) + => (result = Get(name)) is not null; + + public bool Get(string name, [NotNullWhen(true)] out T? result) + where T : class, CompilerObject + => (result = Get(name)) is not null; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/capabilities/scope/IScopeContext.cs b/ZSharp.SourceCompiler.Module/old/contexts/capabilities/scope/IScopeContext.cs new file mode 100644 index 00000000..cc7df7dc --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/capabilities/scope/IScopeContext.cs @@ -0,0 +1,11 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public interface IScopeContext + : IContext + , ILookupContext + { + public void Set(string name, CompilerObject @object); + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/concrete/ClassContext.cs b/ZSharp.SourceCompiler.Module/old/contexts/concrete/ClassContext.cs new file mode 100644 index 00000000..d28d6c4f --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/concrete/ClassContext.cs @@ -0,0 +1,17 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class ClassContext( + Objects.Class @class + ) + : IContext + , IObjectContext + { + public IContext? Parent { get; set; } + + public Objects.Class Class { get; } = @class; + + Objects.Class IObjectContext.Object => Class; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/concrete/ExpressionContext.cs b/ZSharp.SourceCompiler.Module/old/contexts/concrete/ExpressionContext.cs new file mode 100644 index 00000000..d443a21e --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/concrete/ExpressionContext.cs @@ -0,0 +1,17 @@ +using ZSharp.Compiler; +using ZSharp.Objects; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class ExpressionContext(Compiler.Compiler compiler) + : IContext + , ITypeInferenceContext + { + private readonly Compiler.Compiler compiler = compiler; + + IContext? IContext.Parent { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + InferredType ITypeInferenceContext.CreateInferredType(IInferredTypeResolver? resolver) + => (this as ITypeInferenceContext).CreateInferredType(compiler, resolver); + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/concrete/FunctionContext.cs b/ZSharp.SourceCompiler.Module/old/contexts/concrete/FunctionContext.cs new file mode 100644 index 00000000..20a0e461 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/concrete/FunctionContext.cs @@ -0,0 +1,34 @@ +using ZSharp.Compiler; +using ZSharp.Objects; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class FunctionContext( + Compiler.Compiler compiler, + RTFunction function + ) + : IContext + , IMemoryAllocator + , IObjectContext + { + public IContext? Parent { get; set; } + + public RTFunction Function { get; } = function; + + RTFunction IObjectContext.Object => Function; + + CompilerObject IMemoryAllocator.Allocate(string name, IType type, CompilerObject? initializer) + { + Local local = new() + { + Name = name, + Initializer = initializer, + Type = type + }; + + local.IR = compiler.CompileIRObject(local, Function.IR?.Body ?? throw new()); + + return local; + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/concrete/ObjectContext.cs b/ZSharp.SourceCompiler.Module/old/contexts/concrete/ObjectContext.cs new file mode 100644 index 00000000..bb2f4cc4 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/concrete/ObjectContext.cs @@ -0,0 +1,13 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public class ObjectContext(T @object) + : IObjectContext + where T : CompilerObject + { + public IContext? Parent { get; set; } + + public T Object { get; } = @object; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/concrete/ScopeContext.cs b/ZSharp.SourceCompiler.Module/old/contexts/concrete/ScopeContext.cs new file mode 100644 index 00000000..4b60a6a3 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/concrete/ScopeContext.cs @@ -0,0 +1,20 @@ +using CommonZ.Utils; +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class ScopeContext() + : IContext + , IScopeContext + { + private readonly Mapping scope = []; + + public IContext? Parent { get; set; } + + public CompilerObject? Get(string name) + => scope.TryGetValue(name, out var result) ? result : null; + + public void Set(string name, CompilerObject @object) + => scope[name] = @object; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/contexts/strategies/UntilContextTypeStrategy.cs b/ZSharp.SourceCompiler.Module/old/contexts/strategies/UntilContextTypeStrategy.cs new file mode 100644 index 00000000..e17cb45d --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/contexts/strategies/UntilContextTypeStrategy.cs @@ -0,0 +1,20 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class UntilContextTypeStrategy( + IContextChainStrategy strategy + ) + : IContextChainStrategy + where T : IContext + { + public IContextChainStrategy Strategy { get; } = strategy; + + IContext? IContextChainStrategy.NextContext(IContext context) + { + if (context is T) return null; + + return Strategy.NextContext(context); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/core-compilers/DefaultContextCompiler.cs b/ZSharp.SourceCompiler.Module/old/core-compilers/DefaultContextCompiler.cs new file mode 100644 index 00000000..807bc4cb --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/core-compilers/DefaultContextCompiler.cs @@ -0,0 +1,15 @@ + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class DefaultContextCompiler(ZSSourceCompiler compiler) + : CompilerBase(compiler) + , IOverrideCompileExpression + , IOverrideCompileStatement + { + public ObjectResult CompileNode(ZSSourceCompiler compiler, Expression node) + => compiler.ExpressionCompiler.CompileNode(node); + + public ObjectResult CompileNode(ZSSourceCompiler compiler, Statement node) + => compiler.StatementCompiler.CompileNode(node); + } +} diff --git a/ZSharp.SourceCompiler.Module/old/core-compilers/expression/ExpressionCompiler.Literals.cs b/ZSharp.SourceCompiler.Module/old/core-compilers/expression/ExpressionCompiler.Literals.cs new file mode 100644 index 00000000..1aca22a2 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/core-compilers/expression/ExpressionCompiler.Literals.cs @@ -0,0 +1,34 @@ +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class ExpressionCompiler + { + public ObjectResult Compile(ArrayLiteral array) + { + Objects.ArrayLiteral result = new(); + + ObjectResult objectResult; + foreach (var item in array.Items) + if ( + (objectResult = Compiler.CompileNode(item)).IsError + ) + return objectResult; + else result.Items.Add(objectResult.Unwrap()); + + return ObjectResult.Ok(result); + } + + public ObjectResult Compile(LiteralExpression literal) + => literal.Type switch + { + LiteralType.String => Compiler.Compiler.CreateString(literal.Value), + LiteralType.False => Compiler.Compiler.CreateFalse(), + LiteralType.True => Compiler.Compiler.CreateTrue(), + LiteralType.Null => Compiler.Compiler.CreateNull(), + LiteralType.Number => Compiler.Compiler.CreateInteger(int.Parse(literal.Value)), + _ => null + } is CompilerObject result + ? ObjectResult.Ok(result) + : Compiler.CompilationError($"Could not compile literal of type {literal.Type}", literal) + ; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/core-compilers/expression/ExpressionCompiler.cs b/ZSharp.SourceCompiler.Module/old/core-compilers/expression/ExpressionCompiler.cs new file mode 100644 index 00000000..a855a893 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/core-compilers/expression/ExpressionCompiler.cs @@ -0,0 +1,233 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed partial class ExpressionCompiler(ZSSourceCompiler compiler) + : CompilerBase(compiler) + { + public ObjectResult? CompileNode(Expression expression) + => expression switch + { + ArrayLiteral array => Compile(array), + BinaryExpression binary => Compile(binary), + CallExpression call => Compile(call), + CastExpression cast => Compile(cast), + IdentifierExpression identifier => Compile(identifier), + IndexExpression index => Compile(index), + IsOfExpression isOf => Compile(isOf), + LiteralExpression literal => Compile(literal), + WhileExpression @while => Compile(@while), + _ => null + }; + + private ObjectResult Compile(BinaryExpression binary) + { + // TODO: NO SPECIAL TREATMENT FOR OPERATORS . and = + + var left = Compiler.CompileNode(binary.Left).Unwrap(); + + if (binary.Operator == ".") + { + CompilerObject member; + + if (binary.Right is IdentifierExpression identifier) + member = Compiler.Compiler.CreateString(identifier.Name); + + else if (binary.Right is not LiteralExpression literal) + return Compiler.CompilationError("Expected a literal expression on the right side of the dot operator.", binary.Right); + + else member = Compile(literal).Unwrap(); + + if (Compiler.Compiler.IsString(member, out var memberName)) + return ObjectResult.Ok(Compiler.Compiler.CG.Member(left, memberName).Unwrap()); + if (Compiler.Compiler.IsLiteral(member, out var memberIndex)) + return ObjectResult.Ok(Compiler.Compiler.Member(left, memberIndex.Value)); + + return Compiler.CompilationError("Expected a string or an integer literal on the right side of the dot operator.", binary.Right); + } + + var right = Compiler.CompileNode(binary.Right).Unwrap(); + + if (binary.Operator == "=") + return ObjectResult.Ok(Compiler.Compiler.CG.Set(left, right).Unwrap()); + + if (!Compiler.Operators.Binary.Cache(binary.Operator, out var @operator)) + return Compiler.CompilationError($"Operator '{binary.Operator}' is not defined.", binary); + + return ObjectResult.Ok( + Compiler.Compiler.CG.Call(@operator, [new(left), new(right)]).Unwrap() + ); + } + + private ObjectResult Compile(CallExpression call) + { + if ( + Compiler.CompileNode(call.Callee) + .When(out var callable) + .Error(out var error) + ) + return ObjectResult.Error(error); + + var argsResults = call.Arguments + .Select( + arg => + { + if ( + Compiler.CompileNode(arg.Value) + .When(out var value) + .Error(out var error) + ) + return Result, Error>.Error(error); + return Result, Error>.Ok( + new Argument_NEW(arg.Name, value!) + ); + } + ) + .ToArray(); + + if (CombineErrorResults(argsResults, out var argsError)) + return ObjectResult.Error(argsError); + + if ( + Compiler.Compiler.CG.Call( + callable!, + [.. argsResults.Select(arg => arg.Unwrap())] + ) + .When(out var result) + .Error(out var callError) + ) + return Compiler.CompilationError(callError, call); + + return ObjectResult.Ok(result!); + } + + private ObjectResult Compile(CastExpression cast) + { + var expression = Compiler.CompileNode(cast.Expression).Unwrap(); + + var targetType = Compiler.CompileType(cast.TargetType).Unwrap(); + + if (targetType is not Objects.Nullable) + { + Compiler.LogError("Casting to non-nullable type is not supported yet", cast); + + targetType = new Objects.Nullable(targetType); + } + + if ( + Compiler.Compiler.CG.Cast(expression, targetType) + .When(out var typeCast) + .Error(out var error) + ) + return Compiler.CompilationError(error, cast); + + if ( + Compiler.Compiler.IR.CompileCode(typeCast!.Cast) + .When(out var castCode) + .Error(out error) + ) + return Compiler.CompilationError(error, cast); + + if (typeCast.CanFail) + castCode!.Instructions.Add(typeCast.OnFail); + + castCode!.Types[0] = (targetType as Objects.Nullable)!.UnderlyingType; + + return ObjectResult.Ok(new Objects.RawCode(castCode)); + } + + private ObjectResult Compile(IdentifierExpression identifier) + { + CompilerObject? result = null; + + Compiler.Compiler.CurrentContext.PerformOperation( + scope => + { + return scope.Get(identifier.Name, out result); + } + ); + + if (result is not null) return ObjectResult.Ok(result); + + return Compiler.CompilationError($"Could not resolve name {identifier.Name}", identifier); + } + + private ObjectResult Compile(IndexExpression index) + { + var indexable = Compiler.CompileNode(index.Target).Unwrap(); + + var args = index.Arguments.Select(arg => new Argument_NEW(arg.Name, Compiler.CompileNode(arg.Value).Unwrap())); + + return ObjectResult.Ok(Compiler.Compiler.Map(indexable, @object => Compiler.Compiler.CG.Index(@object, [.. args]).Unwrap())); + } + + private ObjectResult Compile(IsOfExpression isOf) + { + var value = Compiler.CompileNode(isOf.Expression).Unwrap(); + var type = Compiler.CompileType(isOf.OfType).Unwrap(); + + if ( + Compiler.Compiler.CG.TypeMatch(value, type) + .When(out var match) + .Error(out var error) + ) + return Compiler.CompilationError(error, isOf); + + if ( + Compiler.Compiler.IR.CompileCode(match!.Match) + .When(out var matchCode) + .Error(out error) + ) + return Compiler.CompilationError(error, isOf); + + IR.VM.Nop noMatch = new(); + + matchCode!.Instructions.AddRange([ + new IR.VM.Pop(), + new IR.VM.PutFalse(), + new IR.VM.Jump(noMatch), + ]); + + if (isOf.Name is not null && isOf.Name != string.Empty && isOf.Name != "_") + { + var allocator = Compiler.Compiler.CurrentContext.FindContext(); + if (allocator is null) + return Compiler.CompilationError($"Could not find memory allocator in context chain", isOf); + + var local = allocator.Allocate( + isOf.Name, + type, + new Objects.RawCode(new([ + match.OnMatch + ]) + { + Types = [type] + }) + ); + + if (local is not Objects.Local localObject) + throw new NotImplementedException(); + + Compiler.Context.CurrentScope.Set(isOf.Name, local); + + matchCode.Instructions.AddRange([ + .. localObject.IR!.Initializer!, + new IR.VM.Pop(), + new IR.VM.PutTrue(), + ]); + } + + matchCode.Instructions.Add(noMatch); + + matchCode.Types.Clear(); + matchCode.Types.Add(Compiler.Compiler.TypeSystem.Boolean); + + return ObjectResult.Ok(new Objects.RawCode(matchCode)); + } + + private ObjectResult Compile(WhileExpression @while) + { + return ObjectResult.Ok(new WhileExpressionCompiler(Compiler, @while, null!).Compile()); + } + } +} diff --git a/ZSharp.SourceCompiler.Module/old/core-compilers/statement/StatementCompiler.cs b/ZSharp.SourceCompiler.Module/old/core-compilers/statement/StatementCompiler.cs new file mode 100644 index 00000000..ac4b248e --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/core-compilers/statement/StatementCompiler.cs @@ -0,0 +1,245 @@ +using ZSharp.Compiler; + +namespace ZSharp.ZSSourceCompiler +{ + public sealed class StatementCompiler(ZSSourceCompiler compiler) + : CompilerBase(compiler) + { + public ObjectResult? CompileNode(Statement statement) + => statement switch + { + BlockStatement block => Compile(block), + CaseStatement @case => Compile(@case), + ExpressionStatement expressionStatement => Compile(expressionStatement), + ForStatement @for => Compile(@for), + IfStatement @if => Compile(@if), + ImportStatement import => Compile(import), + _ => null + }; + + private ObjectResult Compile(Expression expression) + => expression switch + { + WhileExpression @while => Compile(@while), + _ => Compiler.CompileNode(expression) + }; + + private ObjectResult Compile(BlockStatement block) + { + var code = new Compiler.IRCode(); + + var coResults = block.Statements + .Select(Compiler.CompileNode) + .ToArray(); + + if (CombineErrorResults(coResults, out var coErrors)) + return ObjectResult.Error(coErrors); + + var irResults = coResults + .Select(coResult => coResult.Unwrap()) + .Select(Compiler.Compiler.IR.CompileCode) + .Select(irResult => + irResult.Else(error => new CompilationError(null!, error) as Error) + ) + .ToArray(); + + if (CombineErrorResults(irResults, out var irErrors)) + return ObjectResult.Error(irErrors); + + foreach (var ir in irResults.Select(irResult => irResult.Unwrap())) + code.Append(ir); + + if (!code.IsVoid) + return Compiler.CompilationError( + $"Block must not have a value", block + ); + + return ObjectResult.Ok(new Objects.RawCode(code)); + } + + private ObjectResult Compile(ExpressionStatement expressionStatement) + { + if (expressionStatement.Expression is null) + return ObjectResult.Ok(new Objects.RawCode(new())); + + var coResult = expressionStatement.Expression switch { + WhileExpression @while => Compile(@while), + _ => Compiler.CompileNode(expressionStatement.Expression) + }; + + if ( + coResult + .When(out var co) + .IsError + ) + return coResult; + + var irResult = Compiler.Compiler.IR.CompileCode(co!); + + if ( + irResult + .When(out var ir) + .Error(out var irError) + ) + return Compiler.CompilationError( + irError, expressionStatement.Expression + ); + + if (ir!.IsArray) + return Compiler.CompilationError( + "Expression evaluated to more than 1 values", + expressionStatement.Expression + ); + + if (ir.IsValue) + { + ir.Instructions.Add(new IR.VM.Pop()); + ir.Types.Clear(); + } + + return ObjectResult.Ok(new Objects.RawCode(ir)); + } + + private ObjectResult Compile(CaseStatement @case) + { + var ofResult = @case.Of is null + ? ObjectResult.Ok(Compiler.Operators.Binary.Cache("==") ?? throw new()) + : Compiler.CompileNode(@case.Of); + + var valueResult = @case.Value is null + ? ObjectResult.Ok(Compiler.Compiler.CreateTrue()) + : Compiler.CompileNode(@case.Value); + + var elseResult = @case.Else is null + ? ObjectResult.Ok(new Objects.RawCode(new())) + : Compiler.CompileNode(@case.Else); + + var clausesResults = @case.WhenClauses + .Select(clause => + { + var bodyResult = Compiler.CompileNode(clause.Body ?? throw new()); + var valueResult = Compiler.CompileNode(clause.Value); + + if (CombineErrorResults([bodyResult, valueResult], out var error)) + return Result.Error(error); + + return Result.Ok(new() + { + Body = bodyResult.Unwrap(), + Value = valueResult.Unwrap(), + }); + }).ToArray(); + + if (CombineErrorResults([ + ofResult, + valueResult, + .. clausesResults.Select(r => r.When(v => v as CompilerObject)) + ], out var error)) + return ObjectResult.Error(error); + + return ObjectResult.Ok(new Objects.Case() + { + Of = ofResult.Unwrap(), + Value = valueResult.Unwrap(), + Else = elseResult.Unwrap(), + Clauses = [.. clausesResults.Select(r => r.Unwrap())], + }); + } + + private ObjectResult Compile(ForStatement @for) + => ObjectResult.Ok(new ForStatementCompiler(Compiler, @for).Compile()); + + private ObjectResult Compile(IfStatement @if) + { + var conditionResult = Compiler.CompileNode(@if.Condition); + var bodyResult = Compiler.CompileNode(@if.If); + var elseResult = @if.Else is null + ? ObjectResult.Ok(new Objects.RawCode(new())) + : Compiler.CompileNode(@if.Else); + + if (CombineErrorResults([ + conditionResult, + bodyResult, + elseResult, + ], out var error)) + return ObjectResult.Error(error); + + return ObjectResult.Ok(new Objects.If() + { + Condition = conditionResult.Unwrap(), + Body = bodyResult.Unwrap(), + Else = elseResult.Unwrap() + }); + } + + private ObjectResult Compile(ImportStatement import) + { + IEnumerable arguments = [ + new CallArgument() { + Value = import.Source + }, + .. import.Arguments ?? [] + ]; + + var argumentsResults = arguments + .Select(arg => + { + if ( + Compiler.CompileNode(arg.Value) + .When(out var value) + .Error(out var error) + ) + return Result, Error>.Error(error); + + return Result, Error>.Ok( + new(arg.Name, value!) + ); + }) + .ToArray(); + + if (CombineErrorResults(argumentsResults, out var argumentErrors)) + return ObjectResult.Error(argumentErrors); + + var importResult = Compiler.Compiler.CG.Call( + Compiler.ImportSystem.ImportFunction, + [.. argumentsResults.Select(r => r.Unwrap())] + ); + + if (importResult.When(out var result).Error(out var error)) + return Compiler.CompilationError(error, import); + + if (import.Alias is not null) + Context.CurrentScope.Set(import.Alias, result!); + + if (import.ImportedNames is not null) + { + var memberResults = import.ImportedNames + .Select(name => (name, Compiler.Compiler.CG.Member(result!, name.Name))) + .Select(vs => + { + var (name, r) = vs; + + return (name, result: r.Else(e => new CompilationError(name, e) as Error)); + }) + .ToArray(); + + if (CombineErrorResults( + memberResults.Select(t => t.result), + out var memberErrors + )) + return ObjectResult.Error(memberErrors); + + foreach (var (name, memberResult) in memberResults) + Context.CurrentScope.Set( + name.Alias ?? name.Name, + memberResult.Unwrap() + ); + } + + return ObjectResult.Ok(result!); + } + + private ObjectResult Compile(WhileExpression @while) + => ObjectResult.Ok(new WhileStatementCompiler(Compiler, @while).Compile()); + } +} diff --git a/ZSharp.ZSSourceCompiler/extensibility/CompilerBase.cs b/ZSharp.SourceCompiler.Module/old/extensibility/CompilerBase.cs similarity index 100% rename from ZSharp.ZSSourceCompiler/extensibility/CompilerBase.cs rename to ZSharp.SourceCompiler.Module/old/extensibility/CompilerBase.cs diff --git a/ZSharp.ZSSourceCompiler/extensibility/ContextCompiler.cs b/ZSharp.SourceCompiler.Module/old/extensibility/ContextCompiler.cs similarity index 90% rename from ZSharp.ZSSourceCompiler/extensibility/ContextCompiler.cs rename to ZSharp.SourceCompiler.Module/old/extensibility/ContextCompiler.cs index 76dbde85..8db78163 100644 --- a/ZSharp.ZSSourceCompiler/extensibility/ContextCompiler.cs +++ b/ZSharp.SourceCompiler.Module/old/extensibility/ContextCompiler.cs @@ -3,8 +3,6 @@ public abstract class ContextCompiler(ZSSourceCompiler compiler) : CompilerBase(compiler) { - public abstract Node ContextNode { get; } - public abstract CompilerObject ContextObject { get; } public abstract CompilerObject CompileNode(); @@ -15,8 +13,6 @@ public abstract class ContextCompiler where TNode : Node where TObject : CompilerObject { - public override Node ContextNode => Node; - public override CompilerObject ContextObject => Object; public TNode Node { get; } diff --git a/ZSharp.ZSSourceCompiler/context/scoping/Constraint.cs b/ZSharp.SourceCompiler.Module/old/extensibility/error/Error.cs similarity index 56% rename from ZSharp.ZSSourceCompiler/context/scoping/Constraint.cs rename to ZSharp.SourceCompiler.Module/old/extensibility/error/Error.cs index 7780a88b..62f87cdb 100644 --- a/ZSharp.ZSSourceCompiler/context/scoping/Constraint.cs +++ b/ZSharp.SourceCompiler.Module/old/extensibility/error/Error.cs @@ -1,7 +1,7 @@ namespace ZSharp.ZSSourceCompiler { - public sealed class Constraint + public abstract class Error { - + } } diff --git a/ZSharp.SourceCompiler.Module/old/extensibility/error/errors/CombinedCompilationError.cs b/ZSharp.SourceCompiler.Module/old/extensibility/error/errors/CombinedCompilationError.cs new file mode 100644 index 00000000..491c3760 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/extensibility/error/errors/CombinedCompilationError.cs @@ -0,0 +1,9 @@ +namespace ZSharp.ZSSourceCompiler +{ + public sealed class CombinedCompilationError( + params CompilationError[] errors + ) : Error + { + public List Errors { get; } = [.. errors]; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/extensibility/error/errors/CompilationError.cs b/ZSharp.SourceCompiler.Module/old/extensibility/error/errors/CompilationError.cs new file mode 100644 index 00000000..d6ad14aa --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/extensibility/error/errors/CompilationError.cs @@ -0,0 +1,12 @@ +namespace ZSharp.ZSSourceCompiler +{ + public sealed class CompilationError( + Node node, + string error + ) : Error + { + public Node Node { get; } = node; + + public string Error { get; } = error; + } +} diff --git a/ZSharp.SourceCompiler.Module/old/extensibility/oop/ClassSpecification.cs b/ZSharp.SourceCompiler.Module/old/extensibility/oop/ClassSpecification.cs new file mode 100644 index 00000000..285b553a --- /dev/null +++ b/ZSharp.SourceCompiler.Module/old/extensibility/oop/ClassSpecification.cs @@ -0,0 +1,15 @@ +namespace ZSharp.ZSSourceCompiler +{ + public sealed class ClassSpecification + { + public string Name { get; set; } = string.Empty; + + public Node[]? GenericParameters { get; set; } + + public Node[]? Parameters { get; set; } + + public Expression[] Bases { get; set; } = []; + + public Expression[] Content { get; set; } = []; + } +} diff --git a/ZSharp.ZSSourceCompiler/extensibility/overrides/IOverrideCompileExpression.cs b/ZSharp.SourceCompiler.Module/old/extensibility/overrides/IOverrideCompileExpression.cs similarity index 100% rename from ZSharp.ZSSourceCompiler/extensibility/overrides/IOverrideCompileExpression.cs rename to ZSharp.SourceCompiler.Module/old/extensibility/overrides/IOverrideCompileExpression.cs diff --git a/ZSharp.ZSSourceCompiler/extensibility/overrides/IOverrideCompileNode.cs b/ZSharp.SourceCompiler.Module/old/extensibility/overrides/IOverrideCompileNode.cs similarity index 60% rename from ZSharp.ZSSourceCompiler/extensibility/overrides/IOverrideCompileNode.cs rename to ZSharp.SourceCompiler.Module/old/extensibility/overrides/IOverrideCompileNode.cs index 0502a1ff..51dfbe5a 100644 --- a/ZSharp.ZSSourceCompiler/extensibility/overrides/IOverrideCompileNode.cs +++ b/ZSharp.SourceCompiler.Module/old/extensibility/overrides/IOverrideCompileNode.cs @@ -3,6 +3,6 @@ public interface IOverrideCompileNode where T : Node { - public CompilerObject? CompileNode(ZSSourceCompiler compiler, T node); + public ObjectResult? CompileNode(ZSSourceCompiler compiler, T node); } } diff --git a/ZSharp.ZSSourceCompiler/extensibility/overrides/IOverrideCompileStatement.cs b/ZSharp.SourceCompiler.Module/old/extensibility/overrides/IOverrideCompileStatement.cs similarity index 100% rename from ZSharp.ZSSourceCompiler/extensibility/overrides/IOverrideCompileStatement.cs rename to ZSharp.SourceCompiler.Module/old/extensibility/overrides/IOverrideCompileStatement.cs diff --git a/ZSharp.ZSSourceCompiler/import system/ImportSystem.cs b/ZSharp.SourceCompiler.Module/old/import system/ImportSystem.cs similarity index 100% rename from ZSharp.ZSSourceCompiler/import system/ImportSystem.cs rename to ZSharp.SourceCompiler.Module/old/import system/ImportSystem.cs diff --git a/ZSharp.ZSSourceCompiler/import system/importers/StandardLibraryImporter.cs b/ZSharp.SourceCompiler.Module/old/import system/importers/StandardLibraryImporter.cs similarity index 80% rename from ZSharp.ZSSourceCompiler/import system/importers/StandardLibraryImporter.cs rename to ZSharp.SourceCompiler.Module/old/import system/importers/StandardLibraryImporter.cs index a9d5499c..21c25bef 100644 --- a/ZSharp.ZSSourceCompiler/import system/importers/StandardLibraryImporter.cs +++ b/ZSharp.SourceCompiler.Module/old/import system/importers/StandardLibraryImporter.cs @@ -1,12 +1,11 @@ using CommonZ.Utils; -using System.Data; using ZSharp.Compiler; namespace ZSharp.ZSSourceCompiler { - public sealed class StandardLibraryImporter + public sealed class StandardLibraryImporter(Interpreter.Interpreter interpreter) : CompilerObject - , ICTCallable + , ICTCallable_Old { public Mapping Libraries { get; } = []; @@ -18,7 +17,7 @@ public CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) if ( arguments.Length > 1 || arguments[0].Name is not null || - !compiler.IsString(compiler.Evaluate(arguments[0].Object), out var libraryName) + interpreter.Evaluate(arguments[0].Object).Unwrap() is not string libraryName ) { compiler.Log.Error("`std` importer must have exactly 1 argument of type `string`", this); diff --git a/ZSharp.ZSSourceCompiler/import system/importers/StringImporter.cs b/ZSharp.SourceCompiler.Module/old/import system/importers/StringImporter.cs similarity index 85% rename from ZSharp.ZSSourceCompiler/import system/importers/StringImporter.cs rename to ZSharp.SourceCompiler.Module/old/import system/importers/StringImporter.cs index ef91fcbc..ac653b1a 100644 --- a/ZSharp.ZSSourceCompiler/import system/importers/StringImporter.cs +++ b/ZSharp.SourceCompiler.Module/old/import system/importers/StringImporter.cs @@ -3,9 +3,9 @@ namespace ZSharp.ZSSourceCompiler { - public sealed class StringImporter + public sealed class StringImporter(Interpreter.Interpreter interpreter) : CompilerObject - , ICTCallable + , ICTCallable_Old { public Mapping Importers { get; } = []; @@ -15,7 +15,7 @@ public CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) { Argument sourceArgument = arguments.FirstOrDefault(arg => arg.Name is null) ?? throw new(); - if (!compiler.IsString(compiler.Evaluate(sourceArgument.Object), out var source)) + if (interpreter.Evaluate(sourceArgument.Object).Unwrap() is not string source) throw new(); // TODO: proper exception: first parameter must be a string string[] parts = source.Split(':', 2); diff --git a/ZSharp.ZSSourceCompiler/import system/importers/ZSImporter.cs b/ZSharp.SourceCompiler.Module/old/import system/importers/ZSImporter.cs similarity index 81% rename from ZSharp.ZSSourceCompiler/import system/importers/ZSImporter.cs rename to ZSharp.SourceCompiler.Module/old/import system/importers/ZSImporter.cs index 3ff9ce97..1888f88e 100644 --- a/ZSharp.ZSSourceCompiler/import system/importers/ZSImporter.cs +++ b/ZSharp.SourceCompiler.Module/old/import system/importers/ZSImporter.cs @@ -1,12 +1,11 @@ using CommonZ.Utils; -using System.Data; using ZSharp.Compiler; namespace ZSharp.ZSSourceCompiler { - public sealed class ZSImporter + public sealed class ZSImporter(Interpreter.Interpreter interpreter) : CompilerObject - , ICTCallable + , ICTCallable_Old { public Mapping Libraries { get; } = []; @@ -18,7 +17,7 @@ public CompilerObject Call(Compiler.Compiler compiler, Argument[] arguments) if ( arguments.Length > 1 || arguments[0].Name is not null || - !compiler.IsString(compiler.Evaluate(arguments[0].Object), out var libraryName) + interpreter.Evaluate(arguments[0].Object).Unwrap() is not string libraryName ) { compiler.Log.Error("`zs` importer must have exactly 1 argument of type `string`", this); diff --git a/ZSharp.SourceCompiler.Module/utils/ObjectBuildState.cs b/ZSharp.SourceCompiler.Module/utils/ObjectBuildState.cs new file mode 100644 index 00000000..398affb4 --- /dev/null +++ b/ZSharp.SourceCompiler.Module/utils/ObjectBuildState.cs @@ -0,0 +1,28 @@ +namespace ZSharp.SourceCompiler.Module +{ + internal sealed class ObjectBuildState + where T : struct, Enum, IConvertible + { + public T State { get; private set; } + + public bool Get(T state) => State.HasFlag(state); + + public void Set(T state) + { + State = (T)(ValueType)(State.ToInt32(null) | state.ToInt32(null)); + } + + public static bool operator &(ObjectBuildState instance, T value) + => instance.Get(value); + + public bool this[T flag] + { + get => Get(flag); + set + { + if (value) + Set(flag); + } + } + } +} diff --git a/ZSharp.SourceCompiler.Project/GlobalUsings.cs b/ZSharp.SourceCompiler.Project/GlobalUsings.cs new file mode 100644 index 00000000..3cde0950 --- /dev/null +++ b/ZSharp.SourceCompiler.Project/GlobalUsings.cs @@ -0,0 +1,3 @@ +global using System.Collections.Generic; + +global using ZSharp.Importer.ILLoader; diff --git a/ZSharp.SourceCompiler.Project/ModuleAttributes.cs b/ZSharp.SourceCompiler.Project/ModuleAttributes.cs new file mode 100644 index 00000000..d32f6d8d --- /dev/null +++ b/ZSharp.SourceCompiler.Project/ModuleAttributes.cs @@ -0,0 +1 @@ +[module: MapNamespace(OldName = "ZSharp.SourceCompiler.Project", NewName = "")] diff --git a/ZSharp.SourceCompiler.Project/ZSharp.SourceCompiler.Project.csproj b/ZSharp.SourceCompiler.Project/ZSharp.SourceCompiler.Project.csproj new file mode 100644 index 00000000..7e223a09 --- /dev/null +++ b/ZSharp.SourceCompiler.Project/ZSharp.SourceCompiler.Project.csproj @@ -0,0 +1,19 @@ + + + + net9.0 + disable + enable + + + + + + + + + + + + + diff --git a/ZSharp.SourceCompiler.Project/compiler/ProjectCompiler.T.cs b/ZSharp.SourceCompiler.Project/compiler/ProjectCompiler.T.cs new file mode 100644 index 00000000..970c61f1 --- /dev/null +++ b/ZSharp.SourceCompiler.Project/compiler/ProjectCompiler.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Project +{ + partial class ProjectCompiler + { + + } +} diff --git a/ZSharp.SourceCompiler.Project/compiler/ProjectCompiler.cs b/ZSharp.SourceCompiler.Project/compiler/ProjectCompiler.cs new file mode 100644 index 00000000..c0f5fcfd --- /dev/null +++ b/ZSharp.SourceCompiler.Project/compiler/ProjectCompiler.cs @@ -0,0 +1,19 @@ +using System; + +namespace ZSharp.SourceCompiler.Project +{ + public sealed partial class ProjectCompiler( + Interpreter.Interpreter interpreter, + Project project + ) + { + public Interpreter.Interpreter Interpreter { get; } = interpreter; + + public Project Project { get; } = project; + + public ProjectResult Compile() + { + throw new NotImplementedException(); + } + } +} diff --git a/ZSharp.SourceCompiler.Project/discovery/ProjectDiscovery.cs b/ZSharp.SourceCompiler.Project/discovery/ProjectDiscovery.cs new file mode 100644 index 00000000..c953a160 --- /dev/null +++ b/ZSharp.SourceCompiler.Project/discovery/ProjectDiscovery.cs @@ -0,0 +1,10 @@ +namespace ZSharp.SourceCompiler.Project +{ + public static class ProjectDiscovery + { + public static void Discover(Project project) + { + SubModuleDiscovery.Discover(project.RootModule); + } + } +} diff --git a/ZSharp.SourceCompiler.Project/discovery/SubModuleDiscovery.cs b/ZSharp.SourceCompiler.Project/discovery/SubModuleDiscovery.cs new file mode 100644 index 00000000..c8ca23ea --- /dev/null +++ b/ZSharp.SourceCompiler.Project/discovery/SubModuleDiscovery.cs @@ -0,0 +1,32 @@ +using Standard.FileSystem; + +namespace ZSharp.SourceCompiler.Project +{ + public static class SubModuleDiscovery + { + public const string SubModuleFileName = ".zs"; + + public static void Discover(SubModule subModule) + { + Discover(subModule.Directory, subModule); + } + + private static void Discover(Directory directory, SubModule subModule) + { + foreach (var item in directory) + if (item is Directory subDirectory) + { + var innerModule = subModule; + if (subDirectory / SubModuleFileName is File subModuleFule) + subModule.SubModules.Add(innerModule = new SubModule(subDirectory) + { + SubModuleFile = subModuleFule + }); + Discover(subDirectory, innerModule); + } + else if (item is not File file || file.Equals(subModule.SubModuleFile)) continue; + else if (file.Extension != ".zs") continue; + else subModule.SourceFiles.Add(file); + } + } +} diff --git a/ZSharp.SourceCompiler.Project/project/Project.cs b/ZSharp.SourceCompiler.Project/project/Project.cs new file mode 100644 index 00000000..b5b16c20 --- /dev/null +++ b/ZSharp.SourceCompiler.Project/project/Project.cs @@ -0,0 +1,41 @@ +using Standard.FileSystem; + +namespace ZSharp.SourceCompiler.Project +{ + public sealed class Project( + string name, + Directory rootDirectory, + Directory? sourceDirectory = null, + File? subModuleFile = null + ) + { + public string Name { get; } = name; + + public Directory RootDirectory { get; } = rootDirectory; + + public Directory SourceDirectory => RootModule.Directory; + + public SubModule RootModule { get; } = new(sourceDirectory ?? rootDirectory) + { + SubModuleFile = + subModuleFile + ?? (sourceDirectory ?? rootDirectory) / SubModuleDiscovery.SubModuleFileName as File + ?? throw new System.ArgumentException( + $"Could not find file at {(sourceDirectory ?? rootDirectory) / SubModuleDiscovery.SubModuleFileName}", nameof(subModuleFile) + ) + }; + + public IEnumerable GetAllSubModules() + { + static IEnumerable GetSubModules(SubModule module) + { + yield return module; + foreach (var subModule in module.SubModules) + foreach (var innerSubModule in GetSubModules(subModule)) + yield return innerSubModule; + } + + return GetSubModules(RootModule); + } + } +} diff --git a/ZSharp.SourceCompiler.Project/project/ProjectResult.cs b/ZSharp.SourceCompiler.Project/project/ProjectResult.cs new file mode 100644 index 00000000..5a97b2dc --- /dev/null +++ b/ZSharp.SourceCompiler.Project/project/ProjectResult.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Project +{ + public sealed class ProjectResult + { + + } +} diff --git a/ZSharp.SourceCompiler.Project/project/SubModule.cs b/ZSharp.SourceCompiler.Project/project/SubModule.cs new file mode 100644 index 00000000..9728b5f1 --- /dev/null +++ b/ZSharp.SourceCompiler.Project/project/SubModule.cs @@ -0,0 +1,15 @@ +using Standard.FileSystem; + +namespace ZSharp.SourceCompiler.Project +{ + public class SubModule(Directory directory) + { + public Directory Directory { get; } = directory; + + public List SourceFiles { get; } = []; + + public List SubModules { get; } = []; + + public required File SubModuleFile { get; init; } + } +} diff --git a/ZSharp.SourceCompiler.Script/GlobalUsings.cs b/ZSharp.SourceCompiler.Script/GlobalUsings.cs new file mode 100644 index 00000000..501033a9 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using Result = ZSharp.Compiler.Result; +global using IResult = IResult; diff --git a/ZSharp.SourceCompiler.Script/ZSharp.SourceCompiler.Script.csproj b/ZSharp.SourceCompiler.Script/ZSharp.SourceCompiler.Script.csproj new file mode 100644 index 00000000..eac66889 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/ZSharp.SourceCompiler.Script.csproj @@ -0,0 +1,17 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + diff --git a/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.Context.cs b/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.Context.cs new file mode 100644 index 00000000..50918d7a --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.Context.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + public Context Context { get; init; } = new(); + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.Options.cs b/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.Options.cs new file mode 100644 index 00000000..7d01b1dc --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.Options.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + public ScriptingOptions Options { get; init; } = new ScriptingOptions(); + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.T.cs b/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.T.cs new file mode 100644 index 00000000..9920791e --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.T.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.cs b/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.cs new file mode 100644 index 00000000..92424ac4 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/ScriptCompiler.cs @@ -0,0 +1,35 @@ +namespace ZSharp.SourceCompiler.Script +{ + public sealed partial class ScriptCompiler + { + public Interpreter.Interpreter Interpreter { get; } + + public AST.Document Node { get; } + + public string DocumentPath { get; } + + public ScriptCompiler(Interpreter.Interpreter interpreter, AST.Document document, string path) + { + Interpreter = interpreter; + Node = document; + + CompileExpression = new TopLevelExpressionCompiler(interpreter) + { + CompileExpression = new ExpressionCompiler(interpreter) + { + PostProcess = PostProcess + }.Compile + }.Compile; + + DocumentPath = path; + } + + public void Compile() + { + //using var _ = Interpreter.Compiler.ContextScope(new DocumentContext()); + using var _ = Interpreter.Compiler.ContextScope(new ScopeContext()); + + Node.Statements.ForEach(Compile); + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/ScriptCompiler.Compile.cs b/ZSharp.SourceCompiler.Script/compiler/compile/ScriptCompiler.Compile.cs new file mode 100644 index 00000000..87ea77f6 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/ScriptCompiler.Compile.cs @@ -0,0 +1,25 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + public CompileExpression CompileExpression { get; } + + private void Compile(AST.Statement statement) + { + switch (statement) + { + case AST.BlockStatement block: Compile(block); break; + case AST.DefinitionStatement definition: Compile(definition); break; + case AST.ExpressionStatement expression: Compile(expression); break; + case AST.IfStatement @if: Compile(@if); break; + case AST.ImportStatement import: Compile(import); break; + default: + Interpreter.Log.Error( + $"Unsupported statement type: {statement.GetType().Name}.", + new NodeLogOrigin(statement) + ); + break; + } + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/def/ScriptCompiler.Compile.Module.cs b/ZSharp.SourceCompiler.Script/compiler/compile/def/ScriptCompiler.Compile.Module.cs new file mode 100644 index 00000000..e50b0e8d --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/def/ScriptCompiler.Compile.Module.cs @@ -0,0 +1,34 @@ +using ZSharp.Compiler; + +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private IResult Compile(AST.Module module) + { + var moduleCompiler = new Module.ModuleCompiler(Interpreter, module); + + var scope = Interpreter.Compiler.CurrentContext.FindFirstContext(); + if (scope is null) + return Result.Error("No scope context found."); + if (scope.Add(module.Name, moduleCompiler.GetObject()).Error(out var error)) + return Result.Error($"Could not add module '{module.Name}' to scope: {error}"); + + var result = moduleCompiler.Compile(); + + if (!result.Ok(out var definition)) + return result; + + + if ( + Interpreter.Compiler.IR.CompileDefinition(definition, Interpreter.Runtime) + .When(out var irModule) + .Error(out error) + ) return Result.Error(error); + + Interpreter.Runtime.ImportModule(irModule!); + + return result; + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Call.cs b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Call.cs new file mode 100644 index 00000000..e9018de6 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Call.cs @@ -0,0 +1,47 @@ +using ZSharp.Compiler; + +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private IResult Compile(AST.CallExpression call) + { + var calleeResult = Compile(call.Callee); + + if ( + calleeResult + .When(out var callee) + .Error(out var errorMessage) + ) return Result.Error( + $"Failed to compile callee: {errorMessage}" + ); + + var argumentResults = call.Arguments + .Select>(arg => + { + if ( + Compile(arg.Value) + .When(out var argValue) + .Error(out var error) + ) return Result.Error(error); + + return Result.Ok( + new( + arg.Name, + argValue! + ) + ); + }) + .ToList(); + + if (argumentResults.Any(r => r.IsError)) + return Result.Error( + $"Failed to compile arguments: { + (string.Join(", ", Enumerable.Where(argumentResults, (r => r.IsError)).Select(r => r.UnwrapError()))) + }" + ); + + return Interpreter.Compiler.CG.Call(callee!, [.. argumentResults.Select(r => r.Unwrap())]); + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Expression.cs b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Expression.cs new file mode 100644 index 00000000..da544bdc --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Expression.cs @@ -0,0 +1,29 @@ +using ZSharp.Compiler; + +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private IResult Compile(AST.Expression expression) + => PostProcess( + expression switch + { + AST.CallExpression call => Compile(call), + AST.IdentifierExpression identifier => Compile(identifier), + AST.LiteralExpression literal => Compile(literal), + AST.Module module => Compile(module), + _ => CompileExpression(expression) + } + ); + + private IResult PostProcess(IResult result) + { + if (!result.Ok(out var value)) return result; + + if (Options.EvaluationTarget == EvaluationTarget.Statement) + return result; + + return Interpreter.Evaluate(value).When(Interpreter.RTLoader.Load); + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Identifier.cs b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Identifier.cs new file mode 100644 index 00000000..acf4e1d9 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Identifier.cs @@ -0,0 +1,18 @@ +using ZSharp.Compiler; + +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private IResult Compile(AST.IdentifierExpression identifier) + { + foreach (var scope in Interpreter.Compiler.CurrentContext.FindContext()) + if (scope.Get(identifier.Name).Ok(out var result)) + return Result.Ok(result); + + return Result.Error( + $"Identifier '{identifier.Name}' not found." + ); + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.If.cs b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.If.cs new file mode 100644 index 00000000..9920791e --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.If.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Literal.cs b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Literal.cs new file mode 100644 index 00000000..8c89a4e8 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/expr/ScriptCompiler.Compile.Literal.cs @@ -0,0 +1,13 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private IResult Compile(AST.LiteralExpression literal) + { + if (literal.UnitType is not null) + Interpreter.Log.Warning($"Literal has a unit type '{literal.UnitType}' which will be ignored.", new NodeLogOrigin(literal)); + + return new LiteralCompiler(Interpreter).Compile(literal); + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Block.cs b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Block.cs new file mode 100644 index 00000000..e3adf890 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Block.cs @@ -0,0 +1,13 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private void Compile(AST.BlockStatement block) + { + var _ = Interpreter.Compiler.ContextScope(new ScopeContext()); + + foreach (var statement in block.Statements) + Compile(statement); + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Definition.cs b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Definition.cs new file mode 100644 index 00000000..a3a5b80d --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Definition.cs @@ -0,0 +1,16 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private void Compile(AST.DefinitionStatement definitionStatement) + { + var result = Compile(definitionStatement.Definition); + + if (result.Error(out var error)) + Interpreter.Log.Error( + $"Failed to compile definition: {error}", + new NodeLogOrigin(definitionStatement) + ); + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Expression.cs b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Expression.cs new file mode 100644 index 00000000..2f8670bf --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Expression.cs @@ -0,0 +1,27 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private void Compile(AST.ExpressionStatement expressionStatement) + { + var valueObjectResult = Compile(expressionStatement.Expression); + + if ( + valueObjectResult + .When(out var valueObject) + .Error(out var errorMessage) + ) + { + Interpreter.Log.Error( + $"Failed to compile expression: {errorMessage}", + new NodeLogOrigin(expressionStatement) + ); + + return; + } + + Interpreter.Compiler.Evaluator.Evaluate(valueObject!); + // See comment in ZSharp.SourceCompiler.Module/module compiler/compile/stmt/ModuleCompiler.Compile.Expression.cs + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.If.cs b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.If.cs new file mode 100644 index 00000000..5e4730f2 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.If.cs @@ -0,0 +1,52 @@ +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private void Compile(AST.IfStatement @if) + { + var conditionResult = Compile(@if.Condition); + + if ( + conditionResult + .When(out var condition) + .Error(out var error) + ) + { + Interpreter.Log.Error( + $"Failed to compile if condition: {error}", + new NodeLogOrigin(@if.Condition) + ); + return; + } + + // TODO: cast to boolean + + var conditionValueResult = Interpreter.Evaluate(condition!); + + if ( + conditionValueResult + .When(out var conditionValue) + .Error(out error) + ) + { + Interpreter.Log.Error( + $"Failed to evaluate if condition: {error}", + new NodeLogOrigin(@if.Condition) + ); + return; + } + + if (conditionValue is not bool conditionBool) + { + Interpreter.Log.Error( + $"If condition does not evaluate to a boolean value.", + new NodeLogOrigin(@if.Condition) + ); + return; + } + + if (conditionBool) Compile(@if.If); + else if (@if.Else is not null) Compile(@if.Else); + } + } +} diff --git a/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Import.cs b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Import.cs new file mode 100644 index 00000000..10090bb6 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/compiler/compile/stmt/ScriptCompiler.Compile.Import.cs @@ -0,0 +1,122 @@ +using CommonZ; +using ZSharp.AST; +using ZSharp.Compiler; + +namespace ZSharp.SourceCompiler.Script +{ + partial class ScriptCompiler + { + private void Compile(ImportStatement import) + { + IEnumerable arguments = [ + new CallArgument() { + Value = import.Source + }, + .. import.Arguments ?? [] + ]; + + var argumentsResults = arguments + .Select>((arg, i) => + { + if ( + Compile(arg.Value) + .When(out var value) + .Error(out var error) + ) + { + Interpreter.Log.Error( + $"Failed to compile import argument '{arg.Name ?? i.ToString()}': {error}", + new NodeLogOrigin(arg.Value) + ); + return Result.Error(error); + } + + return Result.Ok( + new(arg.Name, value!) + ); + }) + .ToArray(); + + if (argumentsResults.Any(r => r.IsError)) + return; + + var importResult = Interpreter.Compiler.CG.Call( + Context.ImportSystem.ImportFunction, + [.. argumentsResults.Select(r => r.Unwrap())] + ); + + if (importResult.When(out var result).Error(out var error)) + { + Interpreter.Log.Error( + $"Failed to compile import: {error}", + new NodeLogOrigin(import) + ); + return; + } + + if ( + Interpreter.Compiler.Evaluator.Evaluate(result!) + .When(out result) + .Error(out error) + ) + { + Interpreter.Log.Error( + $"Failed to evaluate import: {error}", + new NodeLogOrigin(import) + ); + return; + } + + if (import.Alias is not null) + { + if (Interpreter + .Compiler + .CurrentContext + .PerformOperation( + scope => !scope.Add(import.Alias, result!).Error(out error) + ) + ) + { + Interpreter.Log.Error( + $"No scope context found to import into.", + new NodeLogOrigin(import) + ); + return; + } + } + + if (import.ImportedNames is not null) + { + var scope = Interpreter.Compiler.CurrentContext.FindFirstContext(); + if (scope is null) + { + Interpreter.Log.Error( + $"No scope context found to import into.", + new NodeLogOrigin(import) + ); + return; + } + + var memberResults = import.ImportedNames + .Select(name => (name, Interpreter.Compiler.CG.Member(result, name.Name))) + .Select(vs => + { + var (name, r) = vs; + + return (name, result: r.Else(e => Interpreter.Log.Error( + $"Failed to import member '{name.Name}': {e}", + new NodeLogOrigin(name) + ))); + }) + .ToArray(); + + foreach (var (name, memberResult) in memberResults) + if (memberResult.Ok(out var member)) + scope.Set( + name.Alias ?? name.Name, + member + ); + } + } + } +} diff --git a/ZSharp.SourceCompiler.Script/contexts/ScopeContext.cs b/ZSharp.SourceCompiler.Script/contexts/ScopeContext.cs new file mode 100644 index 00000000..96a4fefa --- /dev/null +++ b/ZSharp.SourceCompiler.Script/contexts/ScopeContext.cs @@ -0,0 +1,34 @@ +using CommonZ.Utils; +using ZSharp.Compiler; + +namespace ZSharp.SourceCompiler.Script +{ + public sealed class ScopeContext() + : IContext + , IScopeContext + { + private readonly Mapping scope = []; + + public IContext? Parent { get; set; } + + public IResult Add(string name, CompilerObject value) + { + if (scope.ContainsKey(name)) + return Result.Error($"Name '{name}' is already defined in this scope."); + + return Set(name, value); + } + + public IResult Get(string name) + => scope.TryGetValue(name, out var value) + ? Result.Ok(value) + : Result.Error($"Name '{name}' is not defined in this scope."); + + public IResult Set(string name, CompilerObject value) + { + scope[name] = value; + + return Result.Ok(value); + } + } +} diff --git a/ZSharp.SourceCompiler.Script/options/EvaluationTarget.cs b/ZSharp.SourceCompiler.Script/options/EvaluationTarget.cs new file mode 100644 index 00000000..955ceceb --- /dev/null +++ b/ZSharp.SourceCompiler.Script/options/EvaluationTarget.cs @@ -0,0 +1,15 @@ +namespace ZSharp.SourceCompiler.Script +{ + public enum EvaluationTarget + { + /// + /// The compiler will evaluate each expression as it's compiled. + /// + Expression, + + /// + /// The compiler will only evaluate the final statement in a script. + /// + Statement, + } +} diff --git a/ZSharp.SourceCompiler.Script/options/ScriptingOptions.cs b/ZSharp.SourceCompiler.Script/options/ScriptingOptions.cs new file mode 100644 index 00000000..acb513e8 --- /dev/null +++ b/ZSharp.SourceCompiler.Script/options/ScriptingOptions.cs @@ -0,0 +1,7 @@ +namespace ZSharp.SourceCompiler.Script +{ + public class ScriptingOptions + { + public EvaluationTarget EvaluationTarget { get; init; } = EvaluationTarget.Statement; + } +} diff --git a/ZSharp.Text/ZSharp.Text.csproj b/ZSharp.Text/ZSharp.Text.csproj index 30402ac0..0d2df0d1 100644 --- a/ZSharp.Text/ZSharp.Text.csproj +++ b/ZSharp.Text/ZSharp.Text.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable diff --git a/ZSharp.Text/Token.cs b/ZSharp.Tokenizer/Token.cs similarity index 100% rename from ZSharp.Text/Token.cs rename to ZSharp.Tokenizer/Token.cs diff --git a/ZSharp.Text/TokenType.cs b/ZSharp.Tokenizer/TokenType.cs similarity index 100% rename from ZSharp.Text/TokenType.cs rename to ZSharp.Tokenizer/TokenType.cs diff --git a/ZSharp.Tokenizer/Tokenizer.cs b/ZSharp.Tokenizer/Tokenizer.cs index 6f77cb3b..ab07596b 100644 --- a/ZSharp.Tokenizer/Tokenizer.cs +++ b/ZSharp.Tokenizer/Tokenizer.cs @@ -20,6 +20,7 @@ public static class Tokenizer private const char LF = '\n'; private const char CR = '\r'; + private const char Tab = '\t'; private const string Operators = "./|+-=<>!@#$%^&*~?"; @@ -58,6 +59,7 @@ Token ReadString() { 'n' => LF, 'r' => CR, + 't' => Tab, StringQuotation => StringQuotation, CharQuotation => CharQuotation, BackSlash => stream.Read(), @@ -84,6 +86,7 @@ Token ReadChar() { 'n' => LF, 'r' => CR, + 't' => Tab, StringQuotation => StringQuotation, CharQuotation => CharQuotation, BackSlash => stream.Read(), @@ -197,7 +200,7 @@ Token EOF() LF => SingleChar(TokenType.NewLine), CR => SingleChar(TokenType.NewLine), ' ' => SingleChar(TokenType.Space), - '\t' => SingleChar(TokenType.Tab), + Tab => SingleChar(TokenType.Tab), '{' => SingleChar(TokenType.LCurly), '}' => SingleChar(TokenType.RCurly), '(' => SingleChar(TokenType.LParen), diff --git a/ZSharp.Tokenizer/ZSharp.Tokenizer.csproj b/ZSharp.Tokenizer/ZSharp.Tokenizer.csproj index e3635754..1c21fabe 100644 --- a/ZSharp.Tokenizer/ZSharp.Tokenizer.csproj +++ b/ZSharp.Tokenizer/ZSharp.Tokenizer.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable diff --git a/ZSharp.ZSSourceCompiler/GlobalUsings.cs b/ZSharp.ZSSourceCompiler/GlobalUsings.cs deleted file mode 100644 index 9a59d6a7..00000000 --- a/ZSharp.ZSSourceCompiler/GlobalUsings.cs +++ /dev/null @@ -1,2 +0,0 @@ -global using CompilerObject = ZSharp.Objects.CompilerObject; -global using ZSharp.AST; diff --git a/ZSharp.ZSSourceCompiler/NodeLogOrigin.cs b/ZSharp.ZSSourceCompiler/NodeLogOrigin.cs deleted file mode 100644 index 66f58290..00000000 --- a/ZSharp.ZSSourceCompiler/NodeLogOrigin.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public sealed class NodeLogOrigin(Node origin) : Compiler.LogOrigin - { - public Node Origin { get; } = origin; - - public override string? ToString() - { - return Origin.TokenInfo?.ToString(); - } - } -} diff --git a/ZSharp.ZSSourceCompiler/NodeObject.cs b/ZSharp.ZSSourceCompiler/NodeObject.cs deleted file mode 100644 index 210b98ce..00000000 --- a/ZSharp.ZSSourceCompiler/NodeObject.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public sealed class NodeObject(Node node) : CompilerObject - { - public Node Node { get; } = node; - } -} diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/document/compiler/DocumentCompiler.cs b/ZSharp.ZSSourceCompiler/builtin-compilers/document/compiler/DocumentCompiler.cs deleted file mode 100644 index 90b9210b..00000000 --- a/ZSharp.ZSSourceCompiler/builtin-compilers/document/compiler/DocumentCompiler.cs +++ /dev/null @@ -1,38 +0,0 @@ - -namespace ZSharp.ZSSourceCompiler -{ - public sealed partial class DocumentCompiler(ZSSourceCompiler compiler, AST.Document node, Document document) - : ContextCompiler(compiler, node, document) - , IOverrideCompileExpression - { - public override Document Compile() - { - using (Context.Compiler(this)) - using (Context.Scope(Object)) - CompileDocument(); - - return base.Compile(); - } - - private void CompileDocument() - { - foreach (var item in Node.Statements) - Compiler.CompileNode(item); - } - - private void Compile(Statement statement) - { - if (statement is ExpressionStatement expressionStatement) - Compiler.Compiler.Evaluate(Compiler.CompileNode(expressionStatement.Expression)); - - // if the statement is a definition, compile it - } - - public CompilerObject? CompileNode(ZSSourceCompiler compiler, Expression node) - => node switch - { - Module module => Compile(module), - _ => null - }; - } -} diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/document/objects/DocumentValue.cs b/ZSharp.ZSSourceCompiler/builtin-compilers/document/objects/DocumentValue.cs deleted file mode 100644 index 56c147b6..00000000 --- a/ZSharp.ZSSourceCompiler/builtin-compilers/document/objects/DocumentValue.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public sealed class DocumentValue(string name, CompilerObject value) - : CompilerObject - , Compiler.ICTAssignable - , Compiler.IEvaluable - { - public string Name { get; } = name; - - public CompilerObject Value { get; set; } = value; - - public bool IsReadOnly { get; set; } - - CompilerObject Compiler.ICTAssignable.Assign(Compiler.Compiler compiler, CompilerObject value) - => IsReadOnly ? throw new InvalidOperationException() : Value = compiler.Evaluate(value); - - public CompilerObject Evaluate(Compiler.Compiler compiler) - => Value; - - } -} diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/module/ClassCompiler.cs b/ZSharp.ZSSourceCompiler/builtin-compilers/module/ClassCompiler.cs deleted file mode 100644 index f140b1f2..00000000 --- a/ZSharp.ZSSourceCompiler/builtin-compilers/module/ClassCompiler.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public sealed class ClassCompiler(ZSSourceCompiler compiler, OOPDefinition oop, CompilerObject @object) - : ContextCompiler(compiler, oop, @object) - { - public override CompilerObject Compile() - { - var metaClass = Node.Of is null ? null : Compiler.CompileNode(Node.Of); - - var cls = (Objects.Class)Object; - - if (Node.Bases is not null && Node.Bases.Count > 0) - cls.Base = (Objects.Class)Compiler.Compiler.Evaluate(Compiler.CompileNode(Node.Bases[0])); - - return base.Compile(); - } - } -} diff --git a/ZSharp.ZSSourceCompiler/builtin-compilers/runtime code/WhileLoopCompiler.cs b/ZSharp.ZSSourceCompiler/builtin-compilers/runtime code/WhileLoopCompiler.cs deleted file mode 100644 index 17c9d3a2..00000000 --- a/ZSharp.ZSSourceCompiler/builtin-compilers/runtime code/WhileLoopCompiler.cs +++ /dev/null @@ -1,39 +0,0 @@ - -namespace ZSharp.ZSSourceCompiler -{ - public sealed class WhileLoopCompiler(ZSSourceCompiler compiler, WhileExpression node) - : ContextCompiler(compiler, node, new()) - , IOverrideCompileStatement - { - public override WhileLoop Compile() - { - Object.Condition = Compiler.CompileNode(Node.Condition); - - using (Context.Compiler(this)) - using (Context.Scope()) - Object.While = Compiler.CompileNode(Node.Body); - - if (Node.Else is not null) - using (Context.Scope()) - Object.Else = Compiler.CompileNode(Node.Else); - - return base.Compile(); - } - - public CompilerObject? CompileNode(ZSSourceCompiler compiler, Statement node) - { - if (node is BreakStatement @break) - return new Objects.RawCode( - new([ - .. @break.Value is null ? [] : compiler.Compiler.CompileIRCode( - compiler.CompileNode(@break.Value) - ).Instructions, - - new IR.VM.Jump(Object.EndLabel) - ]) - ); - - return null; - } - } -} diff --git a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Logging.cs b/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Logging.cs deleted file mode 100644 index 542e0832..00000000 --- a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Logging.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public sealed partial class ZSSourceCompiler : Compiler.Feature - { - public void LogError(string message, Node origin) - { - Compiler.Log.Error(message, new NodeLogOrigin(origin)); - } - } -} diff --git a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Operators.cs b/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Operators.cs deleted file mode 100644 index 7b2b405c..00000000 --- a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.Operators.cs +++ /dev/null @@ -1,9 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.ZSSourceCompiler -{ - public partial class ZSSourceCompiler - { - public Cache Operators { get; } = []; - } -} diff --git a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.cs b/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.cs deleted file mode 100644 index c406e284..00000000 --- a/ZSharp.ZSSourceCompiler/compiler/ZSSourceCompiler.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public sealed partial class ZSSourceCompiler : Compiler.Feature - { - public ExpressionCompiler ExpressionCompiler { get; } - - public StatementCompiler StatementCompiler { get; } - - public Context Context { get; } - - public ZSSourceCompiler(Compiler.Compiler compiler) - : base(compiler) - { - Context = new(this); - - ExpressionCompiler = new(this); - StatementCompiler = new(this); - - Initialize(); - } - - public CompilerObject CompileNode(Expression expression) - => CompileNode(expression); - - public CompilerObject CompileNode(Statement statement) - => CompileNode(statement); - - private CompilerObject CompileNode(T node) - where T : Node - { - foreach (var compiler in Context.Compilers>()) - if (compiler.CompileNode(this, node) is CompilerObject result) - return result; - - throw new($"Could not find suitable compiler for node of type {node.GetType().Name}"); // TODO: proper exception: could not find suitable compiler for T - } - - public CompilerObject CompileType(Expression expression) - => Compiler.TypeSystem.EvaluateType(CompileNode(expression)); - } -} diff --git a/ZSharp.ZSSourceCompiler/context/Context.Compilers.cs b/ZSharp.ZSSourceCompiler/context/Context.Compilers.cs deleted file mode 100644 index b94cfcc4..00000000 --- a/ZSharp.ZSSourceCompiler/context/Context.Compilers.cs +++ /dev/null @@ -1,52 +0,0 @@ -using CommonZ.Utils; -using System.Diagnostics.CodeAnalysis; - -namespace ZSharp.ZSSourceCompiler -{ - public sealed partial class Context - { - private readonly Stack compilerStack = []; - - public CompilerBase CurrentCompiler => compilerStack.Peek(); - - public CompilerBase? ParentCompiler(int level = 0) - => compilerStack.ElementAtOrDefault(level + 1); - - public T? ParentCompiler(int level = 0) - where T : class - => ParentCompiler(level) as T; - - public bool ParentCompiler([NotNullWhen(true)] out T? parent, int level = 0) - where T : class - => (parent = ParentCompiler(level)) is not null; - - public T? Compiler() - where T : class - { - foreach (var compiler in compilerStack) - if (compiler is T t) - return t; - - return null; - } - - public bool Compiler([NotNullWhen(true)] out T? compiler) - where T : class - => (compiler = Compiler()) is not null; - - public IEnumerable Compilers() - where T : class - { - foreach (var compiler in compilerStack) - if (compiler is T t) - yield return t; - } - - public ContextManager Compiler(CompilerBase compiler) - { - compilerStack.Push(compiler); - - return new(() => compilerStack.Pop()); - } - } -} diff --git a/ZSharp.ZSSourceCompiler/context/Context.Scopes.cs b/ZSharp.ZSSourceCompiler/context/Context.Scopes.cs deleted file mode 100644 index c8a1e8a0..00000000 --- a/ZSharp.ZSSourceCompiler/context/Context.Scopes.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CommonZ.Utils; - -namespace ZSharp.ZSSourceCompiler -{ - public sealed partial class Context - { - private readonly Mapping objectContainerScopes = []; - private readonly Mapping objectContainedScopes = []; - - public Scope GlobalScope { get; } - - public Scope CurrentScope { get; private set; } - - public Scope CreateScope(ScopeParent parent = ScopeParent.Default) - => new(parent switch - { - ScopeParent.None => null, - ScopeParent.Global => GlobalScope, - ScopeParent.Current => CurrentScope, - _ => throw new ArgumentOutOfRangeException(nameof(parent), parent, $"Unknown {nameof(ScopeParent)} value") - }); - - public ContextManager Scope(ScopeParent parent = ScopeParent.Default) - => Scope(CreateScope(parent)); - - public ContextManager Scope(Scope scope) - { - (CurrentScope, scope) = (scope, CurrentScope); - - return new(() => CurrentScope = scope); - } - - public ContextManager Scope(CompilerObject @object, ScopeParent parent = ScopeParent.Default) - => Scope(ContainedScope(@object) ?? ContainedScope(@object, CreateScope(parent))); // TODO: proper exception: could not find scope for object - - public Scope? ContainerScope(CompilerObject @object) - => objectContainerScopes.GetValueOrDefault(@object); - - public Scope? ContainedScope(CompilerObject @object) - => objectContainedScopes.GetValueOrDefault(@object); - - public Scope ContainedScope(CompilerObject @object, Scope scope) - => objectContainedScopes[@object] = scope; - } -} diff --git a/ZSharp.ZSSourceCompiler/context/Context.cs b/ZSharp.ZSSourceCompiler/context/Context.cs deleted file mode 100644 index 31391b1d..00000000 --- a/ZSharp.ZSSourceCompiler/context/Context.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public sealed partial class Context - { - public ZSSourceCompiler SourceCompiler { get; } - - public Context(ZSSourceCompiler compiler, Scope? globalScope = null) - { - SourceCompiler = compiler; - - GlobalScope = globalScope ?? new(null); - CurrentScope = GlobalScope; - - compilerStack.Push(new DefaultContextCompiler(compiler)); - } - } -} diff --git a/ZSharp.ZSSourceCompiler/context/scoping/Scope.cs b/ZSharp.ZSSourceCompiler/context/scoping/Scope.cs deleted file mode 100644 index 01279437..00000000 --- a/ZSharp.ZSSourceCompiler/context/scoping/Scope.cs +++ /dev/null @@ -1,77 +0,0 @@ -using CommonZ.Utils; -using System.Diagnostics.CodeAnalysis; - -namespace ZSharp.ZSSourceCompiler -{ - public sealed class Scope(Scope? parent) - { - private readonly Mapping scope = []; - private readonly Mapping> constraints = []; - - public Scope? Parent { get; } = parent; - - public CompilerObject? Get(string name, bool lookupParent = true) - { - if (scope.TryGetValue(name, out var result)) - return result; - - if (lookupParent && Parent is not null) - return Parent.Get(name); - - return null; - } - - public bool Get(string name, [NotNullWhen(true)] out CompilerObject? result, bool lookupParent = true) - => (result = Get(name, lookupParent: lookupParent)) is not null; - - public void Set(string name, CompilerObject value, bool @override = false) - { - if (scope.ContainsKey(name) && !@override) - throw new(); // TODO: Throw a proper exception of NameAlreadyExists - - scope[name] = value; - } - - public IEnumerable Constraints(string name, bool lookupParent = true) - => Get(name, lookupParent: lookupParent) is CompilerObject @object ? Constraints(@object, lookupParent: lookupParent) : []; - - public IEnumerable Constraints(CompilerObject @object, bool lookupParent = true) - { - if (constraints.TryGetValue(@object, out var result)) - return result; - - if (lookupParent && Parent is not null) - return Parent.Constraints(@object); - - return []; - } - - public void Constriant(string name, Constraint constraint, bool lookupParent = true) - { - if (Get(name, lookupParent: lookupParent) is CompilerObject @object) - Constriant(@object, constraint); - else throw new(); // TODO: Throw a proper exception of UnresolvedName - } - - public void Constriant(CompilerObject @object, Constraint constraint) - { - if (constraints.TryGetValue(@object, out var result)) - result.Add(constraint); - else constraints[@object] = [constraint]; - } - - public void Constraints(string name, Constraint[] constraints, bool lookupParent = true) - { - if (Get(name, lookupParent: lookupParent) is CompilerObject @object) - Constraints(@object, constraints); - else throw new(); // TODO: Throw a proper exception of UnresolvedName - } - - public void Constraints(CompilerObject @object, Constraint[] constraints) - { - if (this.constraints.TryGetValue(@object, out var result)) - result.AddRange(constraints); - else this.constraints[@object] = constraints.ToList(); - } - } -} diff --git a/ZSharp.ZSSourceCompiler/context/scoping/ScopeParent.cs b/ZSharp.ZSSourceCompiler/context/scoping/ScopeParent.cs deleted file mode 100644 index c8551286..00000000 --- a/ZSharp.ZSSourceCompiler/context/scoping/ScopeParent.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public enum ScopeParent - { - None, - Current, - Global, - - Default = Current - } -} diff --git a/ZSharp.ZSSourceCompiler/core-compilers/DefaultContextCompiler.cs b/ZSharp.ZSSourceCompiler/core-compilers/DefaultContextCompiler.cs deleted file mode 100644 index 3ec07544..00000000 --- a/ZSharp.ZSSourceCompiler/core-compilers/DefaultContextCompiler.cs +++ /dev/null @@ -1,22 +0,0 @@ - -namespace ZSharp.ZSSourceCompiler -{ - public sealed class DefaultContextCompiler(ZSSourceCompiler compiler) - : ContextCompiler(compiler) - , IOverrideCompileExpression - , IOverrideCompileStatement - { - public override Node ContextNode => throw new InvalidOperationException(); - - public override CompilerObject ContextObject => throw new InvalidOperationException(); - - public CompilerObject? CompileNode(ZSSourceCompiler compiler, Expression node) - => compiler.ExpressionCompiler.CompileNode(node); - - public CompilerObject? CompileNode(ZSSourceCompiler compiler, Statement node) - => compiler.StatementCompiler.CompileNode(node); - - public override CompilerObject CompileNode() - => throw new InvalidOperationException(); - } -} diff --git a/ZSharp.ZSSourceCompiler/core-compilers/expression/ExpressionCompiler.Literals.cs b/ZSharp.ZSSourceCompiler/core-compilers/expression/ExpressionCompiler.Literals.cs deleted file mode 100644 index e9ea777c..00000000 --- a/ZSharp.ZSSourceCompiler/core-compilers/expression/ExpressionCompiler.Literals.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public sealed partial class ExpressionCompiler - { - public CompilerObject CompileNode(LiteralExpression literal) - => literal.Type switch - { - LiteralType.String => Compiler.Compiler.CreateString(literal.Value), - LiteralType.False => Compiler.Compiler.CreateFalse(), - LiteralType.True => Compiler.Compiler.CreateTrue(), - LiteralType.Null => Compiler.Compiler.CreateNull(), - LiteralType.Number => Compiler.Compiler.CreateInteger(int.Parse(literal.Value)), - _ => throw new($"Could not find suitable compiler for node of type {typeof(LiteralExpression).Name}"), // TODO: proper exception: unknown literal type - }; - } -} diff --git a/ZSharp.ZSSourceCompiler/core-compilers/expression/ExpressionCompiler.cs b/ZSharp.ZSSourceCompiler/core-compilers/expression/ExpressionCompiler.cs deleted file mode 100644 index 67de29dd..00000000 --- a/ZSharp.ZSSourceCompiler/core-compilers/expression/ExpressionCompiler.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Numerics; -using System.Security.AccessControl; - -namespace ZSharp.ZSSourceCompiler -{ - public sealed partial class ExpressionCompiler(ZSSourceCompiler compiler) - : CompilerBase(compiler) - { - public CompilerObject? CompileNode(Expression expression) - => expression switch - { - BinaryExpression binary => Compile(binary), - CallExpression call => Compile(call), - IdentifierExpression identifier => Context.CurrentScope.Get(identifier.Name), - LiteralExpression literal => CompileNode(literal), - _ => null - }; - - private CompilerObject Compile(BinaryExpression binary) - { - // TODO: NO SPECIAL TREATMENT FOR OPERATORS . and = - - var left = Compiler.CompileNode(binary.Left); - - if (binary.Operator == ".") - { - CompilerObject member; - - if (binary.Right is IdentifierExpression identifier) - member = Compiler.Compiler.CreateString(identifier.Name); - - else if (binary.Right is not LiteralExpression literal) - throw new("Expected a literal expression on the right side of the dot operator."); - - else member = CompileNode(literal); - - if (Compiler.Compiler.IsString(member, out var memberName)) - return Compiler.Compiler.Member(left, memberName); - if (Compiler.Compiler.IsLiteral(member, out var memberIndex)) - return Compiler.Compiler.Member(left, memberIndex.Value); - - Compiler.LogError("Expected a string or an integer literal on the right side of the dot operator.", binary.Right); - } - - var right = Compiler.CompileNode(binary.Right); - - if (binary.Operator == "=") - return Compiler.Compiler.Assign(left, right); - - if (!Compiler.Operators.Cache(binary.Operator, out var @operator)) - Compiler.LogError($"Operator '{binary.Operator}' is not defined.", binary); - - return Compiler.Compiler.Call(@operator, [new(left), new(right)]); - } - - private CompilerObject Compile(CallExpression call) - { - var callable = Compiler.CompileNode(call.Callee); - - var args = call.Arguments.Select(arg => new Compiler.Argument(arg.Name, Compiler.CompileNode(arg.Value))); - - return Compiler.Compiler.Call(callable, args.ToArray()); - } - } -} diff --git a/ZSharp.ZSSourceCompiler/core-compilers/statement/StatementCompiler.cs b/ZSharp.ZSSourceCompiler/core-compilers/statement/StatementCompiler.cs deleted file mode 100644 index 1670bf02..00000000 --- a/ZSharp.ZSSourceCompiler/core-compilers/statement/StatementCompiler.cs +++ /dev/null @@ -1,75 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - public sealed class StatementCompiler(ZSSourceCompiler compiler) - : CompilerBase(compiler) - { - public CompilerObject? CompileNode(Statement statement) - => statement switch - { - BlockStatement block => Compile(block), - ExpressionStatement expressionStatement => Compile(expressionStatement), - ImportStatement import => Compile(import), - _ => null - }; - - private CompilerObject Compile(BlockStatement block) - { - var result = new Compiler.IRCode(); - - foreach (var statement in block.Statements) - result.Append(Compiler.Compiler.CompileIRCode(Compiler.CompileNode(statement))); - - result.RequireVoidType(); - - return new Objects.RawCode(result); - } - - private CompilerObject Compile(ExpressionStatement expressionStatement) - { - if (expressionStatement.Expression is null) - return new Objects.RawCode(new()); - - var result = Compiler.Compiler.CompileIRCode(Compiler.CompileNode(expressionStatement.Expression)); - - if (result.IsValue) - { - result.Instructions.Add(new IR.VM.Pop()); - result.Types.RemoveAt(result.Types.Count - 1); - } - - result.RequireVoidType(); - - return new Objects.RawCode(result); - } - - private CompilerObject Compile(ImportStatement import) - { - if (import.Arguments is not null) - Compiler.LogError($"Import arguments are not supported yet.", import); - - var source = Compiler.CompileNode(import.Source); - - var result = Compiler.Compiler.Call( - Compiler.ImportSystem.ImportFunction, - [ - new(source), - .. (import.Arguments ?? []).Select( - arg => new Compiler.Argument(arg.Name, Compiler.CompileNode(arg.Value)) - ) - ] - ); - - if (import.ImportedNames is not null) - foreach (var importedName in import.ImportedNames) - Context.CurrentScope.Set( - importedName.Alias ?? importedName.Name, - Compiler.Compiler.Member(result, importedName.Name) - ); - - if (import.Alias is not null) - Context.CurrentScope.Set(import.Alias, result); - - return result; - } - } -} diff --git a/ZSharp.ZSSourceCompiler/objects/LateCompileIRCode.cs b/ZSharp.ZSSourceCompiler/objects/LateCompileIRCode.cs deleted file mode 100644 index 42f508b3..00000000 --- a/ZSharp.ZSSourceCompiler/objects/LateCompileIRCode.cs +++ /dev/null @@ -1,12 +0,0 @@ -using ZSharp.Compiler; - -namespace ZSharp.ZSSourceCompiler -{ - internal sealed class LateCompileIRCode(Func callback) - : CompilerObject - , ICompileIRCode - { - public IRCode CompileIRCode(Compiler.Compiler compiler) - => callback(compiler); - } -} diff --git a/ZSharp.ZSSourceCompiler/objects/ObjectWrapper.cs b/ZSharp.ZSSourceCompiler/objects/ObjectWrapper.cs deleted file mode 100644 index 085155ce..00000000 --- a/ZSharp.ZSSourceCompiler/objects/ObjectWrapper.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ZSharp.ZSSourceCompiler -{ - internal class ObjectWrapper : CompilerObject - { - public CompilerObject? Object { get; set; } - } -} diff --git a/ZSharpParserTest/Program.cs b/ZSharpParserTest/Program.cs deleted file mode 100644 index dbf3743a..00000000 --- a/ZSharpParserTest/Program.cs +++ /dev/null @@ -1,40 +0,0 @@ -using ZSharp.AST; -using ZSharp.Parser; -using ZSharp.Text; -using ZSharp.Tokenizer; - - -using (StreamReader stream = File.OpenText("./parserText.txt")) -{ - var zsharpParser = new ZSharpParser(); - var parser = new Parser(Tokenizer.Tokenize(new(stream))); - - var expressionParser = zsharpParser.Expression; - - expressionParser.Terminal(TokenType.String, token => new LiteralExpression(token.Value, LiteralType.String)); - //expressionParser.Terminal(TokenType.Identifier, token => new IdentifierExpression(token.Value)); - - expressionParser.InfixL("+", 50); - expressionParser.InfixL("*", 70); - expressionParser.InfixL("**", 80); - - expressionParser.Led(TokenType.LParen, LangParser.ParseCallExpression, 100); - - expressionParser.Separator(TokenType.Comma); - expressionParser.Separator(TokenType.RParen); - expressionParser.Separator(TokenType.Semicolon); - - zsharpParser.RegisterParsers(parser); - var documentNode = zsharpParser.Parse(parser); - - Console.WriteLine($"Finished parsing document with {documentNode.Statements.Count} statements!"); - - Console.WriteLine(); - - foreach (var statement in documentNode.Statements) - { - Console.WriteLine(); - Console.WriteLine(statement.GetType().Name); - Console.WriteLine(statement); - } -} diff --git a/ZSharpParserTest/ZSharpParserTest.csproj b/ZSharpParserTest/ZSharpParserTest.csproj deleted file mode 100644 index 07e72643..00000000 --- a/ZSharpParserTest/ZSharpParserTest.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - - PreserveNewest - - - - diff --git a/ZSharpParserTest/parserText.txt b/ZSharpParserTest/parserText.txt deleted file mode 100644 index d662554d..00000000 --- a/ZSharpParserTest/parserText.txt +++ /dev/null @@ -1,89 +0,0 @@ -module Foo; - -import { a as A, b as B } from "std:test"; - -import("A", b: "B") "std:test"; - -import "std:test" as test; - -import {} from "std:test"; - -import {a as A} from "std:test"; - -import {a, b} from "std:test"; - -let myVar = "foo" + "bar" ** "goo" * "baz"; - -let yourVar = "it's actually mine"; - -let otherVar = "other"; - -"expressionStatement!"; - -"CALLABLE"(); - -"CALLABLE"("ARG1"); -"CALLABLE"("ARG1", "ARG2"); - - -"CALLABLE"("ARG1", "ARG2", arg3: "ARG3"); -"CALLABLE"("ARG1", "ARG2", arg3: "ARG3", arg4: "ARG4"); - -"CALLABLE"(arg1: "ARG1", "ARG2"); - - -fun() {} - -fun foo() {} - -fun foo(x) {} - -fun foo(x, y) {} - -fun foo(x, y, z) {} - -fun foo(x, y, ...z) {} - -fun foo(x, y, ...z,) {} - -fun foo(x, y,) {} - -fun foo({}) {} - -fun foo({x}) {} - -fun foo({x, y}) {} - -fun foo({x, y, z}) {} - -fun foo({x, y, ...z}) {} - -fun foo(x, y, {}) {} - -fun foo(x, y, {z}) {} - -fun foo(x, y, {z, w}) {} - -fun foo(x, y, {z, w, v}) {} - -fun foo(x, y, {z, w, ...v}) {} - -fun foo(x, y, ...z, {w, v, ...u}) {} - -class {} - -class Foo {} - -class; - -class Foo; - -class Foo : "Base"; - -class Foo : "Base"; - -class Foo : "Base", "Mixin"; - -class Foo : "Base", "Mixin" { - let x = "x"; -} diff --git a/ZSharpTest/Main.cs b/ZSharpTest/Main.cs deleted file mode 100644 index 13b28b2a..00000000 --- a/ZSharpTest/Main.cs +++ /dev/null @@ -1,206 +0,0 @@ -using ZSharp.Compiler; -using ZSharp.Interpreter; -using ZSharp.Parser; -using ZSharp.Text; -using ZSharp.Tokenizer; - -string fileName = args.Length == 0 ? "test.zs" : args[0]; -string filePath = Path.GetFullPath(fileName); - -#region Parsing - -ZSharp.AST.Document documentNode; -using (StreamReader stream = File.OpenText(filePath)) -{ - var zsharpParser = new ZSharpParser(); - var parser = new Parser(Tokenizer.Tokenize(new(stream))); - - var expressionParser = zsharpParser.Expression; - var statementParser = zsharpParser.Statement; - - expressionParser.Terminal( - TokenType.String, - token => new ZSharp.AST.LiteralExpression(token.Value, ZSharp.AST.LiteralType.String) - ); - expressionParser.Terminal( - TokenType.Number, - token => new ZSharp.AST.LiteralExpression(token.Value, ZSharp.AST.LiteralType.Number) - ); - expressionParser.Terminal( - TokenType.Decimal, - token => new ZSharp.AST.LiteralExpression(token.Value, ZSharp.AST.LiteralType.Decimal) - ); - expressionParser.Terminal( - TokenType.Identifier, - token => token.Value switch - { - "null" => ZSharp.AST.LiteralExpression.Null(), - "true" => ZSharp.AST.LiteralExpression.True(), - "false" => ZSharp.AST.LiteralExpression.False(), - _ => new ZSharp.AST.IdentifierExpression(token.Value), - } - ); - expressionParser.Nud( - LangParser.Keywords.Let, - LangParser.ParseLetExpression - ); - expressionParser.Nud( - LangParser.Keywords.Class, - zsharpParser.Class.Parse - ); - - expressionParser.InfixR("=", 10); - expressionParser.InfixL("<", 20); - expressionParser.InfixL("+", 50); - expressionParser.InfixL("-", 50); - expressionParser.InfixL("*", 70); - expressionParser.InfixL("**", 80); - - expressionParser.Led(TokenType.LParen, LangParser.ParseCallExpression, 100); - expressionParser.Led(".", LangParser.ParseMemberAccess, 150); - - expressionParser.Separator(TokenType.Comma); - expressionParser.Separator(TokenType.RParen); - expressionParser.Separator(TokenType.Semicolon); - - expressionParser.AddKeywordParser( - LangParser.Keywords.While, - LangParser.ParseWhileExpression - ); - - statementParser.AddKeywordParser( - LangParser.Keywords.While, - Utils.ExpressionStatement(LangParser.ParseWhileExpression, semicolon: false) - ); - - //zsharpParser.Function.AddKeywordParser( - // LangParser.Keywords.While, - // Utils.ExpressionStatement(LangParser.ParseWhileExpression, semicolon: false) - //); - - zsharpParser.RegisterParsers(parser); - documentNode = zsharpParser.Parse(parser); - - Console.WriteLine($"Finished parsing document with {documentNode.Statements.Count} statements!"); -} - -#endregion - - -#region Compilation - -var interpreter = new Interpreter(); -ZSharp.Runtime.NET.Runtime runtime = new(interpreter); - -interpreter.Runtime = runtime; -interpreter.HostLoader = runtime; - -ZS.RuntimeAPI.Fields_Globals.runtime = runtime; -runtime.Hooks.GetObject = ZSharp.Runtime.NET.Utils.GetMethod(ZS.RuntimeAPI.Impl_Globals.GetObject); - -var moduleIL_standardIO = typeof(Standard.IO.Impl_Globals).Module; -var moduleIR_standardIO = interpreter.HostLoader.Import(moduleIL_standardIO); -var moduleCO_standardIO = interpreter.CompilerIRLoader.Import(moduleIR_standardIO); - -interpreter.Compiler.TypeSystem.String.ToString = interpreter.CompilerIRLoader.Import( - runtime.Import( - ZSharp.Runtime.NET.Utils.GetMethod(Standard.IO.Impl_Globals.ToString) - ) -); - -interpreter.Compiler.TypeSystem.Int32.Members["parse"] = interpreter.CompilerIRLoader.Import( - runtime.Import( - ZSharp.Runtime.NET.Utils.GetMethod(Standard.IO.Impl_Globals.ParseInt32) - ) -); - -interpreter.SourceCompiler.StandardLibraryImporter.Libraries.Add("io", moduleCO_standardIO); - -var moduleIL_standardMath = typeof(Standard.Math.Impl_Globals).Module; -var moduleIR_standardMath = interpreter.HostLoader.Import(moduleIL_standardMath); -var moduleCO_standardMath = interpreter.CompilerIRLoader.Import(moduleIR_standardMath); - -interpreter.SourceCompiler.StandardLibraryImporter.Libraries.Add("math", moduleCO_standardMath); - -interpreter.SourceCompiler.Operators.Cache( - "+", - interpreter.CompilerIRLoader.Import( - runtime.Import( - ZSharp.Runtime.NET.Utils.GetMethod(Standard.IO.Impl_Globals.Concat) - ) - ) -); - -interpreter.SourceCompiler.Operators.Cache( - "<", - interpreter.CompilerIRLoader.Import( - runtime.Import( - ZSharp.Runtime.NET.Utils.GetMethod(Standard.Math.Impl_Globals.LessThan) - ) - ) -); - -interpreter.SourceCompiler.Operators.Cache( - "-", - interpreter.CompilerIRLoader.Import( - runtime.Import( - ZSharp.Runtime.NET.Utils.GetMethod(Standard.Math.Impl_Globals.Subtract) - ) - ) -); - -//var moduleIL_compilerAPI = typeof(ZS.CompilerAPI.Impl_Globals).Module; -//var moduleIR_compilerAPI = interpreter.HostLoader.Import(moduleIL_compilerAPI); -//var moduleCO_compilerAPI = interpreter.CompilerIRLoader.Import(moduleIR_compilerAPI); - -//interpreter.SourceCompiler.ZSImporter.Libraries.Add("compiler", moduleCO_compilerAPI); - -var document = interpreter.CompileDocument(documentNode, filePath); - -Console.WriteLine($"Compilation finished with {interpreter.Compiler.Log.Logs.Count(l => l.Level == LogLevel.Error)} errors!"); - -foreach (var log in interpreter.Compiler.Log.Logs) - Console.WriteLine(log); - -ZSharp.Objects.Module? mainModule = document.Content.FirstOrDefault( - item => item is ZSharp.Objects.Module module && module.Name == "Program" -) as ZSharp.Objects.Module; - -if (mainModule is not null) -{ - var mainModuleIR = - interpreter.Compiler.CompileIRObject(mainModule, null) ?? throw new(); - - var mainModuleIL = runtime.Import(mainModuleIR); - var mainModuleGlobals = mainModuleIL.GetType("") ?? throw new(); - - var mainMethod = mainModuleGlobals.GetMethod("main", []); - - Decompile(mainModuleGlobals.GetMethod("guessOnce")!); - - if (mainMethod is not null) - Decompile(mainMethod); - - mainMethod?.Invoke(null, null); -} - -#endregion - -Console.WriteLine(); - -Console.WriteLine(); -Console.WriteLine("Press any key to exit..."); -Console.ReadKey(); - - -static void Decompile(System.Reflection.MethodBase method) -{ - Console.WriteLine("========== Disassmebly: " + method.Name + " =========="); - - foreach (var instruction in Mono.Reflection.Disassembler.GetInstructions(method)) - { - Console.WriteLine(instruction); - } - - Console.WriteLine("========== Disassmebly =========="); -} diff --git a/ZSharpTest/Program.cs b/ZSharpTest/Program.cs deleted file mode 100644 index 0f2bc0b5..00000000 --- a/ZSharpTest/Program.cs +++ /dev/null @@ -1,417 +0,0 @@ -//using CommonZ.Utils; -//using ZSharp.CTRuntime; -//using ZSharp.IR.Standard; -//using ZSharp.RAST; -//using ZSharp.VM; - -//using IR = ZSharp.IR; - - -///* -// * Interpreter -// */ - -//var runtime = IR.RuntimeModule.Standard; - -//Interpreter interpreter = new(runtime); - -//{ -// interpreter.SetIR(runtime.TypeSystem.Any, TypeSystem.Any); -// interpreter.SetIR(runtime.TypeSystem.String, TypeSystem.String); -// interpreter.SetIR(runtime.TypeSystem.Void, TypeSystem.Void); -//} - -///* -// * Toolchain -// */ - -//Desugarer desugarer = new(); -////Instantiator instantiator = new(); -//ZSCompiler compiler = new(interpreter); - - -//#region Internal Functions - -//var importSystem = new StringImporter(); -//ModuleImporter moduleImporter; - -//importSystem.AddImporter("std", moduleImporter = new()); - - -//Mapping internalFunctions = []; - -//if (true) { -// IR.InternalFunction @internal; -// ZSInternalFunction impl = new( -// args => -// { -// if (args.Length != 1) -// throw new("import: expected 1 argument"); - -// var sourceObject = args[0]; - -// if (sourceObject is not ZSString sourceString) -// throw new("import: expected string"); - -// var source = sourceString.Value; - -// return importSystem.Import(source); -// } -// ); - -// @internal = new(runtime.TypeSystem.Void) -// { -// Name = "import", -// }; -// @internal.Signature.Args.Parameters.Add(new("source", runtime.TypeSystem.Void)); - -// interpreter.SetIR(@internal, impl); -// internalFunctions.Add("import", @internal); -//} - -//if (true) -//{ -// IR.InternalFunction @internal; -// ZSInternalFunction impl = new( -// args => -// { -// if (args.Length != 2) -// throw new("getattr: expected 2 arguments"); - -// var @object = args[0]; -// var name = args[1]; - -// if (name is not ZSString nameString) -// throw new("getattr: name must be a string"); - -// if (@object is not ZSModule module) -// throw new("getattr: object must be a valid module"); - -// var binding = compiler.Context.Bindings.Cache(module.Module); - -// if (binding is not ICTGetMember getMember) -// throw new("getattr: object does not support get member"); - -// return new ZSHandle(getMember.Member(compiler, nameString.Value)); - -// //IR.IRObject result; - -// //result = -// // (module.Module.Globals.FirstOrDefault(g => g.Name == nameString.Value) -// // as IR.IRObject -// // ) -// // ?? -// // (module.Module.Functions.FirstOrDefault(f => f.Name == nameString.Value) -// // as IR.IRObject -// // ) ?? -// // throw new($"Could not find attribute {nameString.Value} in {module}"); - -// //Code code = new(1, [ -// // new IR.VM.GetObject(result) -// // ], TypeSystem.Any); - -// //return new ZSHandle(code); -// } -// ); - -// @internal = new(runtime.TypeSystem.Any) -// { -// Name = "getAttribute", -// }; -// @internal.Signature.Args.Parameters.Add(new("object", runtime.TypeSystem.Any)); -// @internal.Signature.Args.Parameters.Add(new("name", runtime.TypeSystem.String)); -// interpreter.SetIR(@internal, impl); -// internalFunctions.Add("getAttribute", @internal); -//} - -//if (true) -//{ -// IR.InternalFunction @internal; - -// @internal = new(runtime.TypeSystem.Void) -// { -// Name = "print", -// }; -// @internal.Signature.Args.Parameters.Add(new("message", runtime.TypeSystem.String)); - -// ZSInternalFunction impl = new( -// args => -// { -// if (args.Length != 1) -// throw new("print: expected 1 argument"); - -// var messageObject = args[0]; - -// if (messageObject is not ZSString messageString) -// throw new("print: expected string"); - -// var message = messageString.Value; - -// Console.WriteLine(message); - -// return null; -// }, -// new RTFunctionType(LoadSignature(@internal.Signature)) -// ); - -// interpreter.SetIR(@internal, impl); -// internalFunctions.Add("print", @internal); -//} - - -//#endregion - - -//#region Standard Library - - -//var ioModule = new IR.Module("io"); - -//if (true) { -// IR.Function printFunction; - -// printFunction = new(runtime.TypeSystem.Void) -// { -// Name = "print", -// }; - -// var sig = printFunction.Signature; -// sig.Args.Parameters.Add(new("message", runtime.TypeSystem.String)); - -// printFunction.Body.Instructions.AddRange([ -// new IR.VM.GetArgument(sig.Args.Parameters[0]), -// new IR.VM.CallInternal(internalFunctions["print"]), -// new IR.VM.Return(), -// ]); - -// printFunction.Body.StackSize = 2; - -// ioModule.Functions.Add(printFunction); -//} - -//interpreter.SetIR(ioModule, moduleImporter.AddModule(ioModule)); -//compiler.Load(ioModule); - - -//#endregion - - -//#region Global Scope - - -//if (true) { -// IR.Function importFunction; -// IR.Parameter source; - -// importFunction = new(runtime.TypeSystem.Any) -// { -// Name = "import", -// }; - -// var sig = importFunction.Signature; -// sig.Args.Parameters.Add(source = new("source", runtime.TypeSystem.String)); - -// importFunction.Body.Instructions.AddRange([ -// new IR.VM.GetArgument(source), -// new IR.VM.CallInternal(internalFunctions["import"]), -// new IR.VM.Return(), -// ]); - -// importFunction.Body.StackSize = 2; -// compiler.DefineGlobal( -// desugarer.Context.ImportFunction, -// new RTFunction(importFunction, LoadSignature(sig)) -// ); -//} - -//if (true) -//{ -// IR.Function getattrFunction; -// IR.Parameter @object, name; - -// getattrFunction = new(runtime.TypeSystem.Any) -// { -// Name = "_._" -// }; - -// var sig = getattrFunction.Signature; -// sig.Args.Parameters.Add(@object = new("object", runtime.TypeSystem.Any)); -// sig.Args.Parameters.Add(name = new("name", runtime.TypeSystem.String)); - -// getattrFunction.Body.Instructions.AddRange([ -// new IR.VM.GetArgument(@object), -// new IR.VM.GetArgument(name), -// new IR.VM.CallInternal(internalFunctions["getAttribute"]), -// new IR.VM.Return() -// ]); - -// getattrFunction.Body.StackSize = 3; -// compiler.DefineGlobal( -// desugarer.Context.GetBinaryOperator("."), -// new CGFunction(getattrFunction, LoadSignature(sig)) -// ); -//} - - -//RId globalVoid = new("void"); -//compiler.DefineGlobal(globalVoid, new Class(runtime.TypeSystem.Void)); -//RId globalString = new("string"); -//compiler.DefineGlobal(globalString, new Class(runtime.TypeSystem.String)); - - -//#endregion - - -//#region RAST - -///* -// * The code below represents the RAST of the following Z# code: -// * -// * let stdIO = "std:io"; -// * import { print } from stdIO; -// * -// * fun id(x: string): string { -// * return x; -// * } -// * -// * let message = id("Hello, World!"); -// * print(message); -// * -// * fun foo(x: string): void { -// * print(x); -// * } -// * -// * foo("Hello, foo!"); -// */ - - -//RId stdIO; -//RId print; -//RId id; -//RId id_x; -//RId message; -//RId foo_x; -//RId foo; -//var rastNodes = new RStatement[] -//{ -// // let stdIO = "std:io"; -// new RLetStatement( -// new RNamePattern(stdIO = new("stdIO")), -// null, -// RLiteral.String("std:io") -// ), - -// // import { print } from stdIO; -// new RImport(stdIO) -// { -// Targets = [ -// new("print") -// ] -// }, - -// new RExpressionStatement( -// new RFunction( -// id = new("id"), -// new() -// { -// Args = [ -// new(id_x = new("x"), globalString, null) -// ] -// }) -// { -// ReturnType = globalString, -// Body = new RReturn(id_x) -// } -// ), - -// // let message = "Hello, World!"; -// new RLetStatement( -// new RNamePattern(message = new("message")), -// null, //globals["string"], -// new RCall( -// id, -// [ -// new(RLiteral.String("Hello, World!")) -// ] -// ) -// ), - -// // print(message); -// new RExpressionStatement( -// new RCall(print, -// [ -// new(message) -// ]) -// ), - -// // fun foo(x: string): void { print(x); } -// new RExpressionStatement( -// new RFunction( -// foo = new("foo"), -// new() { -// Args = -// [ -// new(foo_x = new("x"), globalString, null) -// ] -// }) -// { -// ReturnType = globalVoid, -// Body = new RReturn( -// new RCall(print, -// [ -// new(foo_x) -// ]) -// ) -// } -// ), - -// // foo("Hello, foo!"); -// new RExpressionStatement( -// new RCall(foo, -// [ -// new(RLiteral.String("Hello, foo!")) -// ]) -// ) -//}; - -//RModule moduleNode = new(string.Empty) { Content = new(new(rastNodes)) }; - -//#endregion - - -//#region Main - -//// Simplify the RAST -//moduleNode = desugarer.Desugar(moduleNode); - -//// Declare module contents -////var scopes = instantiator.Instantiate(moduleNode); - -//// Document module -//IR.Module module; - -//// Definitions -//using (compiler.UseContext()) // if you want to pre-initialize, pass compiler.Context to the instantiator and use NewScope -// module = compiler.Compile(moduleNode); - - -//var moduleObject = interpreter.LoadIR(module) as ZSModule; - -//Console.WriteLine("Program finished!"); - -//#endregion - - -//#region Utilities - -//Signature LoadSignature(IR.Signature signature) -//{ -// var result = new Signature(signature); - -// foreach (var parameter in signature.Args.Parameters) -// result.Args.Add(new(parameter, interpreter.LoadType(parameter.Type))); - -// return result; -//} - -//#endregion diff --git a/ZSharpTest/Properties/launchSettings.json b/ZSharpTest/Properties/launchSettings.json deleted file mode 100644 index 99803480..00000000 --- a/ZSharpTest/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "ZSharpTest": { - "commandName": "Project", - "commandLineArgs": "guessing-game.zs" - } - } -} \ No newline at end of file diff --git a/ZSharpTest/ZSharpTest.csproj b/ZSharpTest/ZSharpTest.csproj deleted file mode 100644 index 93158e38..00000000 --- a/ZSharpTest/ZSharpTest.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - diff --git a/ZSharpTest/guessing-game.zs b/ZSharpTest/guessing-game.zs deleted file mode 100644 index fcce44e8..00000000 --- a/ZSharpTest/guessing-game.zs +++ /dev/null @@ -1,47 +0,0 @@ -import { input, print } from "std:io"; -import { ceil, log2, random, increment } from "std:math"; -//import { random } from "std:random"; - -module Program; - -fun guessOnce(guess: i32, number: i32, tries: i32): bool { - while (guess < number) - { - print("Too low!"); - return false; - } - while (number < guess) - { - print("Too high!"); - return false; - } - - print("You got it in " + string(increment(tries)) + " tries!"); - return true; -} - -fun main(): void { - let minNumber = 1; - let maxNumber = 100; - - let number = random(minNumber, maxNumber); - let maxTries = ceil(log2(maxNumber - minNumber)); - - var tries = 0; - - while (tries < maxTries) { - let guessString = input("Guess a number between " + string(minNumber) + " and " + string(maxNumber) + ": "); - let guess = i32.parse(guessString); - - while (guessOnce(guess, number, tries)) - { - tries = increment(maxTries); - break; - } else tries = increment(tries); - } - - while (maxTries < tries) { break; } - else print("You didn't get it in " + string(maxTries) + " tries. The number was " + string(number)); - - return; -} diff --git a/ZSharpTest/test.zs b/ZSharpTest/test.zs deleted file mode 100644 index 1cb7f9b9..00000000 --- a/ZSharpTest/test.zs +++ /dev/null @@ -1,77 +0,0 @@ -import { print as output } from "std:io"; - -module Lib { - fun bar(x: string = "hello"): string { - return x; - } - - fun id(x: type): type { - output(x); - return x; - } -} - -module Program; - -fun main(): i32 { - blah(); - - output(pi + 5.0); - - output(1 + 1); - - output(true); - output(false); - - return foo.bar(); -} - -let x = y; -let y = "Hello"; - -let exitCode = 100; - -let pi = 3.14; - -let foo = Foo(); - -fun blah(): Lib.id(string) { - let tmp = Lib.bar(x); - - return tmp; -} - -class Foo { - let x = Lib.bar(y); - - new(self: Foo) - { - - } - - fun bar(this): i32 { - output("bar"); - - // zzz(this); - - let blah = Blah(); - blah.v = "zzz arg"; - - this.zzz(v); - - return exitCode; - } - - fun zzz(this, x: class Blah { let v: string = ""; }): void { - output(this.x = x.v); - - return; - } -} - -/* -if (isProduction) - fun foo() { } -else - import { foo } from "foo"; -*/ \ No newline at end of file diff --git a/ZSharpTest/test2.zs b/ZSharpTest/test2.zs deleted file mode 100644 index f467e9cf..00000000 --- a/ZSharpTest/test2.zs +++ /dev/null @@ -1,60 +0,0 @@ -import { input, print } from "std:io"; - - -module Lib { - fun id(x: type): type { return x; } - - fun str(s: string): string { return s; } - - fun printAndGetVoid(x: string): type { print("CT: " + x); return void; } -} - - -module Program; - -var message: string; - -fun main(): Lib.id(void) { - message = input("Please enter a message: "); - let audience = "World!"; - - bar(audience); - - { - print("Hello"); - } - - var v = 10 - 3; - - print(string(v)); - - v = 4; - - print(string(v)); - - while (false) - { - print("TRUE"); - break; - } else { - print("FALSE"); - } - - return; -} - -fun bar(x: string): Lib.printAndGetVoid("This is executed at CT!") { - foo(message + ", " + Lib.str(x)); - return; -} - -fun foo(x: string): void { - print(x); - return; -} - - -// import { compile } from "pkg:dotnet-compiler"; - -// let dotNETModule = compile(infoof(Program)); -// dotNETModule.Write("Program.dll"); diff --git a/ZSharpTokenizerTest/Program.cs b/ZSharpTokenizerTest/Program.cs deleted file mode 100644 index 2b08a92a..00000000 --- a/ZSharpTokenizerTest/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -using ZSharp.Tokenizer; - - -using (StreamReader stream = File.OpenText("./tokenizerText.txt")) - foreach (var token in Tokenizer.Tokenize(new(stream))) - { - if (token.Is(ZSharp.Text.TokenCategory.WhiteSpace)) - Console.WriteLine($"Token ({token.Type}) @ ({token.Span})"); - else - Console.WriteLine($"Token ({token.Type}) @ ({token.Span}) = {token.Value}"); - } diff --git a/ZSharpTokenizerTest/ZSharpTokenizerTest.csproj b/ZSharpTokenizerTest/ZSharpTokenizerTest.csproj deleted file mode 100644 index 704d2d3c..00000000 --- a/ZSharpTokenizerTest/ZSharpTokenizerTest.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - PreserveNewest - - - - diff --git a/ZSharpTokenizerTest/tokenizerText.txt b/ZSharpTokenizerTest/tokenizerText.txt deleted file mode 100644 index a1956724..00000000 --- a/ZSharpTokenizerTest/tokenizerText.txt +++ /dev/null @@ -1,10 +0,0 @@ -"Hello this is a string" - - "And with escape chars:\n \\ \"" 'H' [] ( - ) , ;: - -_ id this_is_id thisIsAlso _0 __ a0 a0_ - -/ + ++ -- == += -= *= && - -1 2 12 123 1.0 1.2 1.12 1i32 1.111 \ No newline at end of file