diff --git a/src/passes/1-parser/reasonligo/Parser.mly b/src/passes/1-parser/reasonligo/Parser.mly index 14936a7ff..50e8670cd 100644 --- a/src/passes/1-parser/reasonligo/Parser.mly +++ b/src/passes/1-parser/reasonligo/Parser.mly @@ -689,6 +689,7 @@ common_expr: | "" { EBytes $1 } | "" | module_field { EVar $1 } | projection { EProj $1 } +| update_record { EUpdate $1 } | "" { EString (String $1) } | unit { EUnit $1 } | "false" { ELogic (BoolExpr (False $1)) } @@ -775,6 +776,25 @@ projection: field_path = snd $4} in {region; value} } +path : + "" {Name $1} +| projection { Path $1} + +update_record : + "{""..."path "," sep_or_term_list(field_assignment,",") "}" { + let region = cover $1 $6 in + let ne_elements, terminator = $5 in + let value = { + lbrace = $1; + record = $3; + kwd_with = $4; + updates = { value = {compound = Braces($1,$6); + ne_elements; + terminator}; + region = cover $4 $6}; + rbrace = $6} + in {region; value} } + sequence_or_record_in: expr ";" sep_or_term_list(expr,";") { let elts, _region = $3 in diff --git a/src/test/contracts/record.religo b/src/test/contracts/record.religo new file mode 100644 index 000000000..3c723de34 --- /dev/null +++ b/src/test/contracts/record.religo @@ -0,0 +1,53 @@ +type foobar = { + foo : int , + bar : int , +}; + +let fb : foobar = { + foo : 0 , + bar : 0 , +}; + +type abc = { + a : int , + b : int , + c : int +}; + +let abc : abc = { + a : 42 , + b : 142 , + c : 242 +}; + +let a : int = abc.a; +let b : int = abc.b; +let c : int = abc.c; + +let projection = (r : foobar) : int => r.foo + r.bar; + +let modify = (r : foobar) : foobar => {foo : 256, bar : r.bar}; + +let modify_abc = (r : abc) : abc => {...r,b : 2048 , c:42}; + +type big_record = { + a : int , + b : int , + c : int , + d : int , + e : int , +}; + +let br : big_record = { + a : 23 , + b : 23 , + c : 23 , + d : 23 , + e : 23 , +}; + +type double_record = { + inner : abc, +}; + +let modify_inner = (r : double_record) : double_record => {...r,inner : {...r.inner, b : 2048 } }; diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 26915dc4c..a3c3fe3cd 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -747,6 +747,52 @@ let record_mligo () : unit result = in ok () +let record_religo () : unit result = + let%bind program = retype_file "./contracts/record.religo" in + let%bind () = + let expected = record_ez_int ["foo" ; "bar"] 0 in + expect_eq_evaluate program "fb" expected + in + let%bind () = + let%bind () = expect_eq_evaluate program "a" (e_int 42) in + let%bind () = expect_eq_evaluate program "b" (e_int 142) in + let%bind () = expect_eq_evaluate program "c" (e_int 242) in + ok () + in + let%bind () = + let make_input = record_ez_int ["foo" ; "bar"] in + let make_expected = fun n -> e_int (2 * n) in + expect_eq_n program "projection" make_input make_expected + in + let%bind () = + let make_input = record_ez_int ["foo" ; "bar"] in + let make_expected = fun n -> ez_e_record [("foo" , e_int 256) ; ("bar" , e_int n) ] in + expect_eq_n program "modify" make_input make_expected + in + let%bind () = + let make_input = record_ez_int ["a" ; "b" ; "c"] in + let make_expected = fun n -> ez_e_record [ + ("a" , e_int n) ; + ("b" , e_int 2048) ; + ("c" , e_int 42) + ] in + expect_eq_n program "modify_abc" make_input make_expected + in + let%bind () = + let expected = record_ez_int ["a";"b";"c";"d";"e"] 23 in + expect_eq_evaluate program "br" expected + in + let%bind () = + let make_input = fun n -> ez_e_record [("inner", record_ez_int ["a";"b";"c"] n)] in + let make_expected = fun n -> ez_e_record [("inner", ez_e_record[ + ("a" , e_int n) ; + ("b" , e_int 2048) ; + ("c" , e_int n) + ])] in + expect_eq_n program "modify_inner" make_input make_expected + in + ok () + let tuple () : unit result = let%bind program = type_file "./contracts/tuple.ligo" in let ez n = @@ -1967,7 +2013,8 @@ let main = test_suite "Integration (End to End)" [ test "tuple (mligo)" tuple_mligo ; test "tuple (religo)" tuple_religo ; test "record" record ; - test "record" record_mligo ; + test "record (mligo)" record_mligo ; + test "record (religo)" record_religo ; test "condition simple" condition_simple ; test "condition (ligo)" condition ; test "condition (mligo)" condition_mligo ;