← 都来码← 文档索引Ada原文English

Ada

静态强类型,骨架像 Pascal 但语法独立(is … begin … end、procedure / function、loop … exit when、一基数组)。

「完整运算 + 控制流 + 函数调用」三件齐备,能写一般小程序;引 with VML_UI; 之后 ui_* 与 VML_* 常量直接可用。

在手机上怎么跑

vml run examples/ada/fizzbuzz.adb

编译要等一会儿(C 那种要一两分钟,脚本类语言几秒)。程序跑起来后屏幕底部就是手柄,方向键 + 四个动作键都在;点右上角返回可以回到命令行。

写法要点

示例

文件演示什么
fizzbuzz.adbFizzBuzz(for + if/elsif/else + mod)
hello.adb最小程序(声明区 + Put_Line + 字符串并置)
primes.adb素数筛(一基数组 + function / procedure)

实测踩过的坑


下面的内容是从 VML 源码里直接带的(third_party/vml/VMLPrepares/AdaCompiler/): README 讲这个前端支持什么、怎么编;语言规范 讲语法本身。上游一改,这里重新生成就是最新的。

语言规范

Ada 子集语言规范

本文件描述的是本前端实际接受的语法子集,不是 Ada 2012 标准。判据是 scripts/vml-ada-probe/run.sh(14 条用例,全部要能红)。

版本:v1.0 | 日期:2026-10-13 | 修订者:深圳市探索智能科技有限公司

规范标准

字段值
目标标准Ada 83/95 子集
发布年份1983
完成度子集(未逐项统计)
测试14 通过 / 0 失败

关键字

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

概述

支持 Ada 83/95 子集,编译为 VML 汇编代码。词法器把标识符统一规范成小写(Ada 名称大小写不敏感,凡按名字查表/比对的地方因此天然一致),之后走「词法 → 递归下降解析 → 代码生成」三段流水线;with / use 只做语法接受,I/O 绑到本平台的 print_str / print_int / print_float / newline,库导入读 Lib/ada/<名>.adb 声明文件:function / procedure 后面的名字登记为外部函数,NAME : constant Integer := 123; 当编译期字面量。

支持的语言特性

本前端接受的语言特性按下方原有章节组织,每节都写明「收什么写法、是什么语义」:

详见下方各节。

0. 词法

元素规则
注释-- 到行尾(没有块注释)
标识符字母/下划线开头,字母/数字/下划线续;大小写不敏感(词法器统一规范成小写再查表)
整数字面量十进制(_ 作分隔符)、带基数 16#FF# / 2#1010#
浮点字面量1.5 / 1.0E3(1..5 是区间,不会误读)
字符串"…",转义是 ""(没有反斜杠转义)
字符'A'(属性引用的撇号 X'Image 与它按"后跟一个字符再跟一个撇号"区分)
运算符`+ - * / & = /= < > <= >= := => ** .. . , ; : ( ) '<>(<> 与 /=` 同义)

关键字: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. 编译单元

[with <名>;]*            -- 库导入(见 §7)
[use <名>;]*             -- 只做语法接受
procedure Main is
   <声明区>
begin
   <语句序列>
end Main;

procedure X is null; 也可以(空程序)。

2. 声明(在 is 与 begin 之间)

X : Integer;                       -- 变量(默认值 = 0 / 空串 / false)
X : Integer := 10;                 -- 带初值
A, B : Integer;                    -- 一条声明多个名字
K : constant Integer := 5;         -- 常量(本子集当普通变量处理)

type T is array (1 .. 5) of Integer;   -- 一维数组类型(**一基**)
type U is array (0 .. 9) of Float;

procedure P(A : Integer; B : out Integer) is <声明区> begin <语句> end P;
function  F(A : Integer) return Integer is <声明区> begin <语句> end F;

形参模式写在名字之后(Ada 的写法):X : out Integer / X : in out Integer。 out / in out 按引用传递(形参槽里是调用方变量的地址);实参必须是变量或数组元素。

3. 语句

X := <表达式>;                 -- 赋值(目标可以是变量或数组元素 A(i))
A(i) := <表达式>;
P(<实参>);                     -- 过程调用(无参过程写 `P;`)
P;                             -- 无参过程调用
if <条件> then … elsif <条件> then … else … end if;
while <条件> loop … end loop;
for I in <下界> .. <上界> loop … end loop;
for I in reverse <下界> .. <上界> loop … end loop;
loop … exit when <条件>; … end loop;     -- 也支持裸 `exit;`
exit when <条件>;              -- 只能出现在循环里(否则报错)
return;                        -- 过程
return <表达式>;               -- 函数
null;                          -- 空语句
declare <声明区> begin <语句序列> end;   -- 声明**就地提升**(不做块作用域)

4. 表达式(Ada 优先级,从低到高)

or  xor                       -- 最低
and
=  /=  <  >  <=  >=  <>       -- 关系
+  -  &                       -- 加减与字符串并置(`&` 是并置)
not  -  +  abs                -- 一元
*  /  mod  rem                -- 乘除
**                            -- 幂(右结合)

求值结果落在哪里:整数/布尔/指针在 R0,浮点在 F0(与库函数的返回约定一致)。

类型规则:

5. 内建函数与属性

形式语义
Put_Line(X) / Put(X) / New_Line输出(字符串→print_str、整数→print_int、浮点→print_float),Put_Line 末尾补换行
Integer'Image(X) / Float'Image(X)数值转字符串(int_to_str / float_to_str)
Integer'Value(S) / Float'Value(S)字符串转数值
S'Length字符串长度(strlen);数组则给元素个数
A'Length / A'First / A'Last数组的元素数 / 下界 / 上界(编译期常量)
Character'Pos(C) / Character'Val(N)字符 ↔ 码位(恒等,本子集里字符就是整数)
abs(x) / min(a,b) / max(a,b)共享数学库(整型与浮点各一套)
sqrt/sin/cos/tan/exp/log(x)Lib/shared/mathf.vml(32 位浮点)
pow(x,y) / x «bold» y浮点幂;整数 «/» 走 ipow
Integer(x) / Float(x)显式转换(自动插 I2F/F2I)
strlen(s) / int_to_str(x) / float_to_str(x) / str_to_int(s) / str_to_float(s)直接调共享库

6. 类型与存储

Ada 类型表示寄存器类
Integer / Natural / Positive32 位有符号R0
Float32 位 IEEEF0
Boolean0 / 1R0
Character码位(整数)R0
String指向字节串的指针(不是值)R0
一维数组数据段里连续 4 字节元素地址在 R0/R1

7. 库导入

with VML_UI;      -- ⇒ 读 Lib/ada/vml_ui.adb,登记 ui_* 函数名与 VML_* 常量

8. 未实现(明确不做)

记录/变体记录 / 任务与保护对象 / 异常 / 泛型 / 包(真语义)/ 访问类型与指针 / 多维数组 / Long_Float Long_Integer 的完整支持 / 重载与命名实参 / case 语句 / goto。

编译器 README

Ada 编译器(子集)

路径: VMLPrepares/AdaCompiler/ 扩展名: .adb(另收 .ads / .ada) 状态: 🟡 子集可用 —— 「完整运算 + 控制流 + 函数调用」齐备,能写一般小程序 库: Lib/ada/(builtin.vml 自动链接表 + 声明文件) 判据: scripts/vml-ada-probe/run.sh(用例在 bugs/vml_ada_bugs/)

为什么要它

本仓加一门语言的判据是「完整运算 + 控制流 + 函数调用才算语言」——不做「只能跑 hello」的壳。 Ada 是本仓没有的一门静态强类型、类 Pascal 骨架、但语法独立的语言(is … begin … end、 procedure/function、loop/exit when、with/use、一基数组、'Image 属性)。

结构(9 个源文件,继承基类,不另起炉灶)

文件作用
TokenType.cs词法单元类型 + Token(实现 ITokenPosition)
Lexer.cs继承 LexerBase:-- 注释、字符串("" 转义)、字符字面量 'c'、带基数字面量 16#FF#、Ada 运算符
ASTNode.csAST(声明 / 语句 / 表达式)
Parser.cs继承 ParserBase<Token,TokenType>:编译单元、声明区、语句、Ada 优先级的表达式
CodeGenerator.cs继承 CodeGeneratorBase:存储模型 + 表达式/语句/子程序/数组/字符串/浮点代码生成
AdaCompiler.cs静态 Compile / CompileFile / CompileFileWithIncludes + with X; 声明文件加载
AdaPlugin.cs派生 CompilerPluginExBase(Name/Description/SupportedExtensions/三个 Func)
AdaCompiler.csprojOutputType=Exe(开发期自带 Main;见 csproj 里的注释)
Program.csSimpleCompilerProgram("ada", "VML_ADA_LIB", …)

覆盖的语法(实测通过)

存储模型(本子集定死,别混用)

输出与库绑定

Ada.Text_IO 不依赖 GPL 工具链:Put_Line/Put/New_Line 直接绑到本平台的 print_str/print_int/print_float/newline(Lib/shared/builtins.vml)。

with X; 是本子集的库导入:它指向 Lib/ada/<小写名>.adb 声明文件,里面的 function/procedure 名与 NAME : constant Integer := 1; 常量被登记给代码生成器(函数名 → 外部 CALL,由链接器解析;常量 → 编译期字面量)。已经提供 Lib/ada/vml_ui.adb(183 个 ui_* + 175 个常量)。

编译/运行(开发期)

# ① 编 AdaCompiler(本工程是 Exe,自带 Main)
dotnet build third_party/vml/VMLPrepares/AdaCompiler/AdaCompiler.csproj -c Release

# ② 产 .vml(VML_HOME 必须指向 third_party/vml,否则找不到 Lib/ada/*.vml)
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

# ③ 汇编 + 链接 + 运行(vmlcli 认 `.vml` = 已经是汇编)
dotnet ../scripts/vmlcli/bin/Release/net10.0/vmlcli.dll /tmp/hello.vml

接线(把 Ada 并进 27 门那张注册表)见 [INTEGRATION.md](INTEGRATION.md)。

已知限制(明确报错或有意不做,不是悄悄错)