Skip to content

Releases: ApparentlyPlus/Appa

Appa v2.2.0 (Stable)

Choose a tag to compare

@ApparentlyPlus ApparentlyPlus released this 01 Sep 16:54

Appa v2.2.0 (Stable)

This update fixes a cluster of miscompiles in generics, operator dispatch and ARC lowering, every one of them found while porting a Span[T]-shaped library to Gata and scaffolding the self-hosting example, bringing the compiler to v2.2.0:

  • Fixed operator dispatch firing on pointer-typed values. ClassNameOf follows pointer indirection, so any expression whose type was SomeClass* was treated as eligible for SomeClass's own operator overloads. A generic union's T* payload, pattern-bound inside a generic function and advanced with ptr + n, compiled into a call to the pointee class's + operator instead of pointer arithmetic whenever T was instantiated with a class that declared one. The same confusion reached as casts, prefix and postfix operators, unary operators, binary operators, compound assignment and indexed compound assignment. All nine sites now use a new DirectClassNameOf, which reads a class reference and refuses to look through a pointer, so Adder* is a pointer and only Adder is a class.

  • Fixed a generic method's call to a generic free function silently dropping the callee's definition. DrainGenericInstancesCore drained the free-function queue to empty and then the method queue, in that order and once each. Resolving a queued generic method can enqueue a fresh free-function instantiation, and by then nothing was left to drain it, so a module method with its own type parameter that called a generic free function reachable through no other call site emitted the call and never the function. Both drains now sit inside an outer loop that runs until the two queues are empty together.

  • Fixed a dead release being appended after a return that already released. A function with several early-exit if { return ...; } branches, whose final branch also returned a freshly built managed value, had the block's frame released a second time after its own return statement. Unreachable in C terms, but it emitted a release of a temporary the return had already handed off. LowerBlock now checks whether the statements it produced already end in a return, break or continue before releasing the frame.

  • Fixed void being emitted as the type of a return temporary. The lowered return declares a __ret temp to hold the value across the frame's releases, and typed it from the returned expression rather than from the function. An expression that carries no IR type of its own produced void __ret0 = ...;, which no C compiler accepts. Ownership now tracks the declared return type of the function being lowered and falls back to it, saving and restoring it around nested functions the way it already did for the throws state.

  • Fixed a throws function whose body ends without a return falling off the end of a non-void C function. The lowering that wraps returns in Ok(...) never supplied the implicit one, so the emitted function simply ran out of statements while declaring a Result return type. LowerFunction now appends return Ok(...) to any throws body that is empty or does not already end in a return.

  • Fixed G093 firing on code that manages a union's reference count by hand. The unsafe block warning suppresses itself when the block names retain or release, but it only recognised the two intrinsics by their C names. A union's generated per-type retain/release pair did not match, so hand-counting a union inside unsafe still drew "this builds a value inside an 'unsafe' block, where it is never released". The check now also recognises a single-argument call to a union's own retain or release.

  • Added argc/argv plumbing to the generated hosted main. It was int main(void), which left an environment's _env_argc/_env_argv with nothing to read. It is now int main(int argc, char** argv) and stashes both into the gata_argc/gata_argv globals the hosted environment declares, which is what makes libgata's new Args module work.

  • Extended the C-reserved rename list with the names the Windows headers claim. windows.h, which the hosted preamble includes on that platform, defines min, max, near, far, IN, OUT, OPTIONAL, CONST, VOID, TRUE, FALSE, interface, ERROR, INVALID_HANDLE_VALUE and the calling-convention macros. A local, parameter or struct member named after any of them compiled everywhere except Windows. All of them now take the same trailing-underscore rename as the C keywords.

  • Added CompilerBugRegressionTests, covering the first three fixes above end to end. Each one compiles the emitted C with a real host compiler and asserts on the program's output, rather than settling for "appa accepted it".

Installation

For setting up Appa in your own machine, grab one of the following executables depending on the platform and run appa install:

  • Windows: appa-win.exe
  • Linux: appa-linux
  • MacOS on ARM (Apple Silicon): appa-amac
  • MacOS on Intel (Legacy x64): appa-imac

Appa v2.1.0 (Stable)

Choose a tag to compare

@ApparentlyPlus ApparentlyPlus released this 18 Aug 18:18

This update fixes a crucial correctness bug in process/thread launching plus a related C-name collision gap, bringing the compiler to v2.1.0:

  1. Fixed process/thread launching for every build shape but the split kernel+user one. appa build only ever emitted the generated launcher (uapps, which creates each process and spawns its threads) into umain.c, which is produced solely when a build has both a kernel realm and a user realm. A Hosted build, or a kernel-only build, that declared a process with threads compiled cleanly, required none of the proc-create/thread-spawn intrinsics, and then silently did nothing at runtime - the threads were emitted, fully typed and reachable, but never started. Layout.Compose now emits the launcher call into program.c and kernel-only kmain.c as well, Pipeline's capability probe no longer gates the required intrinsics behind "both realms present," and a new end-to-end test spawns real threads through a Hosted build and checks their output, so this can't regress silently again.

  2. Fixed the G091 ("process declares no threads") check being skipped entirely on the Hosted target. The validation loop that reports it lived textually after the Hosted branch's early return, so a Hosted build with an empty process got no diagnostic at all. Hoisted the check above the target branch so it runs for both targets uniformly.

  3. Fixed struct member names never receiving the same C-keyword rename locals and parameters already get. A class field, a union variant, or a variant's payload field named after a C keyword or standard macro (e.g. register, inline, extern, restrict, typedef) was emitted verbatim into the generated struct, producing a C compile failure the Gata source gave no indication of. Mangler.Member now applies the same trailing-underscore rename at every emission site - struct declarations, field/payload access, retain/release calls, generated equality - and ManglingCollisionTests now round-trips six of the sharper C keywords (including errno and stdout, which are macros rather than keywords on some libcs) through a real C compiler.

  4. Added diagnostic G102 for the one name that rename can't rescue: an @extern declaration, which is emitted verbatim so the linker can find it. Declaring one under a C-reserved name now fails fast at compile time instead of failing silently at link time.

  5. Fixed the GatOS build never copying the linked kernel binary to the project's build/ directory, and the ISO there being named after GRUB's internal staging name rather than the project. Both artifacts - <name>.iso and <name>.bin - are now copied out under the project's name, sanitized into a safe filename stem, with the CLI's summary line listing both.

  6. Gave every emitted thread entry a forward declaration alongside its definition, closing a latent "used before its declaration" gap in the generated C now that a launcher can reference a thread from earlier in the same translation unit.

Installation

For setting up Appa in your own machine, grab one of the following executables depending on the platform and run appa install:

  • Windows: appa-win.exe
  • Linux: appa-linux
  • MacOS on ARM (Apple Silicon): appa-amac
  • MacOS on Intel (Legacy x64): appa-imac

Appa v2.0.0 (Stable)

Choose a tag to compare

@ApparentlyPlus ApparentlyPlus released this 08 Aug 00:51

Appa, the Gata compiler, reaches its first stable release with the merge of branch next, plus the workflow and packaging fixes that landed on top of it.

This is a full release aimed at setting the baseline for things to come, and finalizing the Gata syntax. Below is the full changelog:

  • Rebuilt the command line as a laid-out program rather than a pile of Console.WriteLine calls. The new Fmt module measures visible width with SGR escapes counted as zero columns, so colored cells still align, and it provides greedy word wrap, padded two-column tables with hanging indents, and right-justified lines against the real terminal width clamped to a readable 48 to 96 columns. Piped output and CI logs fall back to a fixed 80 columns instead of throwing. Every block of help, diagnostics, and installer output now goes through it, so nothing in the tree is wrapped or padded by hand.

  • Gave Appa a proper help screen and command discovery. PrintHelp() renders commands, options, and examples as data through Fmt, the command list is generated from a single Commands() source so help and matching cannot drift apart, and a mistyped command now gets a "did you mean" suggestion instead of a bare failure.

  • Added a banner and logo with a gold-to-ember gradient. The cat art and the Appa wordmark are composed into a single lockup, vertically centered against each other, letterspaced so a short string reads as a masthead, and painted down a 32-step gradient in 24-bit color where the terminal advertises it and in the nearest of three xterm-256 golds where it does not. The same palette now drives the diagnostics gutter, which moved from blue to sand.

  • Rewrote spinners to report elapsed time. Steps are numbered as they run, each finished step prints with its duration pinned to the right edge, and downloads spin on a single line with live progress before collapsing into the same finished-step line as every other stage.

  • Turned appa install and appa update into a complete job. They fetch the cross-toolchain, libgata, the environments and the GatOS template, put Appa on PATH (re-running the whole install elevated through sudo or a UAC prompt when that is required), install the binary into its own directory, fix up permissions and ownership on Unix, and then offer to delete the copy you downloaded. On Windows the self-delete is deferred to a PowerShell fragment that runs after the process exits, since a running image can be neither deleted nor overwritten.

  • Made installer failures legible. Errors that are not the compiler's fault, network problems, permissions, missing tooling, are now identified as such and reported with what to do next, rather than surfacing as a stack trace.

  • Collapsed reserved local names from a generated-prefix table into one rule. IsReservedLocal was a frozen dictionary of twenty prefixes (_g, _res_, _catch_, _ixo and the rest) matched against digit suffixes; it is now simply "the name begins with __". Every compiler temporary in Ownership and TypeResolver was renamed to that prefix, which means one underscore belongs to the user again. The diagnostic changed accordingly and now suggests the single-underscore spelling of the name you tried to use.

  • Extended reserved-name checking to the places it was missing. Loop variables in both for-in shapes and match bindings are now checked against the reserved rule, which they previously slipped past entirely.

  • Made % overloadable. The modulo operator now parses as an overloadable operator name and mangles to mod, joining the arithmetic and comparison operators it had been left out of.

  • Fixed throws with no return type inventing an int. A throws declaration with no return type now produces nothing, exactly as throws void does, since the Result typedef the two share already folds void to int for its C name. assign inside a handler for such a call now reports that the call produces no value and points at giving the function a return type, instead of silently coercing.

  • Allowed multiple kernel and userspace blocks. A realm is one namespace however many blocks open it, across however many files, so structural validation now counts entry points rather than blocks and accepts the split as long as exactly one entry function exists between them.

  • Made the process deployment mode single-spelled. The mode is written before process and nowhere else; the trailing colon form is gone, and writing one now produces a targeted diagnostic showing the correct spelling rather than a generic header error.

  • Added diagnostic G057 for shadowed functions. A file-local private function that displaces the name of a public function in an imported file now warns once per name, with the owning module named, the qualified call spelling offered as an alternative, and a new @shadows annotation to declare the displacement deliberate. A stray @shadows on a function that shadows nothing is rejected. The code G057 was previously DuplicateRealm, which the multi-block change made obsolete.

  • Added CI on four runners: Linux, Windows, macOS arm64, and macOS Intel. Each builds and publishes its own native AOT executable and uploads it as an artifact, and the README carries a status badge per platform.

  • Hardened the test harness against toolchain variation across those runners. HostedRun now probes each C compiler once and caches the answers: whether -lm is needed or the math functions are already in the C runtime, and which -std= spelling it accepts, falling back from c23 to c2x and from c17 to c18 or c11 on compilers that predate the ratified names. This is what turned the math fidelity, portability, and union fuzz tests green on every runner rather than just the development machine.

  • Expanded test coverage substantially. New OperatorConsistencyTests and HardeningTests files, plus significant additions to MultiFileTests, InstallerTests, PipelineTests, CatchCallTests, and CliDiagnosticsTests, covering operator overloading, multi-file name resolution and shadowing, and the installer paths.

  • Added the project's public face: a 444-line README covering the vision, the compiler internals, getting started, project configuration, and a full CLI reference, a LICENSE, the Appa logo in SVG, and an application icon with proper product, company, and title metadata on the assembly.

  • Extracted the test harness TempDir into src/CLI/Scratch.cs so the compiler and its tests share one scratch directory implementation, and cleaned up stale comments and dead code left in Ownership, TypeResolver, and Parser, including a comment that had been spliced into the middle of a diagnostic string literal.

Installation

For setting up Appa in your own machine, grab one of the following executables depending on the platform and run appa install:

  • Windows: appa-win.exe
  • Linux: appa-linux
  • MacOS on ARM (Apple Silicon): appa-amac
  • MacOS on Intel (Legacy x64): appa-imac

Appa v1.0.0

Choose a tag to compare

@ApparentlyPlus ApparentlyPlus released this 04 Jul 16:35
Merge branch 'feat/cli'