Skip to content

Commit 54858d0

Browse files
committed
feat: add support for slice assignment and refactor index expression handling
1 parent e348e20 commit 54858d0

10 files changed

Lines changed: 475 additions & 154 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2023 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var hasProperty = require( './has_property.js' );
24+
var getValue = require( './get_value.js' );
25+
var getSlice = require( './get_slice.js' );
26+
27+
28+
// MAIN //
29+
30+
/**
31+
* Returns a trap for retrieving property values.
32+
*
33+
* @private
34+
* @param {Function} prop2slice - function for converting an indexing expression to a slice
35+
* @returns {Function} handler
36+
*/
37+
function factory( prop2slice ) {
38+
return get;
39+
40+
/**
41+
* Trap for retrieving property values.
42+
*
43+
* @private
44+
* @param {Object} target - target object
45+
* @param {(string|symbol)} property - property name
46+
* @param {Object} receiver - the proxy object or an object inheriting from the proxy
47+
* @throws {Error} invalid slice operation
48+
* @throws {RangeError} number of slice dimensions must match the number of array dimensions
49+
* @returns {*} result
50+
*/
51+
function get( target, property, receiver ) {
52+
if ( hasProperty( property ) ) {
53+
return getValue( target, property, receiver );
54+
}
55+
return getSlice( target, property, receiver, prop2slice );
56+
}
57+
}
58+
59+
60+
// EXPORTS //
61+
62+
module.exports = factory;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2023 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var slice = require( '@stdlib/ndarray/base/slice' );
24+
var errMessage = require( './error_message.js' );
25+
var errConstructor = require( './error_constructor.js' );
26+
27+
28+
// MAIN //
29+
30+
/**
31+
* Returns an ndarray view.
32+
*
33+
* @private
34+
* @param {Object} target - target object
35+
* @param {string} property - property name
36+
* @param {Object} receiver - the proxy object or an object inheriting from the proxy
37+
* @param {Function} prop2slice - function for converting an indexing expression to a slice
38+
* @throws {Error} invalid slice operation
39+
* @throws {RangeError} number of slice dimensions must match the number of array dimensions
40+
* @returns {FancyArray} result
41+
*/
42+
function getSlice( target, property, receiver, prop2slice ) { // eslint-disable-line stdlib/jsdoc-require-throws-tags
43+
var strict;
44+
var E;
45+
var s;
46+
47+
strict = false; // TODO: support strict mode
48+
s = prop2slice( target, property, strict );
49+
try {
50+
return slice( receiver, s, strict, false );
51+
} catch ( err ) {
52+
E = errConstructor( err );
53+
throw new E( errMessage( err.message ) );
54+
}
55+
}
56+
57+
58+
// EXPORTS //
59+
60+
module.exports = getSlice;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2023 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var isFunction = require( '@stdlib/assert/is-function' );
24+
25+
26+
// MAIN //
27+
28+
/**
29+
* Returns the property value associated with a specified property.
30+
*
31+
* @private
32+
* @param {Object} target - target object
33+
* @param {(string|symbol)} property - property
34+
* @param {Object} receiver - the proxy object or an object inheriting from the proxy
35+
* @returns {*} result
36+
*/
37+
function getValue( target, property, receiver ) {
38+
var value = target[ property ];
39+
if ( isFunction( value ) ) {
40+
return wrapper;
41+
}
42+
return value;
43+
44+
/**
45+
* Method wrapper.
46+
*
47+
* @private
48+
* @returns {*} results
49+
*/
50+
function wrapper() {
51+
var args;
52+
var i;
53+
54+
args = [];
55+
for ( i = 0; i < arguments.length; i++ ) {
56+
args.push( arguments[ i ] );
57+
}
58+
return value.apply( ( this === receiver ) ? target : this, args ); // eslint-disable-line no-invalid-this
59+
}
60+
}
61+
62+
63+
// EXPORTS //
64+
65+
module.exports = getValue;

lib/node_modules/@stdlib/ndarray/fancy/lib/main.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,21 @@ var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-propert
2626
var parent = require( '@stdlib/ndarray/ctor' ); // eslint-disable-line stdlib/no-redeclare
2727
var inherit = require( '@stdlib/utils/inherit' );
2828
var Proxy = require( '@stdlib/proxy/ctor' );
29-
var get0d = require( './get.0d.js' );
30-
var get1d = require( './get.1d.js' );
31-
var getnd = require( './get.nd.js' );
29+
var prop2slice0d = require( './prop2slice.0d.js' );
30+
var prop2slice1d = require( './prop2slice.1d.js' );
31+
var prop2slicend = require( './prop2slice.nd.js' );
32+
var get = require( './get.js' );
33+
var set = require( './set.js' );
34+
35+
36+
// VARIABLES //
37+
38+
var get0d = get( prop2slice0d );
39+
var set0d = set( prop2slice0d );
40+
var get1d = get( prop2slice1d );
41+
var set1d = set( prop2slice1d );
42+
var getnd = get( prop2slicend );
43+
var setnd = set( prop2slicend );
3244

3345

3446
// MAIN //
@@ -92,10 +104,13 @@ function FancyArray( dtype, buffer, shape, strides, offset, order, options ) {
92104
handlers = {};
93105
if ( ndims === 0 ) {
94106
handlers.get = get0d;
107+
handlers.set = set0d;
95108
} else if ( ndims === 1 ) {
96109
handlers.get = get1d;
110+
handlers.set = set1d;
97111
} else {
98112
handlers.get = getnd;
113+
handlers.set = setnd;
99114
}
100115
return new Proxy( this, handlers );
101116
}

lib/node_modules/@stdlib/ndarray/fancy/lib/get.0d.js renamed to lib/node_modules/@stdlib/ndarray/fancy/lib/prop2slice.0d.js

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -20,49 +20,36 @@
2020

2121
// MODULES //
2222

23-
var isFunction = require( '@stdlib/assert/is-function' );
2423
var trim = require( '@stdlib/string/base/trim' );
2524
var replace = require( '@stdlib/string/base/replace' );
2625
var MultiSlice = require( '@stdlib/slice/multi' );
2726
var str2multislice = require( '@stdlib/slice/base/str2multislice' );
2827
var seq2multislice = require( '@stdlib/slice/base/seq2multislice' );
2928
var str2slice = require( '@stdlib/slice/base/str2slice' );
30-
var slice = require( '@stdlib/ndarray/base/slice' );
3129
var format = require( '@stdlib/string/format' );
32-
var errMessage = require( './error_message.js' );
33-
var errConstructor = require( './error_constructor.js' );
34-
var hasProperty = require( './has_property.js' );
3530
var RE_INTEGER = require( './re_integer.js' );
3631
var RE_SUBSEQ = require( './re_subseq.js' );
3732

3833

3934
// MAIN //
4035

4136
/**
42-
* Trap for retrieving property values.
37+
* Converts a zero-dimensional ndarray indexing expression to a slice.
4338
*
4439
* @private
4540
* @param {Object} target - target object
46-
* @param {(string|symbol)} property - property name
47-
* @param {Object} receiver - the proxy object or an object inheriting from the proxy
41+
* @param {string} property - property name
42+
* @param {boolean} strict - boolean indicating whether to enforce strict bounds checking
4843
* @throws {Error} invalid slice operation
4944
* @throws {RangeError} number of slice dimensions must match the number of array dimensions
50-
* @returns {*} result
45+
* @returns {MultiSlice} multi-slice object
5146
*/
52-
function get( target, property, receiver ) { // eslint-disable-line stdlib/jsdoc-require-throws-tags
53-
var value;
47+
function prop2slice( target, property ) {
5448
var shape;
5549
var prop;
5650
var ch;
57-
var E;
5851
var s;
59-
if ( hasProperty( property ) ) {
60-
value = target[ property ];
61-
if ( isFunction( value ) ) {
62-
return wrapper;
63-
}
64-
return value;
65-
}
52+
6653
prop = trim( property );
6754

6855
// Retrieve the first character in order to to detect how a slice operation was specified:
@@ -120,32 +107,10 @@ function get( target, property, receiver ) { // eslint-disable-line stdlib/jsdoc
120107
else {
121108
throw new Error( format( 'invalid operation. Unsupported slice operation. Value: `%s`.', property ) );
122109
}
123-
try {
124-
return slice( receiver, s, true );
125-
} catch ( err ) {
126-
E = errConstructor( err );
127-
throw new E( errMessage( err.message ) );
128-
}
129-
130-
/**
131-
* Method wrapper.
132-
*
133-
* @private
134-
* @returns {*} results
135-
*/
136-
function wrapper() {
137-
var args;
138-
var i;
139-
140-
args = [];
141-
for ( i = 0; i < arguments.length; i++ ) {
142-
args.push( arguments[ i ] );
143-
}
144-
return value.apply( ( this === receiver ) ? target : this, args ); // eslint-disable-line no-invalid-this
145-
}
110+
return s;
146111
}
147112

148113

149114
// EXPORTS //
150115

151-
module.exports = get;
116+
module.exports = prop2slice;

0 commit comments

Comments
 (0)