4个版本
0.2.2 | 2024年5月10日 |
---|---|
0.2.1 | 2024年4月20日 |
0.1.1 | 2024年4月20日 |
0.1.0 | 2024年4月20日 |
#54 在 编程语言
192 每月下载量
91KB
2K SLoC
impc
IMP编程语言的编译器。目前,
impc run <program>
将解析给定的程序并调用有效的树遍历解释器;在这种情况下,它已经准备好用于执行IMP程序的相对简单任务。开发重点已经转移到实现一个针对LLVM的最小优化后端,这将取代解释器,当功能完全时。
安装和使用
假设您已在系统上安装了Rust工具链(如果没有,请遵循这些说明),那么可以使用 impc
来安装,使用 cargo install
。
# from crates.io
cargo install impc
# from source
cargo install --git https://github.com/eikopf/impc.git
安装了 impc
后,运行 impc --help
和 impc run --help
以获取其使用细节。要运行IMP程序,可以使用 impc run <filename>
命令,如果需要,可以使用 --let
选项显式提供绑定以避免交互式提示阶段。
IMP
从很大程度上说,IMP是一种非常无趣的语言;它的整个语法可以放在一个30行的ANTLR4 .g4
文件中(见下文),其语义非常简单。
在IMP中,
- 所有变量总是处于作用域内,并且在执行之前必须具有已绑定值;
- 算术表达式使用无符号整数语义进行评估,但减法饱和在0;
- 算术表达式始终定义,因此整数溢出是未定义行为;
- 由于整数溢出是UB并且整数没有指定的位宽,因此严格正确的实现应该使用任意精度整数,除非它可以证明某些固定宽度的类型不会发生溢出;
- 布尔表达式具有普通布尔语义;
- 布尔和算术表达式不定义评估顺序,因为它们不能产生副作用;
- 命令按顺序执行,只有赋值命令可以产生副作用(即值绑定);
while
和if
命令的行为符合预期的语义。
这些属性允许IMP具有一个有趣的特性:它可以被积极优化。一般来说,只要保持赋值命令的顺序,命令可以任意重新排序,并且有时可以证明赋值命令的任意重新排序都是有效的(即,如果它们是互斥的)。在更复杂的情况下,这些属性可以用来展开、内联或几乎完全删除 while
和 if
命令。
grammar IMP;
aexp : INT #Atom
| VAR #Variable
| '(' inner=aexp ')' #Brackets
| left=aexp '*' right=aexp #Mult
| left=aexp '+' right=aexp #Add
| left=aexp '-' right=aexp #Sub
;
bexp : 'true' #True
| 'false' #False
| left=aexp '=' right=aexp #Equal
| left=aexp '<' right=aexp #Smaller
| left=aexp '>' right=aexp #Greater
| left=aexp '<>' right=aexp #Inequality
| 'not' inner=bexp #Not
| '(' left=bexp 'and' right=bexp ')' #And
| '(' left=bexp 'or' right=bexp ')' #Or
;
cmd : 'skip' #Skip
| variable=VAR ':=' expression=aexp #Assignment
| first=cmd ';' second=cmd #Sequence
| 'if' condition=bexp 'then' truecase=cmd 'else' falsecase=cmd 'fi' #If
| 'while' condition=bexp 'do' body=cmd 'od' #While
;
VAR : [a-zA-Z][a-zA-Z0-9_]* ;
INT : [0-9]+ ;
WS : [ \r\n\t] -> skip ;
依赖关系
~6-14MB
~188K SLoC