CameLIGO: Add `mut`ability , `for` loops, and `while` loops
Motivation and Context
This is part of the ongoing work to improve CameLIGO's support for mutable programs.
This MR aims to implement add:
- a
let mut
(a la Rust) construct and an assignment operatorx := e
for mutable variables. -
for
loops -
for .. in ..
loops -
while
loops
Description
We update CameLIGO's CST
by adding the following nodes:
ELetMutIn
EAssign
EFor
EForIn
EWhile
The lexer and parser are updated, adding the following keywords and symbols (thanks to @rinderkn for helping me out!):
mut
for
while
do
done
to
downto
:=
The abstractors were trivially updated to support the extended CST
.
Design notes:
-
We chose to support
let mut
instead oflet x = ref 0 in ...
for the following reasons:- Users from OCaml will not confuse (second class) mutable variables with first class references (which OCaml provides)
- Transpilation from OCaml is not too poorly affected by this choice. Since we can use
let%mut x = e in e
in OCaml to encode this construct.
-
CameLIGO's parser levels (hierarchy) for expressions was updated to permit
x := 1, 2, 3
to be parsed asx := (1, 2, 3)
(as in OCaml). -
We added a
for .. in
loop to support iteration over collections without the restriction on mutability becoming an issue to users.For example, the following wouldn't typecheck (since the anonymous function captures the mutable variable
i
):let iteri f xs = let mut i = 0 in List.iter (fun x -> begin f i x; i := i + 1 end) xs
However, the following does typecheck:
let iteri f xs = let mut i = 0 in for x in xs do f i x; i := i + 1 done
-
downto
-loops are currently unsupported (raises an error in the abstractor). This is because negative increments are incorrectly compiled in ourE_for
construct.
Types of changes
-
Bug fix (non-breaking change which fixes an issue) -
New feature (non-breaking change which adds functionality) -
Breaking change (fix or feature that would cause existing functionality to not work as expected) -
Performance improvement (non-breaking change that improves performance) -
None (change with no changelog)
Changelog
Add mutable variables, the assignment operator, for
loops, and while
loops to CameLIGO.
let do_something g n =
let mut x = 1 in
for j = 1 to n do
while x < 10 do
x := g i j x;
done
end;
x
Checklist:
-
Changes follow the existing coding style (use dune @fmt
to check). -
Tests for the changes have been added (for bug fixes / feature). -
Documentation has been updated. -
Changelog description has been added (if appropriate). -
Start titles under ## Changelog
section with #### (if appropriate). -
There is no image or uploaded file in changelog -
Examples in changed behaviour have been added to the changelog (for breaking change / feature).