11/**
2- * Assignment operators
2+ * Assignment operators (C-family)
33 *
4- * = += -= *= /= %= |= &= ^= >>= <<= >>>= ||= &&= ??=
5- * Note: **= is in pow.js (must be with ** for correct parsing )
4+ * = += -= *= /= %= |= &= ^= >>= <<=
5+ * Note: **= is in pow.js, >>>= ||= &&= ??= are JS-specific (in assignment-js.js )
66 */
77import { binary , operator , compile } from '../../parse.js' ;
8- import { destructure } from '../destruct.js' ;
9- import { isLval , prop } from '../member.js' ;
108
119const ASSIGN = 20 ;
12- const err = msg => { throw Error ( msg ) } ;
1310
1411// Base assignment
1512binary ( '=' , ASSIGN , true ) ;
@@ -20,44 +17,31 @@ binary('-=', ASSIGN, true);
2017binary ( '*=' , ASSIGN , true ) ;
2118binary ( '/=' , ASSIGN , true ) ;
2219binary ( '%=' , ASSIGN , true ) ;
23- // **= is in pow.js
2420
2521// Compound bitwise
2622binary ( '|=' , ASSIGN , true ) ;
2723binary ( '&=' , ASSIGN , true ) ;
2824binary ( '^=' , ASSIGN , true ) ;
2925binary ( '>>=' , ASSIGN , true ) ;
3026binary ( '<<=' , ASSIGN , true ) ;
31- binary ( '>>>=' , ASSIGN , true ) ;
3227
33- // Compound logical
34- binary ( '||=' , ASSIGN , true ) ;
35- binary ( '&&=' , ASSIGN , true ) ;
36- binary ( '??=' , ASSIGN , true ) ;
28+ // Simple assign helper for x, a.b, a[b], (x)
29+ const assign = ( a , fn , obj , key ) =>
30+ typeof a === 'string' ? ctx => fn ( ctx , a , ctx ) :
31+ a [ 0 ] === '.' ? ( obj = compile ( a [ 1 ] ) , key = a [ 2 ] , ctx => fn ( obj ( ctx ) , key , ctx ) ) :
32+ a [ 0 ] === '[]' && a . length === 3 ? ( obj = compile ( a [ 1 ] ) , key = compile ( a [ 2 ] ) , ctx => fn ( obj ( ctx ) , key ( ctx ) , ctx ) ) :
33+ a [ 0 ] === '()' && a . length === 2 ? assign ( a [ 1 ] , fn ) : // unwrap parens: (x) = 1
34+ ( ( ) => { throw Error ( 'Invalid assignment target' ) } ) ( ) ;
3735
3836// Compile
39- operator ( '=' , ( a , b ) => {
40- // Handle let/const/var declarations: ['=', ['let', pattern], value]
41- if ( Array . isArray ( a ) && ( a [ 0 ] === 'let' || a [ 0 ] === 'const' || a [ 0 ] === 'var' ) ) {
42- const pattern = a [ 1 ] ;
43- b = compile ( b ) ;
44- if ( typeof pattern === 'string' ) return ctx => { ctx [ pattern ] = b ( ctx ) ; } ;
45- return ctx => destructure ( pattern , b ( ctx ) , ctx ) ;
46- }
47- isLval ( a ) || err ( 'Invalid assignment target' ) ;
48- return ( b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] = b ( ctx ) ) ) ;
49- } ) ;
50- operator ( '+=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] += b ( ctx ) ) ) ) ;
51- operator ( '-=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] -= b ( ctx ) ) ) ) ;
52- operator ( '*=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] *= b ( ctx ) ) ) ) ;
53- operator ( '/=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] /= b ( ctx ) ) ) ) ;
54- operator ( '%=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] %= b ( ctx ) ) ) ) ;
55- operator ( '|=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] |= b ( ctx ) ) ) ) ;
56- operator ( '&=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] &= b ( ctx ) ) ) ) ;
57- operator ( '^=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] ^= b ( ctx ) ) ) ) ;
58- operator ( '>>=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] >>= b ( ctx ) ) ) ) ;
59- operator ( '<<=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] <<= b ( ctx ) ) ) ) ;
60- operator ( '>>>=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] >>>= b ( ctx ) ) ) ) ;
61- operator ( '||=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] ||= b ( ctx ) ) ) ) ;
62- operator ( '&&=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] &&= b ( ctx ) ) ) ) ;
63- operator ( '??=' , ( a , b ) => ( isLval ( a ) || err ( 'Invalid assignment target' ) , b = compile ( b ) , prop ( a , ( obj , path , ctx ) => obj [ path ] ??= b ( ctx ) ) ) ) ;
37+ operator ( '=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] = b ( ctx ) ) ) ) ;
38+ operator ( '+=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] += b ( ctx ) ) ) ) ;
39+ operator ( '-=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] -= b ( ctx ) ) ) ) ;
40+ operator ( '*=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] *= b ( ctx ) ) ) ) ;
41+ operator ( '/=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] /= b ( ctx ) ) ) ) ;
42+ operator ( '%=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] %= b ( ctx ) ) ) ) ;
43+ operator ( '|=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] |= b ( ctx ) ) ) ) ;
44+ operator ( '&=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] &= b ( ctx ) ) ) ) ;
45+ operator ( '^=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] ^= b ( ctx ) ) ) ) ;
46+ operator ( '>>=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] >>= b ( ctx ) ) ) ) ;
47+ operator ( '<<=' , ( a , b ) => ( b = compile ( b ) , assign ( a , ( o , k , ctx ) => o [ k ] <<= b ( ctx ) ) ) ) ;
0 commit comments