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 := efor mutable variables. -
forloops -
for .. in ..loops -
whileloops
Description
We update CameLIGO's CST by adding the following nodes:
ELetMutInEAssignEForEForInEWhile
The lexer and parser are updated, adding the following keywords and symbols (thanks to @rinderkn for helping me out!):
mutforwhiledodonetodownto:=
The abstractors were trivially updated to support the extended CST.
Design notes:
-
We chose to support
let mutinstead 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 ein OCaml to encode this construct.
-
CameLIGO's parser levels (hierarchy) for expressions was updated to permit
x := 1, 2, 3to be parsed asx := (1, 2, 3)(as in OCaml). -
We added a
for .. inloop 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) xsHowever, 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_forconstruct.
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 @fmtto 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 ## Changelogsection 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).