From 0a8a5c0f00148826d56f72fd5f7201e9b5a09625 Mon Sep 17 00:00:00 2001 From: Lucas Klemmer Date: Thu, 18 Jul 2024 18:04:24 +0200 Subject: [PATCH] Remove automatic key-combination for array functions --- tests/test_eval_array.py | 2 +- wal/ast_defs.py | 1 - wal/implementation/array.py | 67 +++++++++++++------------------------ wal/libs/std/std.wal | 6 ++++ 4 files changed, 30 insertions(+), 46 deletions(-) diff --git a/tests/test_eval_array.py b/tests/test_eval_array.py index b894d91..09fd0f6 100644 --- a/tests/test_eval_array.py +++ b/tests/test_eval_array.py @@ -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) diff --git a/wal/ast_defs.py b/wal/ast_defs.py index 6e20738..6cfc77d 100644 --- a/wal/ast_defs.py +++ b/wal/ast_defs.py @@ -80,7 +80,6 @@ class Operator(Enum): ARRAY = 'array' SETA = 'seta' GETA = 'geta' - GETA_DEFAULT = 'geta/default' DELA = 'dela' MAPA = 'mapa' ALLSCOPES = 'all-scopes' diff --git a/wal/implementation/array.py b/wal/implementation/array.py index e6a9a38..338e15c 100644 --- a/wal/implementation/array.py +++ b/wal/implementation/array.py @@ -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 @@ -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 } diff --git a/wal/libs/std/std.wal b/wal/libs/std/std.wal index e3e5078..79e326a 100644 --- a/wal/libs/std/std.wal +++ b/wal/libs/std/std.wal @@ -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)))