diff --git a/lib/parser.mly b/lib/parser.mly index 67b59f3b..8d2f0eb4 100644 --- a/lib/parser.mly +++ b/lib/parser.mly @@ -404,7 +404,7 @@ sexp_cond: { Lambda ($loc, params, body) } %inline sexp_field_set: - | Set; Ampersand; var = sexp_expr; value = sexp_expr + | Set; Ampersand; var = sexp_expr; Exclamation; value = sexp_expr { Set ($loc, ($loc(var), var), value) } %inline sexp_field_get: diff --git a/lib/syntax_errors.messages b/lib/syntax_errors.messages index 84b981f5..ab063af3 100644 --- a/lib/syntax_errors.messages +++ b/lib/syntax_errors.messages @@ -80,9 +80,13 @@ prog: Lbrack False Rpar prog: Lpar Set Ampersand False Wildcard +Expecting '!' to indicate move of to-set expression + +prog: Lpar Set Ampersand False Exclamation Wildcard + -prog: Lpar Set Ampersand False False Wildcard +prog: Lpar Set Ampersand False Exclamation False Wildcard diff --git a/std/hashtbl.smu b/std/hashtbl.smu index bf738b7e..8ede697e 100644 --- a/std/hashtbl.smu +++ b/std/hashtbl.smu @@ -92,16 +92,16 @@ (prelude/iter-range 0 size (fn [i] (__unsafe_ptr_set &(array/data data) i !#empty))) (def old-data& !tbl.data) - (set &tbl.data data) - (set &tbl.nitems 0) + (set &tbl.data !data) + (set &tbl.nitems !0) (iter-data-move &old-data (fn [key! value!] (insert &tbl !key !value)))) (defn insert [tbl& key! value!] (if (>. (load-factor tbl) load-limit) (grow &tbl)) (let [idx (probe-linear tbl key true)] - (set &tbl.data.[idx] (#item {:key :value})) - (set &tbl.nitems (+ 1 tbl.nitems))))) + (set &tbl.data.[idx] !(#item {:key :value})) + (set &tbl.nitems !(+ 1 tbl.nitems))))) (defn find [tbl key] (let [idx (probe-linear tbl key false)] diff --git a/test/functions.t/poly_fn_ret_fn.smu b/test/functions.t/poly_fn_ret_fn.smu index d90ddd3d..ec1abeba 100644 --- a/test/functions.t/poly_fn_ret_fn.smu +++ b/test/functions.t/poly_fn_ret_fn.smu @@ -2,7 +2,7 @@ (defn black-box [f g] (if once - (do (set &once false) (copy f)) + (do (set &once !false) (copy f)) (copy g))) (def foo (fn [a] (print (fmt-str a " foo")))) diff --git a/test/functions.t/tailrec_mutable.smu b/test/functions.t/tailrec_mutable.smu index dc685f25..f87b2817 100644 --- a/test/functions.t/tailrec_mutable.smu +++ b/test/functions.t/tailrec_mutable.smu @@ -2,12 +2,12 @@ (defn mut-bref [i rf&] (if (> i 0) - (set &(.a rf) true) + (set &(.a rf) !true) (mut-bref (+ i 1) &rf))) (defn dontmut-bref [i rf&] (if (> i 0) - (set &(.a rf) false) + (set &(.a rf) !false) -- introduce a new object, so the old one won't get mutated (do (def rf2& {:a true}) @@ -30,7 +30,7 @@ (defn mod-rec [r& i] (if (= i 2) - (set &(.a r) i) + (set &(.a r) !i) (mod-rec &r (+ i 1)))) (let [ar& {:a 20}] @@ -52,7 +52,7 @@ -- int (defn change-int [i& j] (if (= j 100) - (set &i j) + (set &i !j) (change-int &i (+ j 1)))) (let [i& 0] diff --git a/test/misc.t/array_push.smu b/test/misc.t/array_push.smu index 02a13b11..381eec0d 100644 --- a/test/misc.t/array_push.smu +++ b/test/misc.t/array_push.smu @@ -21,8 +21,8 @@ (def nested& [[0 1] [2 3]]) (def a [4 5]) (array/push &nested !(copy a)) -(set & nested.[1] (copy a)) -(set &nested.[1] (copy a)) +(set & nested.[1] !(copy a)) +(set &nested.[1] !(copy a)) (array/push &nested ![4 5]) -(set &nested.[1] [4 5]) -(set &nested.[1] [4 5]) +(set &nested.[1] ![4 5]) +(set &nested.[1] ![4 5]) diff --git a/test/misc.t/closure_monomorph.smu b/test/misc.t/closure_monomorph.smu index 80ed0876..3987fb96 100644 --- a/test/misc.t/closure_monomorph.smu +++ b/test/misc.t/closure_monomorph.smu @@ -7,7 +7,7 @@ -- TODO cannot capture [cmp] here (if (< (cmp arr.[j] pivot) 0) (do - (set &i (+ i 1)) + (set &i !(+ i 1)) (array/swap-items &arr i j))))) (def i (+ i 1)) (array/swap-items &arr i hi) @@ -43,7 +43,7 @@ -- TODO cannot capture [cmp] here (if (< (cmp arr.[j] pivot) 0) (do - (set &i (+ i 1)) + (set &i !(+ i 1)) (array/swap-items &arr i j))))) (def i (+ i 1)) (array/swap-items &arr i hi) diff --git a/test/misc.t/m2.smu b/test/misc.t/m2.smu index a7e0cc86..623846d6 100644 --- a/test/misc.t/m2.smu +++ b/test/misc.t/m2.smu @@ -21,7 +21,7 @@ (rec (defn pop [arr&] (print "pop") - (set &cnt (+ cnt 1)) + (set &cnt !(+ cnt 1)) (array/drop-back &arr) (pop-all &arr)) (defn pop-all [arr&] diff --git a/test/misc.t/partials.smu b/test/misc.t/partials.smu index 454689c9..fc464733 100644 --- a/test/misc.t/partials.smu +++ b/test/misc.t/partials.smu @@ -15,7 +15,6 @@ (defn set-moved () (def a& {:a [10] :b [20]}) (ignore {a.a}) - (set &a.a [20]) - ) + (set &a.a ![20])) (set-moved) diff --git a/test/misc.t/upward_mut.smu b/test/misc.t/upward_mut.smu index 94ff6ccf..859badc8 100644 --- a/test/misc.t/upward_mut.smu +++ b/test/misc.t/upward_mut.smu @@ -2,7 +2,7 @@ (defn counter [] (def cnt& 0) - (fn [] (set &cnt (+ cnt 1)) + (fn [] (set &cnt !(+ cnt 1)) cnt)) (def c (counter)) @@ -13,7 +13,7 @@ (defn counter [] (def cnt& {:c 0}) - (fn [] (set &cnt {:c (+ (.c cnt) 1)}) + (fn [] (set &cnt !{:c (+ (.c cnt) 1)}) cnt)) (def c (counter)) diff --git a/test/mutable_value_semantics.t/array_copies.smu b/test/mutable_value_semantics.t/array_copies.smu index 12496aa7..be121937 100644 --- a/test/mutable_value_semantics.t/array_copies.smu +++ b/test/mutable_value_semantics.t/array_copies.smu @@ -7,10 +7,10 @@ (def d b) -- (set &(array-get a 0) 12) -(set &a.[0] 12) +(set &a.[0] !12) (print-0th a) -- (set &(array-get c 0) 15) -(set &c.[0] 15) +(set &c.[0] !15) (print-0th a) (print-0th b) (print-0th c) @@ -25,10 +25,10 @@ (def d b) -- (set &(array-get a 0) 12) - (set &a.[0] 12) + (set &a.[0] !12) (print-0th a) -- (set &(array-get c 0) 15) - (set &c.[0] 15) + (set &c.[0] !15) (print-0th a) (print-0th b) (print-0th c) diff --git a/test/mutable_value_semantics.t/array_in_record_copies.smu b/test/mutable_value_semantics.t/array_in_record_copies.smu index d221dbfb..a1b1084b 100644 --- a/test/mutable_value_semantics.t/array_in_record_copies.smu +++ b/test/mutable_value_semantics.t/array_in_record_copies.smu @@ -2,7 +2,7 @@ (def a& {:a [10]}) (def b (copy a)) -(set &a.a.[0] 12) +(set &a.a.[0] !12) (defn print-thing [a] (print (fmt-str (.a a).[0]))) @@ -15,7 +15,7 @@ (defn in-fun [] (def a& {:a [10]}) (def b (copy a)) - (set &a.a.[0] 12) + (set &a.a.[0] !12) (print-thing a) (print-thing b)) diff --git a/test/mutable_value_semantics.t/const_let.smu b/test/mutable_value_semantics.t/const_let.smu index ab9c5933..5731d0a0 100644 --- a/test/mutable_value_semantics.t/const_let.smu +++ b/test/mutable_value_semantics.t/const_let.smu @@ -1,13 +1,13 @@ (def v& [0]) (def const (copy v.[0])) -(set &v.[0] 1) +(set &v.[0] !1) (print (fmt-str v.[0])) (print (fmt-str const)) (defn in-fun [] (def v& [0]) (def const (copy v.[0])) - (set &v.[0] 1) + (set &v.[0] !1) (print (fmt-str v.[0])) (print (fmt-str const))) diff --git a/test/mutable_value_semantics.t/hidden_match_reference.smu b/test/mutable_value_semantics.t/hidden_match_reference.smu index 762b2685..cf995c43 100644 --- a/test/mutable_value_semantics.t/hidden_match_reference.smu +++ b/test/mutable_value_semantics.t/hidden_match_reference.smu @@ -5,7 +5,7 @@ ((#some i) -- set op. Depending on whether i behaves as a reference or value, return 1 or 2 (let [i (copy i)] - (set &op (#some 2)) + (set &op !(#some 2)) i)) (#none -1))) diff --git a/test/mutable_value_semantics.t/member_refcounts.smu b/test/mutable_value_semantics.t/member_refcounts.smu index 57967483..aab9151c 100644 --- a/test/mutable_value_semantics.t/member_refcounts.smu +++ b/test/mutable_value_semantics.t/member_refcounts.smu @@ -1,15 +1,15 @@ (type r {:a (array int)}) (def a& [10]) (def r {:a (copy a)}) -(set &a.[0] 20) +(set &a.[0] !20) (print (fmt-str (.a r).[0])) (def r [(copy a)]) -(set &a.[0] 30) +(set &a.[0] !30) (print (fmt-str r.[0].[0])) (def r (#some (copy a))) -(set & a.[0] 40) +(set & a.[0] !40) (match r ((#some a) (print (fmt-str a.[0]))) (#none (print "none"))) diff --git a/test/mutable_value_semantics.t/modify_in_fn.smu b/test/mutable_value_semantics.t/modify_in_fn.smu index 843b0adf..7c71b6ab 100644 --- a/test/mutable_value_semantics.t/modify_in_fn.smu +++ b/test/mutable_value_semantics.t/modify_in_fn.smu @@ -1,6 +1,6 @@ (type f {:a& int}) (defn modify [r&] - (set &(.a r) 30)) + (set &(.a r) !30)) (defn mod2 [a&] (array/push &a !20)) diff --git a/test/mutable_value_semantics.t/mut_alias.smu b/test/mutable_value_semantics.t/mut_alias.smu index 245b4da6..be92c7af 100644 --- a/test/mutable_value_semantics.t/mut_alias.smu +++ b/test/mutable_value_semantics.t/mut_alias.smu @@ -3,7 +3,7 @@ (def f {:a 0}) (def fst& (copy f)) (def snd (copy fst)) -(set &(.a fst) 1) +(set &(.a fst) !1) (print (fmt-str (.a fst))) (print (fmt-str (.a f))) (print (fmt-str (.a snd))) @@ -12,7 +12,7 @@ (def f {:a 0}) (def fst& (copy f)) (def snd (copy fst)) - (set &(.a fst) 1) + (set &(.a fst) !1) (print (fmt-str (.a fst))) (print (fmt-str (.a f))) (print (fmt-str (.a snd)))) diff --git a/test/mutable_value_semantics.t/nested_array.smu b/test/mutable_value_semantics.t/nested_array.smu index ad9a1ac2..01bd68fd 100644 --- a/test/mutable_value_semantics.t/nested_array.smu +++ b/test/mutable_value_semantics.t/nested_array.smu @@ -7,6 +7,6 @@ (def a& [[10] [20]]) (def b (copy a)) -(set &a.[0].[0] 15) +(set &a.[0].[0] !15) (prnt a) (prnt b) diff --git a/test/mutable_value_semantics.t/ref_to_const.smu b/test/mutable_value_semantics.t/ref_to_const.smu index 5a5464a0..cf17950b 100644 --- a/test/mutable_value_semantics.t/ref_to_const.smu +++ b/test/mutable_value_semantics.t/ref_to_const.smu @@ -3,6 +3,6 @@ (defn infunc [] (def base-length 2.0) (def length& !base-length) - (set &length (+. length 3.0))) + (set &length !(+. length 3.0))) (ignore infunc) diff --git a/test/mutable_value_semantics.t/simple_set.smu b/test/mutable_value_semantics.t/simple_set.smu index a874fced..89a3b828 100644 --- a/test/mutable_value_semantics.t/simple_set.smu +++ b/test/mutable_value_semantics.t/simple_set.smu @@ -1,10 +1,10 @@ (def b& 10) -(set &b 14) +(set &b !14) (print (fmt-str b)) (defn hmm [] (def b& 10) - (set &b 15) + (set &b !15) b) (print (fmt-str (hmm))) @@ -13,5 +13,5 @@ (ignore b) (def c [30]) -(set &a.[0] (copy c)) -(set &a.[0] [10]) +(set &a.[0] !(copy c)) +(set &a.[0] ![10]) diff --git a/test/mutable_value_semantics.t/unneeded_mut.smu b/test/mutable_value_semantics.t/unneeded_mut.smu index 48cddda9..e2346e56 100644 --- a/test/mutable_value_semantics.t/unneeded_mut.smu +++ b/test/mutable_value_semantics.t/unneeded_mut.smu @@ -2,7 +2,7 @@ (ignore a)) (defn do_mut [a& b] - (set &a (copy b))) + (set &a !(copy b))) (def b& 0) (ignore b) diff --git a/test/records.t/nested_prealloc.smu b/test/records.t/nested_prealloc.smu index b48ad49e..59ea5363 100644 --- a/test/records.t/nested_prealloc.smu +++ b/test/records.t/nested_prealloc.smu @@ -20,7 +20,7 @@ (if (= i 10) () (do - (set &(.wrapped test) {:dat (+ (.dat (.wrapped test)) 1) :b 0 :c 0}) + (set &(.wrapped test) !{:dat (+ (.dat (.wrapped test)) 1) :b 0 :c 0}) (vector_loop (+ i 1))))) (vector_loop 0) (.wrapped test)) diff --git a/test/typing.ml b/test/typing.ml index 3f789a27..b7369fc7 100644 --- a/test/typing.ml +++ b/test/typing.ml @@ -353,28 +353,28 @@ let test_array_different_weak () = let test_mutable_declare () = test "int" "(type foo { :x& int }) 0" let test_mutable_set () = - test "unit" "(type foo { :x& int }) (def foo& { :x 12 }) (set &(.x foo) 13)" + test "unit" "(type foo { :x& int }) (def foo& { :x 12 }) (set &(.x foo) !13)" let test_mutable_set_wrong_type () = test_exn "Mutate: Expected type int but got type bool" - "(type foo { :x& int }) (def foo& { :x 12 }) (set &(.x foo) true)" + "(type foo { :x& int }) (def foo& { :x 12 }) (set &(.x foo) !true)" let test_mutable_set_non_mut () = test_exn "Cannot mutate non-mutable binding" - "(type foo { :x int }) (def foo { :x 12}) (set &(.x foo) 13)" + "(type foo { :x int }) (def foo { :x 12}) (set &(.x foo) !13)" -let test_mutable_value () = test "int" "(def b& 10) (set &b 14) b" +let test_mutable_value () = test "int" "(def b& 10) (set &b !14) b" let test_mutable_nonmut_value () = - test_exn "Cannot mutate non-mutable binding" "(def b 10) (set &b 14) b" + test_exn "Cannot mutate non-mutable binding" "(def b 10) (set &b !14) b" let test_mutable_nonmut_transitive () = test_exn "Cannot mutate non-mutable binding" - "(type foo { :x& int }) (def foo { :x 12 }) (set &(.x foo) 13)" + "(type foo { :x& int }) (def foo { :x 12 }) (set &(.x foo) !13)" let test_mutable_nonmut_transitive_inv () = test_exn "Cannot mutate non-mutable binding" - "(type foo { :x int }) (def foo& { :x 12 }) (set &(.x foo) 13)" + "(type foo { :x int }) (def foo& { :x 12 }) (set &(.x foo) !13)" let test_variants_option_none () = test_exn "Expression contains weak type variables: (option 'a)" @@ -684,12 +684,12 @@ let test_excl_borrow () = let test_excl_borrow_use_early () = wrap_fn ~tl test_exn "x was borrowed in line 2, cannot mutate" - (own ^ "(def y x)\n (ignore x)\n (set &x 11)\n (ignore y)") + (own ^ "(def y x)\n (ignore x)\n (set &x !11)\n (ignore y)") let tl = Some "Cannot move top level binding" let test_excl_move_mut () = - wrap_fn ~tl test "unit" (own ^ "(def y& !x) (set &y 11) (ignore y)") + wrap_fn ~tl test "unit" (own ^ "(def y& !x) (set &y !11) (ignore y)") let test_excl_move_mut_use_after () = wrap_fn test_exn "x was moved in line 2, cannot use" @@ -719,7 +719,7 @@ let test_excl_if_lit_borrow () = let proj_msg = Some "Cannot project at top level" let test_excl_proj () = - wrap_fn ~tl:proj_msg test "unit" (own ^ "(def y& &x) (set &y 11) (ignore x)") + wrap_fn ~tl:proj_msg test "unit" (own ^ "(def y& &x) (set &y !11) (ignore x)") let test_excl_proj_immutable () = wrap_fn ~tl:proj_msg test_exn "Cannot project immutable binding" @@ -753,7 +753,7 @@ let test_excl_moved_param () = test_exn "Borrowed parameter x is moved" "(defn meh [x] x)" let test_excl_set_moved () = - test "unit" "(defn meh [a&] (ignore {a}) (set &a 10))" + test "unit" "(defn meh [a&] (ignore {a}) (set &a !10))" let test_excl_binds () = test "unit" @@ -1240,7 +1240,7 @@ let () = {| (def a& 10) (defn set-a [] - (set &a 11)) + (set &a !11)) (let [b a] (set-a) (ignore b))|}; @@ -1257,10 +1257,10 @@ let () = "a was mutably borrowed in line 3, cannot borrow" {|(defn hmm [] (def a& 10) - (def set-a (fn [] (set &a 11))) - (set &a 11) + (def set-a (fn [] (set &a !11))) + (set &a !11) (set-a) - (set &a 11)) + (set &a !11)) |}; tase_exn "closure carry set" "a was mutably borrowed in line 3, cannot borrow" @@ -1268,25 +1268,25 @@ let () = and a different error occurs *) {|(defn hmm [] (def a& [10]) - (def set-a (fn [] (set &a [11]))) - (set &a [11]) + (def set-a (fn [] (set &a ![11]))) + (set &a ![11]) (def x& !a) (set-a))|}; tase_exn "excl 1" "a was mutably borrowed in line 1, cannot borrow" - "(def a& 10)(defn f [a& b] (set &a 11))(f &a a)"; + "(def a& 10)(defn f [a& b] (set &a !11))(f &a a)"; tase_exn "excl 2" "a was borrowed in line 1, cannot mutate" - "(def a& 10)(defn f [a& b] (set &a 11))(let [b a] (f &a b))"; + "(def a& 10)(defn f [a& b] (set &a !11))(let [b a] (f &a b))"; tase_exn "excl 3" "a was borrowed in line 1, cannot mutate" - "(def a& 10) (defn f [a b&] (set &b 11))(f a &a)"; + "(def a& 10) (defn f [a b&] (set &b !11))(f a &a)"; tase_exn "excl 4" "a was borrowed in line 1, cannot mutate" - "(def a& 10)(defn f [a b&] (set &b 11)) (let [b a] (f b &a))"; + "(def a& 10)(defn f [a b&] (set &b !11)) (let [b a] (f b &a))"; tase "excl 5" "unit" "(def a& 10) (defn f [a b] ()) (f a a)"; tase_exn "excl 6" "a was mutably borrowed in line 1, cannot borrow" "(def a& 10) (defn f [a& b&] ()) (f &a &a)"; tase_exn "excl env" "a was mutably borrowed in line 4, cannot borrow" {|(def a& [10]) (defn set-a [b&] - (set &a [11])) + (set &a ![11])) (set-a &a)|}; tase_exn "follow string literal" "Cannot move string literal. Use `copy`" @@ -1305,14 +1305,14 @@ let () = "(def a& [10]) (def b& a)"; tase_exn "partially set moved" "a was moved in line 2, cannot set a.[0]" - "(def a& [10])\n(def b {a})\n(set &a.[0] 10)"; + "(def a& [10])\n(def b {a})\n(set &a.[0] !10)"; tase_exn "forbid move out of array" "Cannot move out of array. Use `copy`" "(defn set-moved ()\n\ (def a& [\"a\" \"b\"])\n\ (def b a.[0])\n\ (ignore {b})\n\ - (set &a.[0] \"c\"))"; + (set &a.[0] !\"!c\"))"; tase_exn "track moved multi-borrow param" "Borrowed parameter s is moved" {|(defn test (s&) @@ -1327,7 +1327,7 @@ let () = (match thing ((#item {:key :value}) (do (ignore {key}) (ignore {value}) (ignore {value}) - -- (set &thing #empty) + -- (set &thing !#!empty) )) (#empty ()))) |}; @@ -1338,7 +1338,7 @@ let () = (match thing ((#item {:key :value}) (do (ignore {key}) (ignore {value}) - -- (set &thing #empty) + -- (set &thing !#!empty) )) (#empty ()))) |};