Skip to content
ALB Wiki

Diff — ALB .NET backend

Comparing rev 3 → rev 4

{{infobox
| title = ALB .NET backend
| tool = `albn.exe` ("ALBN — AdaLogic BASIC for .NET/C#")
| produces = C# source (.cs) + generated .csproj (deterministic project)
| builds_with = `dotnet` SDK — default target `net8.0`
| emitter_unit = `Emit_Native_DotNet` (emit_native_dotnet.adb) — ~10,700 lines
| flags = `--build` · `--framework` · `--langversion` · `--nullable` · `--unsafe`
| status = The managed powerhouse — the System.* ecosystem from BASIC
}}
The **ALB .NET backend** — **ALBN** — compiles [[AdaLogic BASIC]] into **C#**: one complete source file plus a generated `.csproj` that any `dotnet` SDK can build — Microsoft's open-source **Roslyn** compiler then lowers the C# to IL bytecode, which the CLR's JIT (or NativeAOT, for a standalone native binary) takes the rest of the way. It is the managed powerhouse of the family: where FASM hands you a PE and C hands you a build kit, ALBN hands the program the entire .NET ecosystem — `System.Net.Sockets`, `System.Numerics`, `System.Reflection`, real generics — while still reaching down to the native floor through P/Invoke when it needs the metal.
```alb One-liner
albn tool.alb --build
→ tool.cs + tool.csproj + SDL3.dll → dotnet build → managed .exe
```
-
## Why managed is a different bargain
+
# Why managed is a different bargain
Every other backend answers "what does the program run on?" with hardware. ALBN answers with a **runtime that already exists**: the JIT compiles the emitted C# per-machine, the GC collects, the class libraries are already installed. The emitter's job changes accordingly — it doesn't port the OS; it ports *ALB* into a language where most of the OS is one `using` away.
And yet the runtime still brings ALB's own machinery, because ALB's semantics aren't .NET's: the claim-tree memory model, the Prolog relation table, sized-integer discipline, and the deterministic learning layer all get rebuilt in C# rather than deferred to managed equivalents.
-
## What the generated program looks like
+
# What the generated program looks like
A real namespace, a real entry point, the framework namespaces it actually uses:
```csharp
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Numerics;
using System.Reflection;
using System.Runtime.InteropServices;
namespace ALB_Generated
{
    public static class Program
    {
        public static void Main(string[] args) { …
```
The `.csproj` is equally deliberate — not a default template but a hand-specified project: `<Deterministic>true</Deterministic>` (byte-identical builds), `<Optimize>true`, `EnableDefaultCompileItems=false`, `ImplicitUsings=disable` (no ambient magic), `AllowUnsafeBlocks` when `--unsafe` is passed, and `SDL3.dll` linked with `CopyToOutputDirectory` so the native dependency travels with the build.
-
## ALB's types, as real C# types
+
# ALB's types, as real C# types
No boxing the language into `object` — ALB's type system maps to value-type structs you'd write by hand:
- **`Pure128`** — `long Numerator; long Denominator;` — PURE rationals as a struct, numerator and denominator kept separate so ⅓ + ⅓ stays exactly ⅓
- **`ALB_U128`** — `ulong Low; ulong High;` — 128-bit integers before `UInt128` was a thing you could assume
- **`F32x2`, `F32x4`** — ALB's `FLOAT2`/`FLOAT4` vectors as real structs
- **`Mat2x2` / `Mat3x3` / `Mat4x4`** — the full matrix family with named `M11…M44` fields
- **`ALB_AssignSlot`** — the variant box: one struct with a `Kind` tag and slots for `long`/`ulong`/`double`/`bool`/`string`/`Pure128`/`ALB_U128` — how the runtime holds "a value of any ALB type"
-
## The bridge down: P/Invoke
+
# The bridge down: P/Invoke
Managed doesn't mean sealed off. The emitter writes hand-marshaled interop by hand — `[StructLayout]`-faithful `struct SDL_Event`, `SDL_FRect`, `SDL_Surface`, `SDL_AudioSpec` — and declares the native surface itself:
```csharp
[DllImport("SDL3", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SDL_Init(uint flags);
```
The whole graphics/audio/input stack rides SDL3 through P/Invoke — the same native library the asm backends link, now calling *into* a JIT-compiled program. `--unsafe` opens the door further, enabling `AllowUnsafeBlocks` in the project so emitted code can pin, take addresses, and do pointer work where managed references won't do.
-
## The runtime, ported to the managed world
+
# The runtime, ported to the managed world
- **The learning layer, same as everywhere** — `ALB_NN_*` and Markov prediction, with the *same* deterministic `Seed_Neural_Weight` algorithm (input-span, positive/negative neighbor patterns) — a net trained on FASM starts from identical weights on .NET
- **The Logic pillar in C#** — `ALB_RelFact` (relation id, arity, arguments, value) — the Prolog/Datalog knowledge base rebuilt as a managed relation table
- **The claim grid, in a GC'd world** — `ALB_ClaimNode` (Active/Marked/Root/Address/Child1/Child2) — ALB's own ownership tree running *inside* .NET's collector; two memory philosophies in one process
- **Real sockets** — `System.Net.Sockets` behind ALB's `NET` statements — managed networking, not a port of the asm `ws2_32` loader
- **Files** — `ALB_FileSlot` records wrapping real `FileStream`s
- **Whole-program snapshots** — `ALB_UserStateSnapshot` for `SAVE STATE`
- **An MML music engine** — `ALB_MmlNumber` parses Music Macro Language (tempo, octave, note length) and *synthesizes* the waveform: `440.0 * Math.Pow(2.0, (midi - 69) / 12.0)`, S16 samples generated into an audio scratch buffer — chiptune from BASIC through managed math
- **Clip-mapped rendering** — `ALB_MapRenderX/Y` translates the virtual canvas into window coordinates
The event model stays ALB's: `while (ALB_Running)` pumping `SDL_PollEvent(out ev)`, dispatching to the emitted `ON TICK` / `ON PAINT` / `ON KEY` bodies — a managed main loop that looks exactly like the native one, because it's generated by the same rules.
-
## Flags worth knowing
+
# Flags worth knowing
`--build` packages everything into `dotnet_<name>/` — source, csproj, SDL3.dll — a **deterministic C# project directory** you can carry to any machine with the SDK. `--framework <tfm>` retargets (default `net8.0`), `--langversion` pins the C# dialect, `--nullable` controls nullability annotations, `--unsafe` lifts the pointer ban, `--metrics`/`--walker`/`--quiet` do what they do on `albw`.
-
## Under the hood
+
# Under the hood
`Emit_Native_DotNet` (~10,700 lines, `pragma SPARK_Mode (On)`) is the same AST-walker architecture as the [[ALB Ada backend|Ada]] and [[ALB TypeScript backend|TypeScript]] emitters: `Emit_Program` receives the token array, the tree, and the root — the whole program visible before a line is written. `albn.adb` handles flags, the csproj writer, and SDL3 staging. The pattern continues: one front end, and each backend's job is to be *more itself* — here, the most idiomatic C# the language allows.
-
## See also
+
# See also
- [[AdaLogic BASIC]] — the language
- [[ALB FASM backend]] · [[ALB C backend]] · [[ALB Ada backend]] · [[ALB TypeScript backend]] · [[ALB NASM backend]] · [[ALB FASM16 backend]]
- [[Compilers]] — the native toolchain families ALBN bypasses
- [[Java Virtual Machine]] — the CLR's older sibling
- [[History of Programming]] — where managed runtimes sit in the arc
-
## References
+
# References
1. ALB Handbook — alb-lang.org/handbook — the language reference.
2. Microsoft Learn — Roslyn (.NET Compiler Platform) documentation, learn.microsoft.com.
3. Microsoft Learn — dotnet SDK and NativeAOT documentation.
[[Category:Backends]]
[[Category:AdaLogic BASIC]]