Enable shorter JsLIGO syntax for nested record updates
Motivation and Context
Description
When a record p
contains a record a
which contains b
etc.
Updating a sub-sub-sub-field can be cumbersome, currently it goes like :
let p = {...p, a:{...p.a, b:{...p.a.b, c:"Before"}}};
A shorter but equivalent syntax is :
p.a.b.c = "After";
Which is already supported by the parser but rejected by abstractor.
This MR enable this new writing, abstracting it into an AST equivalent to the former writing.
Sanity check
As a first sanity check, the two writings :
let p = {...p, a:{...p.a, b:{...p.a.b, c:"Before"}}};
p.a.b.c = "After";
Give the same AST Imperative (ligo print ast-imperative ...
) :
let mut p = { p with a = { p.a with b = { p.a.b with c = "Before" } } }[@@private] in
{
p := { p with a = { p.a with b = { p.a.b with c = "After" } } };
...
}
Remaining work
This is still a draft, remaining work is :
-
Add tests, and find a test strategy to ensure the two writing are indeed equivalent -
Handle the Component
case (c.f. TODO in code) -
Handle the empty list case in path_acc_out
, i.e. make it a nelist (c.f. TODO in code) -
Handle the "impossible case" where sub-expression is neither EProj
norEVar
(c.f. TODO in code) -
Deal with locations proprely -
Deal with passing of attributes
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
For a contract with the new syntax for record update
type storage = int;
type parameter = int;
type user = {
id : int,
name : string
};
const user1 : user = {
id : 24,
name : "User1",
};
const main = (_action: parameter, store: storage) : [ list<operation> , storage ] => {
let p = user1;
p.id = 42; // Record field update
return [list([]), store]
};
Before
> ligo compile contract 'contract.jsligo'
File "contract.jsligo", line 17, characters 2-11:
16 | let p = user1;
17 | p.id = 42; // Record field update
18 | return [
Not supported assignment.
After
> ligo compile contract 'contract.jsligo'
{ parameter int ; storage int ; code { CDR ; NIL operation ; PAIR } }
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).
Edited by Nicolas Phan