Internal Design of a Julia Runtime in C#

I have been working hard recently on developing a runtime for Julia from the ground up written purely in C# (GitHub - HyperSphereStudio/Spinor: Spinor Programming Language. Dynamically Typed Extension of Julia written and built to run on .NET).

I will be writing a paper on the theory of what I hope to achieve and current/future designs of the runtime (which I call the Spinor Programming Language since it is a fork of Julia).

For a quick summary the project consumes Spinor/Julia code from a file and interprets the top level scope into something called a Runtime Module. Runtime modules only exist at compile time and handles dynamic code generation. You can choose to save the dynamically generated code to a c# .dll and even interact with the output in c# if you choose to. Essentially, the Spinor Language creates either a library or executable that references other libraries based on your input.

Example Boot.sp

#This File Is A Special File That is Run without full Spinor type initialization
#Types are built organically from this File
#Only define abstract types, abstractbuiltin & primitive types in this file

abstract type Number end
abstract type Real <: Number end
abstract type Integer <: Real end

abstractbuiltin type AbstractFloat <: Real end
abstractbuiltin type Signed <: Integer end
abstractbuiltin type Unsigned <: Integer end

primitive type Float16 <: AbstractFloat 16 end
primitive type Float32 <: AbstractFloat 32 end
primitive type Float64 <: AbstractFloat 64 end
primitive type Float128 <: AbstractFloat 128 end

primitive type Bool <: Signed 8 end
primitive type Char <: Unsigned 32 end

primitive type Int8    <: Signed   8 end
primitive type UInt8   <: Unsigned 8 end
primitive type Int16   <: Signed   16 end
primitive type UInt16  <: Unsigned 16 end
primitive type Int32   <: Signed   32 end
primitive type UInt32  <: Unsigned 32 end
primitive type Int64   <: Signed   64 end
primitive type UInt64  <: Unsigned 64 end
primitive type Int128  <: Signed   128 end
primitive type UInt128 <: Unsigned 128 end

#After Running the following will be added: Int = Native Int, UInt = Native UInt, Float = Native Float

abstractbuiltin type Exception end

abstract type IO end

struct s 
    x
end

Output of Spinor Runtime for Int64

namespace Root.Core
{
  public struct Int64 : Number, Real, IAny, Integer, Any, Signed, IPrimitiveValue
  {
    public readonly long Value;
    private static readonly SType __RuntimeType__;

    public Int64(long value) => this.Value = value;

    public override string ToString() => this.Value.ToString();

    void Any.Serialize(SpinorSerializer x) => x.Write<long>(this.Value);

    SType IAny.RuntimeType => Int64.__RuntimeType__;

    SType Any.Type => Int64.__RuntimeType__;
  }
}

There is still tons of work that needs to be done. This is only surface level working at the moment. My next task will be implementing multiple dispatch and functions.

If anyone has any tips for how I should design the language let me know. This is a sandbox to try many new ideas :slight_smile:

While Writing this I found it funny that Runtime Modules only run during Compile time… Perhaps I should rename this lol

4 Likes

so the up shot of this is… this is ironpython but for Julia?

1 Like