@@ -7,7 +7,7 @@ import declareSync from './utilities/declareSync.js'
77import { build , buildString } from './compiler.js'
88import chainingSupported from './utilities/chainingSupported.js'
99import InvalidControlInput from './errors/InvalidControlInput.js'
10- import { splitPath } from './utilities/splitPath.js'
10+ import { splitPathMemoized } from './utilities/splitPath.js'
1111
1212function isDeterministic ( method , engine , buildState ) {
1313 if ( Array . isArray ( method ) ) {
@@ -34,17 +34,36 @@ function isDeterministic (method, engine, buildState) {
3434}
3535
3636const defaultMethods = {
37- '+' : ( data ) => [ ] . concat ( data ) . reduce ( ( a , b ) => + a + + b , 0 ) ,
38- '*' : ( data ) => data . reduce ( ( a , b ) => + a * + b ) ,
39- '/' : ( data ) => data . reduce ( ( a , b ) => + a / + b ) ,
40-
41- '-' : ( data ) =>
42- // @ts -ignore Type checking is incorrect on the following line.
43- ( ( a ) => ( a . length === 1 ? ( a [ 0 ] = - a [ 0 ] ) : a ) & 0 || a ) (
44- [ ] . concat ( data )
45- // @ts -ignore Type checking is incorrect on the following line.
46- ) . reduce ( ( a , b ) => + a - + b ) ,
47- '%' : ( data ) => data . reduce ( ( a , b ) => + a % + b ) ,
37+ '+' : ( data ) => {
38+ if ( typeof data === 'string' ) return + data
39+ if ( typeof data === 'number' ) return + data
40+ let res = 0
41+ for ( let i = 0 ; i < data . length ; i ++ ) res += + data [ i ]
42+ return res
43+ } ,
44+ '*' : ( data ) => {
45+ let res = 1
46+ for ( let i = 0 ; i < data . length ; i ++ ) res *= + data [ i ]
47+ return res
48+ } ,
49+ '/' : ( data ) => {
50+ let res = data [ 0 ]
51+ for ( let i = 1 ; i < data . length ; i ++ ) res /= + data [ i ]
52+ return res
53+ } ,
54+ '-' : ( data ) => {
55+ if ( typeof data === 'string' ) return - data
56+ if ( typeof data === 'number' ) return - data
57+ if ( data . length === 1 ) return - data [ 0 ]
58+ let res = data [ 0 ]
59+ for ( let i = 1 ; i < data . length ; i ++ ) res -= + data [ i ]
60+ return res
61+ } ,
62+ '%' : ( data ) => {
63+ let res = data [ 0 ]
64+ for ( let i = 1 ; i < data . length ; i ++ ) res %= + data [ i ]
65+ return res
66+ } ,
4867 max : ( data ) => Math . max ( ...data ) ,
4968 min : ( data ) => Math . min ( ...data ) ,
5069 in : ( [ item , array ] ) => ( array || [ ] ) . includes ( item ) ,
@@ -145,8 +164,18 @@ const defaultMethods = {
145164 '!=' : ( [ a , b ] ) => a != b ,
146165 '!==' : ( [ a , b ] ) => a !== b ,
147166 xor : ( [ a , b ] ) => a ^ b ,
148- or : ( arr ) => arr . reduce ( ( a , b ) => a || b , false ) ,
149- and : ( arr ) => arr . reduce ( ( a , b ) => a && b ) ,
167+ or : ( arr ) => {
168+ for ( let i = 0 ; i < arr . length ; i ++ ) {
169+ if ( arr [ i ] ) return arr [ i ]
170+ }
171+ return arr [ arr . length - 1 ]
172+ } ,
173+ and : ( arr ) => {
174+ for ( let i = 0 ; i < arr . length ; i ++ ) {
175+ if ( ! arr [ i ] ) return arr [ i ]
176+ }
177+ return arr [ arr . length - 1 ]
178+ } ,
150179 substr : ( [ string , from , end ] ) => {
151180 if ( end < 0 ) {
152181 const result = string . substr ( from )
@@ -163,7 +192,7 @@ const defaultMethods = {
163192 method : ( [ data , key , defaultValue ] , context , above , engine ) => {
164193 const notFound = defaultValue === undefined ? null : defaultValue
165194
166- const subProps = splitPath ( String ( key ) )
195+ const subProps = splitPathMemoized ( String ( key ) )
167196 for ( let i = 0 ; i < subProps . length ; i ++ ) {
168197 if ( data === null || data === undefined ) {
169198 return notFound
@@ -205,7 +234,7 @@ const defaultMethods = {
205234 }
206235 return null
207236 }
208- const subProps = splitPath ( String ( key ) )
237+ const subProps = splitPathMemoized ( String ( key ) )
209238 for ( let i = 0 ; i < subProps . length ; i ++ ) {
210239 if ( context === null || context === undefined ) {
211240 return notFound
@@ -815,7 +844,7 @@ defaultMethods.get.compile = function (data, buildState) {
815844 if ( key && typeof key === 'object' ) return false
816845
817846 key = key . toString ( )
818- const pieces = splitPath ( key )
847+ const pieces = splitPathMemoized ( key )
819848 if ( ! chainingSupported ) {
820849 return `(((a,b) => (typeof a === 'undefined' || a === null) ? b : a)(${ pieces . reduce (
821850 ( text , i ) => {
@@ -864,7 +893,7 @@ defaultMethods.var.compile = function (data, buildState) {
864893 buildState . useContext = true
865894 return false
866895 }
867- const pieces = splitPath ( key )
896+ const pieces = splitPathMemoized ( key )
868897 const [ top ] = pieces
869898 buildState . varTop . add ( top )
870899
0 commit comments