Skip to content

Commit

Permalink
Remove automatic key-combination for array functions
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasKl committed Jul 18, 2024
1 parent 84a4257 commit 0a8a5c0
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 46 deletions.
2 changes: 1 addition & 1 deletion tests/test_eval_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_geta(self):
self.checkEqual('(geta (array (1 2) (3 4)) 1)', 2)
self.checkEqual('(geta (array (1 2) (3 4)) 3)', 4)

with self.assertRaises(ValueError):
with self.assertRaises(WalEvalError):
self.checkEqual('(geta (array (1 2) (3 4)) 4)', 4)

self.checkEqual("(geta (array (\"a\" 2) ('b 4)) \"a\")", 2)
Expand Down
1 change: 0 additions & 1 deletion wal/ast_defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ class Operator(Enum):
ARRAY = 'array'
SETA = 'seta'
GETA = 'geta'
GETA_DEFAULT = 'geta/default'
DELA = 'dela'
MAPA = 'mapa'
ALLSCOPES = 'all-scopes'
Expand Down
67 changes: 23 additions & 44 deletions wal/implementation/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,60 +28,40 @@ def to_str (sexpr):

def op_seta(seval, args):
'''Updates values depending on the tuples in args'''
assert len(args) >= 3, 'seta: requires at least three arguments. (seta name [key:(int, str)] value)'
evaluated_args = seval.eval_args(args[1:-1])
evaluated_val = seval.eval(args[-1])
assert all(map(lambda x: isinstance(x, (int, str, Symbol)),
evaluated_args)), 'seta: keys must be either int, string or a symbol'
res = None
key = '-'.join(map(to_str, evaluated_args))
assert len(args) == 3, 'seta: requires three arguments. (seta array key:(int, str, symbol) value)'
array = seval.eval(args[0])

assert isinstance(array, dict), 'seta: must be applied on array'
array[key] = evaluated_val
res = array
return res
key = seval.eval(args[1])
assert isinstance(key, (int, str, Symbol)), 'seta: key must be either int, string or a symbol'
val = seval.eval(args[2])
key = to_str(key)
array[key] = val
return array


def op_geta_default(seval, args):
'''Returns the value from key '-'.join(keys) from array. If key is not in array return default'''
assert len(args) >= 3, 'geta: requires at least three arguments. (geta array:(array, symbol) default:expr [key:(int, str, symbol])'
def op_geta(seval, args):
'''Returns the value at key from array.'''
assert len(args) == 2, 'geta: requires at least three arguments. (geta array:(array, symbol) key:(int, str, symbol)'
array = seval.eval(args[0])
assert(isinstance(array, dict)), 'geta: first argument must be either array or symbol'
evaluated = seval.eval_args(args[2:])
assert all(map(lambda x: isinstance(x, (int, str, Symbol)),
evaluated)), 'geta: keys must be either int or string'

key = '-'.join(map(to_str, evaluated))
default = args[1]

if key in array:
return array[key]
assert(isinstance(array, dict)), 'geta: first argument must be an array'
key = seval.eval(args[1])
assert isinstance(key, (int, str, Symbol)), 'geta: key must be either int, string or a symbol'
key = to_str(key)

if key not in array and default is None:
raise ValueError(f'Key {key} not found')

default = seval.eval(default)
return default


def op_geta(seval, args):
'''Returns the value from key '-'.join(keys) from array'''
assert len(args) >= 2, 'geta: requires at least two arguments. (geta array:(array, symbol) [key:(int, str, symbol])'
return op_geta_default(seval, [args[0], None] + args[1:])
assert key in array, f'geta: key {key} not found'
return array[key]


def op_dela(seval, args):
'''Removes the value from key '-'.join(keys) from array
'''Removes the value at key from array
Returns the array without the removed value'''
assert len(args) >= 2, 'dela: requires at least two arguments. (dela array:(array, symbol) [key:(int, str, symbol])'
assert len(args) == 2, 'dela: requires at least two arguments. (dela array key)'
array = seval.eval(args[0])
assert(isinstance(array, dict)), 'dela: first argument must be either array or symbol'
evaluated = seval.eval_args(args[1:])
assert all(map(lambda x: isinstance(x, (int, str, Symbol)),
evaluated)), 'dela: keys must be either int or string'

key = '-'.join(map(str, evaluated))
assert(isinstance(array, dict)), 'dela: first argument must be an array'
key = seval.eval(args[1])
assert isinstance(key, (int, str, Symbol)), 'geta: key must be either int, string or a symbol'
key = to_str(key)
assert key in array, f'dela: key {key} not found'
del array[key]
return array

Expand All @@ -104,7 +84,6 @@ def op_mapa(seval, args):
Operator.ARRAY.value: op_array,
Operator.SETA.value: op_seta,
Operator.GETA.value: op_geta,
Operator.GETA_DEFAULT.value: op_geta_default,
Operator.DELA.value: op_dela,
Operator.MAPA.value: op_mapa
}
6 changes: 6 additions & 0 deletions wal/libs/std/std.wal
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,9 @@
(signal? (+ g (symbol->string ex)))))))
(groups ,@including)))

(defmacro geta/default [a default key]
(define array-sym (gensym))
`(let ([,array-sym ,a])
(if (in ,key ,array-sym)
(geta ,array-sym ,key)
,default)))

0 comments on commit 0a8a5c0

Please sign in to comment.