Ada
Statically typed, with a Pascal-like skeleton but its own syntax (is ... begin ... end, procedure / function, loop ... exit when, 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 getPut_Line/Put/New_Linefor output (bound to this platform's print library, so no Ada toolchain is needed) - To draw or read input, write
with VML_UI;and callui_*and theVML_*constants directly (Lib/ada/vml_ui.adbregisters 183 function names and 175 constants) - 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
- ⚠
modandremland on the sameMODinstruction - the semantics on negative numbers are not promised (they agree on positives). - ⚠ Arrays are one-dimensional only; a multi-dimensional subscript is a compile error, not a silent mis-computation.
- ⚠ A
declareblock has no scope: declarations are hoisted, so same-named ones in different blocks overwrite each other. Floatis 32-bit (themathffamily); there is no fullLong_Float(64-bit double precision).- Records / variant records / generics / exceptions / tasks / packages (real semantics) / access types are not implemented (
package bodyis skipped leniently); thecasestatement andgotoare explicitly not done either. - Strings have pointer semantics:
S := "xy"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 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).
Version: v1.0 | Date: 2026-10-13 | Revised by: Shenzhen Tanso Intelligent Technology Co., Ltd.
Specification standard
| Field | Value |
|---|---|
| Target standard | Ada 83/95 subset |
| Publication year | 1983 |
| Completeness | Subset (not itemised) |
| 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 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 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 external functions and NAME : constant Integer := 123; as 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:
- Lexical: comments (
--to end of line), identifiers, integer literals (decimal and based16#FF#), floats, strings (escape is""), characters, operators — §0 - Compilation unit and library import:
with/use,Lib/ada/*.adbdeclaration files — §1, §7 - Declarations (between
isandbegin): subprograms, variables, constants, types and subtypes, arrays — §2 - Statements: assignment,
if/elsif/else,while/for(withreverse),exit/return,declareblocks — §3 - Expressions: Ada precedence (low to high) with comparison, logical and arithmetic operators — §4
- Builtins and attributes:
Put_Line/Put/New_Line,'Image/'Value/'Length/'First/'Last, the math library — §5 - Types and storage:
Integer/Float/Boolean/Character/String/ one-dimensional arrays and their register classes — §6 - 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/_; case-insensitive (the lexer lowercases before lookup) | |
| Integers | decimal (_ as separator) and based 16#FF# / 2#1010# | |
| Floats | 1.5 / 1.0E3 (1..5 is a range and is not mis-lexed) | |
| Strings | "…", escape is "" (no backslash escapes) | |
| Characters | 'A' (distinguished from the attribute apostrophe in X'Image) | |
| Operators | `+ - * / & = /= < > <= >= := => ** .. . , ; : ( ) ' | <> (<> means the same as /=`) |
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 mode comes after the name (X : out Integer, X : in out Integer). out / in out are passed 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
Where the value lands: integers / booleans / pointers in R0, 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 (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 | 32-bit IEEE | F0 |
Boolean | 0 / 1 | R0 |
Character | code point (an integer) | R0 |
String | 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/procedurenames in the declaration file become external functions: calling them emitsCALL <name>and lets the linker resolve it against the bodies pulled in byLib/ada/builtin.vml.NAME : constant Integer := 123;becomes a compile-time literal.- A missing
Lib/ada/<name>.adbis 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)
Path: VMLPrepares/AdaCompiler/ Extensions: .adb (also .ads / .ada) Status: 🟡 usable subset — full arithmetic + control flow + subprogram calls Library: Lib/ada/ (auto-linked builtin.vml + declaration file) 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) := …;(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 … endprocedure/function … return T, recursion, bare calls to parameterless subprograms,out/in outparameters (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 (
absminmaxsqrtsincostanexplog**), andwith VML_UI;⇒ui_*plusVML_*constants
Storage model (fixed; do not mix)
- Top-level variables → data-section slots (
ada_<name>): any subprogram can reach them by label. - Locals → stack frame (
R12-N), parameters →R12+(12+4i)(same as the other 27 frontends). - Arrays always live in the data section (
adaarr_<name>, zeroedint[]) — even local ones. - Strings are pointers to byte strings;
&writes into a fresh 2 KiB heap buffer viastrcpy+strcat.
Build / run (dev-time)
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)
modandremboth lower to the sameMODinstruction — negative-operand semantics are not promised. Multi-dimensional indexing reports an error (never silently wrong).declareblocks have no block scope (declarations are hoisted).Floatis 32-bit; no fullLong_Float. Records / tasks / exceptions / generics / real packages are not implemented. Strings are pointer-semantics.