diff --git a/Qrakhen.Qamp.CLI/Program.cs b/Qrakhen.Qamp.CLI/Program.cs index 8e10ef2..3a61e3b 100644 --- a/Qrakhen.Qamp.CLI/Program.cs +++ b/Qrakhen.Qamp.CLI/Program.cs @@ -7,6 +7,32 @@ using System.Text; // do args here too, keep console, etc. output with exit, all the spicy things // if no file is given for example in args just keep cli live until quit +void Init(string[] args) +{ + Console.WriteLine(string.Join(',', args)); + string command = args.Length > 1 ? args[0] : args.Length == 1 ? "run" : "cli"; + string target = args.Length > 1 ? args[1] : args.Length == 1 ? args[0] : ""; + switch (command) { + case "run": + // check wheter .sqi or .sqr file + break; + case "cli": + + break; + case "read": + + break; + case "digest": + + break; + case "help": + + break; + } +} + +Init(args); + List Ignored = [ '\0', '\b' ]; LoggerService.Default = LogLevel.Error; List History = []; @@ -109,3 +135,31 @@ do { } } } while(code != ConsoleCode.Exit); + +public class Command +{ + + public class Parameters + { + + } + + public class Definition + { + public string Name { get; init; } + public string Alias { get; init; } + + public class Parameter + { + public string Name { get; init; } + public string Alias { get; init; } + } + } +} + +public class ArgumentAttribute(string name, string alias, string description) +{ + public string Name { get; } = name; + public string Alias { get; } = alias; + public string Description { get; } = description; +} \ No newline at end of file diff --git a/Qrakhen.Qamp.Core/README.md b/Qrakhen.Qamp.Core/README.md new file mode 100644 index 0000000..06e0ac6 --- /dev/null +++ b/Qrakhen.Qamp.Core/README.md @@ -0,0 +1,127 @@ +# Q& +## Q Ampersand +### ...or just 'Qwamp'. + +## About + +A single-pass byte code interpreter with the ability to pre-compile executables +into a format that can be efficiently executed by the runtime. +It serves many features, which are listed a bit further down below. + +This would have officially been the fourth iteration of my language (sqript4), +but I thought I'd stop with the numbers as people would ask what happened to the +previous three languages. + +Q& (or Qamp for Q Ampersand) was originally made for my contributions to the +Advent Of Code 2025, but I thought it's a nice and stable enough concept to be +sharing it to the public anyway. + +## Usage + +To build **Q&**, you need nothing more than a C# compiler that supports .NET10. +There are .NET8 compatible versions available, but they are not recommended, +as **Q&** utilizes all of the performance optimizations .NET10 has to offer. + +After cloning, a simple `dotnet build ./` in the root directory will suffice. + +You can execute pre-compiled .sqi files using `qamp.runtime.exe [parameters]`, +or the REPL/CLI using `qamp.cli.exe [parameters]`. +If you want to build your own source into pre-compiled instruction files, +use `qamp.digest.exe ` - the digester will look for an `Init()` function +declared in any of the files, and build the instructions from there. + +## Feature Overview + + - Easily extensible with custom Libraries using the C# SDK + - Classic OOP Features (Classes & Inheritance) + - Chooseable between Dynamic and Static Typing + - Premium Syntax and Syntactic Sugars + - Syntax-Highlighting REPL Interface + - Customizable Dialects (Syntax & Keywords) + - Separated Parsing, Compilation and Execution + +## Language & Syntax + +You are free to choose between the classic sqript-style dialect `*~ q <~ 0xf;` or +the standard dialect, which is strongly inspired by the C# standard: `var q = 0xf;`. + +All of the following examples are written in the classic dialect `--dialect=sqr` or `-d=q`. + +### Syntax + +Most basic Usage: +```cs + # this is a comment. +*~ q <~ 12; # q == 12 +*~ f <~ (n) <: n < 2 ? n : f(n-1) + f(n-2); # fibonacci +f(12); # 233 +*~ a <~ [1, 2, 3]; # a = [1, 2, 3] +*~ x <~ a:0 + a:2; # x == 4 +``` + +### Assignments + +**Q&** has two distinct ways to assign a value to a variable: + - By reference `<&`, or + - By value `<=`. + +Using the auto-assignment operator `<~`, **Q&** will choose the correct assignment based on what +type the right-hand expression consists of. +Primitive types will be assigned by value, any object values will be assigned by reference. +This is strongly inspired by the behaviour that most interpeters implement. + +#### What happens if... +##### I assign an object by value? +The entire object will be deep-copied and transfered to the new location. +See it as a free clone method on basically anything that is considered an object. +##### I assign a primitive by reference? +So, assuming that `x` is a primitive (value type), given the instruction `*~ y <& x;`, +`y` will be assigned as a reference value _pointing_ to the location of `x` - somewhat like a +pointer in C, but a little smarter. +##### I do not praise the god emperor of mankind? +You will be duly punished. + +#### Variable Declaration + +``` +*~ q <~ 0xf; +``` + +#### Variable Declaration + +## Customization & Extras + +Some more information about extending and customizing Q& to your needs. + +### Implementing external Libraries + +Implementation is easy. +Q& is written in C#, and supports basically anything you can wrap in C#. +All you have to do in order to implement a library is referencing the SDK dll +which should be located within your `./Build/` folder after building as described above. + +Here's a quick example of how you would implement virtually any library: +```cs +using Qrakhen.Qamp.Core; +using System.Math; + +Value Sqrt(Value number) +{ + Assert.IsNumber(number); + + if (number.IsDecimal) + return Math.Sqrt(number.AsDecimal); + if (number.IsSigned) + return Math.Sqrt(number.AsSigned); + if (number.IsUnsigned) + return Math.Sqrt(number.Unsigned); + throw new Qrakhen.Qamp.Core.QampException($"Unsupported value type {value}"); +} + +Injector injector = new(); +injector.Register(scope: Scope.Global, name: "sqrt", params: [ ("number", ValueType.Number) ], returns: ValueType.Number); +injector.Export("desiredPath.sqi"); +``` +That's it - although this being a very simple example, more is possible. +I will add a few basic implementations of very common libraries in a separate repository soon. + diff --git a/Qrakhen.Qamp.Reader/Class1.cs b/Qrakhen.Qamp.Reader/Class1.cs new file mode 100644 index 0000000..980dc3e --- /dev/null +++ b/Qrakhen.Qamp.Reader/Class1.cs @@ -0,0 +1,6 @@ +namespace Qrakhen.Qamp.Reader; + +public class Class1 +{ + +} diff --git a/Qrakhen.Qamp.Reader/Qrakhen.Qamp.Reader.csproj b/Qrakhen.Qamp.Reader/Qrakhen.Qamp.Reader.csproj new file mode 100644 index 0000000..b760144 --- /dev/null +++ b/Qrakhen.Qamp.Reader/Qrakhen.Qamp.Reader.csproj @@ -0,0 +1,9 @@ + + + + net10.0 + enable + enable + + + diff --git a/Qrakhen.Qamp.sln b/Qrakhen.Qamp.sln index ce2534f..81f5316 100644 --- a/Qrakhen.Qamp.sln +++ b/Qrakhen.Qamp.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qrakhen.Qamp.Digest", "Qrak EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qrakhen.Qamp.Runtime", "Qrakhen.Qamp.Runtime\Qrakhen.Qamp.Runtime.csproj", "{4B0C0717-6529-4B70-A3EA-C3426F1B3FDC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qrakhen.Qamp.Reader", "Qrakhen.Qamp.Reader\Qrakhen.Qamp.Reader.csproj", "{F34E1BFD-4308-461A-A6E8-862715B91679}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +35,10 @@ Global {4B0C0717-6529-4B70-A3EA-C3426F1B3FDC}.Debug|Any CPU.Build.0 = Debug|Any CPU {4B0C0717-6529-4B70-A3EA-C3426F1B3FDC}.Release|Any CPU.ActiveCfg = Release|Any CPU {4B0C0717-6529-4B70-A3EA-C3426F1B3FDC}.Release|Any CPU.Build.0 = Release|Any CPU + {F34E1BFD-4308-461A-A6E8-862715B91679}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F34E1BFD-4308-461A-A6E8-862715B91679}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F34E1BFD-4308-461A-A6E8-862715B91679}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F34E1BFD-4308-461A-A6E8-862715B91679}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE