# Ada

«bold»Statically typed«/», with a Pascal-like skeleton but its own syntax (`is ... begin ... end`, `procedure` / `function`, `loop ... exit when`, «bold»1-based arrays«/»).

Arithmetic, control flow and function calls are all there, so a normal small program is within reach; after `with VML_UI;` the `ui_*` calls and `VML_*` constants are available directly.

## How to run it on your phone

```
vml run examples/ada/fizzbuzz.adb
```

Compiling takes a while (one to two minutes for C, a few seconds for scripting languages).
Once the program is running, **the gamepad is at the bottom of the screen** - the D-pad
and the four action buttons are all there. Tap the back arrow in the top-right corner to
return to the Shell.

## What to know before you write

- After `with Ada.Text_IO; use Ada.Text_IO;` you get `Put_Line` / `Put` / `New_Line` for output (bound to this platform's print library, so «bold»no Ada toolchain is needed«/»)
- To draw or read input, write `with VML_UI;` and call `ui_*` and the `VML_*` constants directly (`Lib/ada/vml_ui.adb` registers 183 function names and 175 constants)
- «bold»Array indices are 1-based«/»: `A(1)` is the first element
- Turn a number into a string with `Integer'Image(X)` / `Float'Image(X)`; join strings with `&`

## Examples

| File | What it shows |
|---|---|
| `fizzbuzz.adb` | FizzBuzz (`for` plus `if/elsif/else` plus `mod`) |
| `hello.adb` | The smallest program (declaration part, `Put_Line`, string concatenation) |
| `primes.adb` | A prime sieve (1-based array plus `function` / `procedure`) |

## Pitfalls we hit on real devices

- ⚠ «bold»`mod` and `rem` land on the same `MOD` instruction«/» - the semantics on «bold»negative numbers are not promised«/» (they agree on positives).
- ⚠ Arrays are «bold»one-dimensional only«/»; a multi-dimensional subscript is a «bold»compile error«/», not a silent mis-computation.
- ⚠ «bold»A `declare` block has no scope«/»: declarations are hoisted, so same-named ones in different blocks overwrite each other.
- `Float` is «bold»32-bit«/» (the `mathf` family); there is no full `Long_Float` (64-bit double precision).
- «bold»Records / variant records / generics / exceptions / tasks / packages (real semantics) / access types«/» are not implemented (`package body` is skipped leniently); the `case` statement and `goto` are explicitly not done either.
- Strings have «bold»pointer semantics«/»: `S := "xy"` «bold»re-points«/» the variable instead of overwriting it in place.

---

The rest of this page is taken straight from the VML source (`third_party/vml/VMLPrepares/AdaCompiler/`):
the `README` covers what this front end supports and how to compile it, and the
language reference covers the syntax itself. When upstream changes, regenerating
this page brings it up to date.

## Language reference

### Ada subset — language specification

> This documents the «bold»subset the frontend actually accepts«/», not the Ada 2012 standard.
> The judges are `scripts/vml-ada-probe/run.sh` (14 cases, all of them able to go red).

> «bold»Version«/»: v1.0 | «bold»Date«/»: 2026-10-13 | «bold»Revised by«/»: Shenzhen Tanso Intelligent Technology Co., Ltd.

#### Specification standard

| Field | Value |
|:-----|:----|
| «bold»Target standard«/» | Ada 83/95 subset |
| «bold»Publication year«/» | 1983 |
| «bold»Completeness«/» | Subset (not itemised) |
| «bold»Tests«/» | 14 passing / 0 failing |

#### Keywords

`procedure` `function` `is` `begin` `end` `if` `then` `elsif` `else` `while`
`loop` `for` `in` `reverse` `return` `declare` `type` `subtype` `array` `of`
`null` `and` `or` `not` `xor` `mod` `rem` `exit` `when` `with` `use` `range`
`others` `abs` `constant` `out` `true` `false` `all` `renames` `package` `body`
`pragma`

#### Overview
A subset of Ada 83/95 is supported, compiled to VML assembly. The lexer «bold»lower-cases every identifier«/» (Ada names are case-insensitive, so every table lookup and comparison agrees by construction), and the pipeline is lexer → recursive-descent parser → code generator. `with` / `use` are accepted «bold»syntactically only«/»; I/O is bound to the platform's `print_str` / `print_int` / `print_float` / `newline`; library imports read `Lib/ada/<name>.adb` declaration files, registering the names after `function` / `procedure` as «bold»external functions«/» and `NAME : constant Integer := 123;` as «bold»compile-time literals«/».

#### Supported language features

The features this frontend accepts are organised by the sections below; each one states what is accepted and what it means:

- «bold»Lexical«/»: comments (`--` to end of line), identifiers, integer literals (decimal and based `16#FF#`), floats, strings (escape is `""`), characters, operators — §0
- «bold»Compilation unit and library import«/»: `with` / `use`, `Lib/ada/*.adb` declaration files — §1, §7
- «bold»Declarations«/» (between `is` and `begin`): subprograms, variables, constants, types and subtypes, arrays — §2
- «bold»Statements«/»: assignment, `if` / `elsif` / `else`, `while` / `for` (with `reverse`), `exit` / `return`, `declare` blocks — §3
- «bold»Expressions«/»: Ada precedence (low to high) with comparison, logical and arithmetic operators — §4
- «bold»Builtins and attributes«/»: `Put_Line` / `Put` / `New_Line`, `'Image` / `'Value` / `'Length` / `'First` / `'Last`, the math library — §5
- «bold»Types and storage«/»: `Integer` / `Float` / `Boolean` / `Character` / `String` / one-dimensional arrays and their register classes — §6
- «bold»Deliberately not done«/»: records, generics, exceptions, tasks, access types, `case`, `goto` — §8

See the sections below for details.

#### 0. Lexical

| Element | Rule |
|---|---|
| Comments | `--` to end of line (no block comments) |
| Identifiers | letter/`_` then letter/digit/`_`; «bold»case-insensitive«/» (the lexer lowercases before lookup) |
| Integers | decimal (`_` as separator) and «bold»based«/» `16#FF#` / `2#1010#` |
| Floats | `1.5` / `1.0E3` (`1..5` is a range and is not mis-lexed) |
| Strings | `"…"`, «bold»escape is `""`«/» (no backslash escapes) |
| Characters | `'A'` (distinguished from the attribute apostrophe in `X'Image`) |
| Operators | `+ - * / & = /= < > <= >= := => ** .. . , ; : ( ) ' | <>` (`<>` means the same as `/=`)

«bold»Keywords«/»: `procedure function is begin end if then elsif else while loop for in reverse return
declare type subtype array of null and or not xor mod rem exit when with use range others abs
constant out true false all renames package body pragma`

#### 1. Compilation unit

```
[with <name>;]*            -- library import, see §7
[use <name>;]*             -- accepted, no semantic effect
procedure Main is
   <declarative part>
begin
   <statement sequence>
end Main;
```

`procedure X is null;` (an empty program) is also accepted.

#### 2. Declarations (between `is` and `begin`)

```
X : Integer;                       -- defaults to 0 / empty string / false
X : Integer := 10;
A, B : Integer;
K : constant Integer := 5;         -- treated as an ordinary variable

type T is array (1 .. 5) of Integer;    -- 1-D, **1-based**
type U is array (0 .. 9) of Float;

procedure P(A : Integer; B : out Integer) is <decl> begin <stmts> end P;
function  F(A : Integer) return Integer is <decl> begin <stmts> end F;
```

The parameter «bold»mode comes after the name«/» (`X : out Integer`, `X : in out Integer`).
`out` / `in out` are passed «bold»by reference«/» (the parameter slot holds the caller's variable address);
the argument must be a variable or an array element.

#### 3. Statements

```
X := <expr>;                   -- target may be a variable or an array element A(i)
A(i) := <expr>;
P(<args>);  P;                 -- procedure call (parameterless form has no parens)
if <cond> then … elsif <cond> then … else … end if;
while <cond> loop … end loop;
for I in <lo> .. <hi> loop … end loop;
for I in reverse <lo> .. <hi> loop … end loop;
loop … exit when <cond>; … end loop;   -- bare `exit;` too
exit when <cond>;              -- only inside a loop (otherwise an error)
return;  return <expr>;
null;
declare <decl> begin <stmts> end;   -- declarations are **hoisted** (no block scope)
```

#### 4. Expressions (Ada precedence, low → high)

```
or  xor
and
=  /=  <  >  <=  >=  <>
+  -  &                       -- `&` is concatenation
not  -  +  abs                -- unary
*  /  mod  rem
**                            -- right-associative
```

«bold»Where the value lands«/»: integers / booleans / pointers in `R0`, «bold»floats in `F0`«/»
(matching the library return convention).

Type rules: either side `Float` ⇒ the whole expression is 32-bit float (the other side is `I2F`'d);
`=`/`/=` on strings goes through `strcmp`; `and or xor` normalise both sides to 0/1;
`&` always concatenates strings into a fresh 2 KiB heap buffer.

#### 5. Built-ins and attributes

| Form | Meaning |
|---|---|
| `Put_Line(X)` / `Put(X)` / `New_Line` | output (`print_str` / `print_int` / `print_float`); `Put_Line` appends a newline |
| `Integer'Image(X)` / `Float'Image(X)` | number → string |
| `Integer'Value(S)` / `Float'Value(S)` | string → number |
| `S'Length` | string length (`strlen`); element count for arrays |
| `A'Length` / `A'First` / `A'Last` | element count / lower bound / upper bound (compile-time constants) |
| `Character'Pos(C)` / `Character'Val(N)` | identity in this subset (a character is an integer) |
| `abs` / `min` / `max` | shared math library (integer and float variants) |
| `sqrt sin cos tan exp log` | `Lib/shared/mathf.vml` («bold»32-bit float«/») |
| `pow(x,y)` / `x «bold» y` | float power; integer `«/»` uses `ipow` |
| `Integer(x)` / `Float(x)` | explicit conversions (inserts `I2F`/`F2I`) |
| `strlen` `int_to_str` `float_to_str` `str_to_int` `str_to_float` | direct shared-library calls |

#### 6. Types and storage

| Ada type | Representation | Register class |
|---|---|---|
| `Integer` / `Natural` / `Positive` | 32-bit signed | `R0` |
| `Float` | «bold»32-bit IEEE«/» | `F0` |
| `Boolean` | 0 / 1 | `R0` |
| `Character` | code point (an integer) | `R0` |
| `String` | «bold»pointer to bytes«/» (not a value) | `R0` |
| 1-D arrays | consecutive 4-byte elements in the data section | address in `R0`/`R1` |

#### 7. Library import

```
with VML_UI;      -- loads Lib/ada/vml_ui.adb; registers ui_* names and VML_* constants
```

- `function` / `procedure` names in the declaration file become «bold»external functions«/»: calling them
  emits `CALL <name>` and lets the «bold»linker«/» resolve it against the bodies pulled in by
  `Lib/ada/builtin.vml`.
- `NAME : constant Integer := 123;` becomes a «bold»compile-time literal«/».
- A missing `Lib/ada/<name>.adb` is «bold»not an error«/» (`with Ada.Text_IO;` has no such file by design).
- Dotted names (`with Ada.Text_IO;`) are not treated as library imports.

#### 8. Not implemented

Records / variant records / tasks / protected objects / exceptions / generics / real packages /
access types / multi-dimensional arrays / full `Long_Float` & `Long_Integer` /
overloading and named association / `case` statements / `goto`.

## Compiler README

### Ada compiler (subset)

«bold»Path«/»: `VMLPrepares/AdaCompiler/`
«bold»Extensions«/»: `.adb` (also `.ads` / `.ada`)
«bold»Status«/»: 🟡 usable subset — full arithmetic + control flow + subprogram calls
«bold»Library«/»: `Lib/ada/` (auto-linked `builtin.vml` + declaration file)
«bold»Judges«/»: `scripts/vml-ada-probe/run.sh` (cases in `bugs/vml_ada_bugs/`)

#### Why

This repo's bar for "a language" is *complete arithmetic + control flow + subprogram calls* —
not a hello-world shell. Ada is a statically typed language with a Pascal-like skeleton but its
own grammar (`is … begin … end`, `procedure`/`function`, `loop`/`exit when`, `with`/`use`,
1-based arrays, `'Image` attributes).

#### Layout (9 sources, built on the shared base classes)

| File | Role |
|---|---|
| `TokenType.cs` | token kinds + `Token` (implements `ITokenPosition`) |
| `Lexer.cs` | extends `LexerBase`: `--` comments, `"…"` strings (`""` escape), `'c'` char literals, based literals `16#FF#` |
| `ASTNode.cs` | AST |
| `Parser.cs` | extends `ParserBase<Token,TokenType>` |
| `CodeGenerator.cs` | extends `CodeGeneratorBase` |
| `AdaCompiler.cs` | static `Compile` / `CompileFile` / `CompileFileWithIncludes` + `with X;` declaration loading |
| `AdaPlugin.cs` | extends `CompilerPluginExBase` |
| `AdaCompiler.csproj` | `OutputType=Exe` (dev-time `Main`) |
| `Program.cs` | `SimpleCompilerProgram("ada", "VML_ADA_LIB", …)` |

#### Covered syntax (verified by the probe suite)

- Skeleton `procedure Main is … begin … end Main;`, `with Ada.Text_IO; use Ada.Text_IO;`
- Declarations, `X := …;`, `A(i) := …;` («bold»1-based«/» indexing)
- `+ - * / mod rem **`, `= /= < > <= >=`, `and or not xor`, string concatenation `&`
- `if/elsif/else`, `while … loop`, `for I in 1 .. 10 loop` (incl. `in reverse`), `loop … exit when …`,
  `declare … begin … end`
- `procedure` / `function … return T`, recursion, bare calls to parameterless subprograms,
  «bold»`out` / `in out` parameters (by reference)«/»
- Types: `Integer` / `Float` (32-bit) / `Boolean` / `Character` / `String` (pointer) / 1-D arrays
- Output: `Put_Line` / `Put` / `New_Line`, `Integer'Image`, `Float'Image`, `Integer'Value`,
  `S'Length`, `A'Length` / `A'First` / `A'Last`, `Character'Pos` / `Character'Val`
- Libraries: string ops, math (`abs` `min` `max` `sqrt` `sin` `cos` `tan` `exp` `log` `**`),
  and `with VML_UI;` ⇒ `ui_*` plus `VML_*` constants

#### Storage model (fixed; do not mix)

- «bold»Top-level variables → data-section slots«/» (`ada_<name>`): any subprogram can reach them by label.
- «bold»Locals → stack frame«/» (`R12-N`), «bold»parameters → `R12+(12+4i)`«/» (same as the other 27 frontends).
- «bold»Arrays always live in the data section«/» (`adaarr_<name>`, zeroed `int[]`) — even local ones.
- «bold»Strings are pointers to byte strings«/»; `&` writes into a fresh 2 KiB heap buffer via `strcpy`+`strcat`.

#### Build / run (dev-time)

```bash
dotnet build third_party/vml/VMLPrepares/AdaCompiler/AdaCompiler.csproj -c Release
cd third_party/vml && export VML_HOME="$PWD"
dotnet VMLPrepares/AdaCompiler/bin/Release/net10.0/AdaCompiler.dll Examples/ada/hello.adb -o /tmp/hello.vml
dotnet ../scripts/vmlcli/bin/Release/net10.0/vmlcli.dll /tmp/hello.vml
```

Wiring Ada into the shared 27-language registry: see [`INTEGRATION.md`](INTEGRATION.md).

#### Known limits (either reported as errors or deliberately absent)

- `mod` and `rem` both lower to the same `MOD` instruction — negative-operand semantics are «bold»not«/»
  promised. Multi-dimensional indexing reports an «bold»error«/» (never silently wrong).
- `declare` blocks have «bold»no block scope«/» (declarations are hoisted).
- `Float` is «bold»32-bit«/»; no full `Long_Float`. Records / tasks / exceptions / generics / real
  packages are not implemented. Strings are pointer-semantics.
