Crates.io | impc |
lib.rs | impc |
version | 0.2.2 |
source | src |
created_at | 2024-04-20 14:31:14.359287 |
updated_at | 2024-05-10 16:45:50.064619 |
description | A compiler for the IMP programming language |
homepage | |
repository | https://github.com/eikopf/impc |
max_upload_size | |
id | 1214638 |
size | 103,538 |
impc
A compiler for the IMP programming language. Currently,
impc run <program>
will parse the given program and invoke a valid tree-walk interpreter; in this condition it is ready to use for the relatively simple task of executing IMP programs. The development focus has shifted to implementing a minimal optimising backend targeting LLVM, which should supersede the interpreter when feature-complete.
Assuming you have a Rust toolchain installed on your system (if not, follow these instructions), then impc
can be installed using cargo install
.
# from crates.io
cargo install impc
# from source
cargo install --git https://github.com/eikopf/impc.git
With impc
installed, run impc --help
and impc run --help
for the specific details of its usage. To run an IMP program, you can use the impc run <filename>
command and optionally provide explicit bindings with the --let
option if you want to avoid the interactive prompt stage.
IMP is, largely speaking, a deeply uninteresting language; its entire grammar can be given in a single 30-line ANTLR4 .g4
file (see below), and its semantics are incredibly simple.
In IMP,
while
and if
commands behave with the expected semantics.These properties admit the single interesting characteristic of IMP: it is can be aggressively optimised. In general, commands can be arbitrarily reordered so long as the order of assignment commands is preserved, and even then it can often be shown that arbitrary reorderings of assignment commands are valid (i.e. if they are disjoint). In more complex situations, these properties can be used to unroll, inline, or almost entirely erase while
and if
commands.
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 ;