aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-08-19 14:45:31 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commit2bc0fe723d0f5cf2be5d84545b823dec0dbfb52b (patch)
treeba0ff0449d9f56b53e55b9d4b9ae2b68662d5073
parentadd (failing) struct spec (diff)
downloadalive-2bc0fe723d0f5cf2be5d84545b823dec0dbfb52b.tar.gz
alive-2bc0fe723d0f5cf2be5d84545b823dec0dbfb52b.zip
implement (set) as per spec
-rw-r--r--alv/builtins.moon36
-rw-r--r--alv/result/const.moon2
-rw-r--r--spec/lang/array_spec.moon14
-rw-r--r--spec/lang/struct_spec.moon4
4 files changed, 45 insertions, 11 deletions
diff --git a/alv/builtins.moon b/alv/builtins.moon
index b1c8593..9610b5f 100644
--- a/alv/builtins.moon
+++ b/alv/builtins.moon
@@ -532,6 +532,39 @@ get = Constant.meta
val = val[key]
@out\set val
+set = Constant.meta
+ meta:
+ name: 'set'
+ summary: "Update Arrays and Structs."
+ examples: { '(set val key new-val)' }
+
+ value: class extends PureOp
+ pattern: (sig! / evt!) + (const.str / const.sym / const.num) + (sig! / evt!)
+ type: (inputs) => inputs[1]\type!
+
+ setup: (...) =>
+ super ...
+
+ { val, key, new_val } = @inputs
+
+ expected_val_typ = val\type!\get key!
+ got_val_typ = new_val\type!
+ if expected_val_typ ~= got_val_typ
+ msg = string.format "expected value for key '%s' to be %s, not %s",
+ key!, expected_val_typ, got_val_typ
+ error Error 'argument', msg
+
+ tick: =>
+ { val, key, new_val } = @unwrap_all!
+
+ if type(key) == 'number'
+ key = key + 1
+
+ val = {k,v for k,v in pairs val}
+ val[key] = new_val
+
+ @out\set val
+
loop = Constant.meta
meta:
name: 'loop'
@@ -629,7 +662,8 @@ Scope.from_table {
'~': to_sig
'!': to_evt
- :array, :struct, :get
+ :array, :struct
+ :get, :set
:loop, :recur
diff --git a/alv/result/const.moon b/alv/result/const.moon
index 9e24ab1..ecd386d 100644
--- a/alv/result/const.moon
+++ b/alv/result/const.moon
@@ -45,7 +45,7 @@ class Constant extends Result
--- compare two values.
--
-- Compares two `SigStream`s by comparing their types and their Lua values.
- __eq: (other) => other.type == @type and other.value == @value
+ __eq: (other) => other.type == @type and @type\eq other.value, @value
--- Result metatype.
-- @tfield string metatype (`=`)
diff --git a/spec/lang/array_spec.moon b/spec/lang/array_spec.moon
index 97632e3..25c0167 100644
--- a/spec/lang/array_spec.moon
+++ b/spec/lang/array_spec.moon
@@ -33,11 +33,11 @@ describe "array", ->
it "checks value type", ->
err = assert.has.error -> COPILOT\eval_once '(set (array 1) 0 "a")'
- assert.matches "argument error: TBD", err
+ assert.matches "expected value for key '0' to be num, not str", err
it "checks index range", ->
err = assert.has.error -> COPILOT\eval_once '(set (array 1 2) -1 0)'
- assert.matches "index '-1' out of range!", err
+ assert.matches "index '%-1' out of range!", err
COPILOT\eval_once '(set (array 1 2) 0 0)'
@@ -75,21 +75,21 @@ describe "array", ->
assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result
it "can insert a value", ->
- rt = COPILOT\eval_once '(set (array "b" "c") 0 "a")'
+ rt = COPILOT\eval_once '(insert (array "b" "c") 0 "a")'
assert.is.true rt\is_const!
assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result
- rt = COPILOT\eval_once '(set (array "a" "c") 1 "b")'
+ rt = COPILOT\eval_once '(insert (array "a" "c") 1 "b")'
assert.is.true rt\is_const!
assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result
- rt = COPILOT\eval_once '(set (array "a" "b") 1 "c")'
+ rt = COPILOT\eval_once '(insert (array "a" "b") 1 "c")'
assert.is.true rt\is_const!
assert.is.equal svec3\mk_const({ 'a', 'b', 'c' }), rt.result
it "checks index range", ->
err = assert.has.error -> COPILOT\eval_once '(insert (array 1 2) -1 0)'
- assert.matches "index '-1' out of range!", err
+ assert.matches "index '%-1' out of range!", err
COPILOT\eval_once '(insert (array 1 2) 0 0)'
@@ -117,7 +117,7 @@ describe "array", ->
it "checks index range", ->
err = assert.has.error -> COPILOT\eval_once '(remove (array 1 2 3) -1)'
- assert.matches "index '-1' out of range!", err
+ assert.matches "index '%-1' out of range!", err
err = assert.has.error -> COPILOT\eval_once '(remove (array 1 2 3) 3)'
assert.matches "index '3' out of range!", err
diff --git a/spec/lang/struct_spec.moon b/spec/lang/struct_spec.moon
index 57c7e79..aa7b689 100644
--- a/spec/lang/struct_spec.moon
+++ b/spec/lang/struct_spec.moon
@@ -14,11 +14,11 @@ describe "struct", ->
it "cannot add members", ->
err = assert.has.error -> COPILOT\eval_once '(set (struct "a" 1) "b" 2)'
- assert.matches "argument error: TBD", err
+ assert.matches "{a: num} has no 'b' key", err
it "checks value type", ->
err = assert.has.error -> COPILOT\eval_once '(set (struct "a" 1) "a" "str")'
- assert.matches "argument error: TBD", err
+ assert.matches "expected value for key 'a' to be num, not str", err
describe "(get)", ->
it "can get values", ->