1+ import type { CellRenderFn , FormulaMap } from '../types' ;
12import { expr2xy , xy2expr } from './alphabet' ;
23import { numberCalc } from './helper' ;
34
45// Converting infix expression to a suffix expression
56// src: AVERAGE(SUM(A1,A2), B1) + 50 + B20
67// return: [A1, A2], SUM[, B1],AVERAGE,50,+,B20,+
7- export const infixExprToSuffixExpr = ( src ) => {
8+ export const infixExprToSuffixExpr = ( src : string ) : ( string | [ string , number ] ) [ ] => {
89 const operatorStack = [ ] ;
910 const stack = [ ] ;
1011 let subStrs = [ ] ; // SUM, A1, B2, 50 ...
@@ -47,20 +48,24 @@ export const infixExprToSuffixExpr = (src) => {
4748 const [ sx , sy ] = expr2xy ( stack . pop ( ) ) ;
4849 // console.log('::', sx, sy, ex, ey);
4950 let rangelen = 0 ;
50- for ( let x = sx ; x <= ex ; x += 1 ) {
51- for ( let y = sy ; y <= ey ; y += 1 ) {
52- stack . push ( xy2expr ( x , y ) ) ;
53- rangelen += 1 ;
54- }
51+ for ( let x = sx ; x <= ex ; x += 1 ) {
52+ for ( let y = sy ; y <= ey ; y += 1 ) {
53+ stack . push ( xy2expr ( x , y ) ) ;
54+ rangelen += 1 ;
5555 }
56+ }
57+ if ( typeof c1 === 'string' ) {
5658 stack . push ( [ c1 , rangelen ] ) ;
59+ }
5760 } catch {
5861 // console.log(e);
5962 }
6063 } else if ( fnArgType === 1 || fnArgType === 3 ) {
6164 if ( fnArgType === 3 ) stack . push ( fnArgOperator ) ;
6265 // fn argument => A1,A2,B5
63- stack . push ( [ c1 , fnArgsLen ] ) ;
66+ if ( typeof c1 === 'string' ) {
67+ stack . push ( [ c1 , fnArgsLen ] ) ;
68+ }
6469 fnArgsLen = 1 ;
6570 } else {
6671 // console.log('c1:', c1, fnArgType, stack, operatorStack);
@@ -123,7 +128,7 @@ export const infixExprToSuffixExpr = (src) => {
123128 return stack ;
124129} ;
125130
126- const evalSubExpr = ( subExpr , cellRender ) => {
131+ const evalSubExpr = ( subExpr : string , cellRender : CellRenderFn ) : string | number => {
127132 const [ fl ] = subExpr ;
128133 let expr = subExpr ;
129134 if ( fl === '"' ) {
@@ -137,16 +142,25 @@ const evalSubExpr = (subExpr, cellRender) => {
137142 if ( expr [ 0 ] >= '0' && expr [ 0 ] <= '9' ) {
138143 return ret * Number ( expr ) ;
139144 }
140- const [ x , y ] = expr2xy ( expr ) ;
141- return ret * cellRender ( x , y ) ;
145+ try {
146+ const [ x , y ] = expr2xy ( expr ) ;
147+ return ret * Number ( cellRender ( x , y ) ) ;
148+ } catch {
149+ return 0 ;
150+ }
142151} ;
143152
144153// evaluate the suffix expression
145154// srcStack: <= infixExprToSufixExpr
146155// formulaMap: {'SUM': {}, ... }
147156// cellRender: (x, y) => {}
148- const evalSuffixExpr = ( srcStack , formulaMap , cellRender , cellList ) => {
149- const stack = [ ] ;
157+ const evalSuffixExpr = (
158+ srcStack : ( string | [ string , number ] ) [ ] ,
159+ formulaMap : FormulaMap ,
160+ cellRender : CellRenderFn ,
161+ cellList : string [ ] ,
162+ ) : unknown => {
163+ const stack : unknown [ ] = [ ] ;
150164 // console.log(':::::formulaMap:', formulaMap);
151165 for ( let i = 0 ; i < srcStack . length ; i += 1 ) {
152166 // console.log(':::>>>', srcStack[i]);
@@ -172,18 +186,19 @@ const evalSuffixExpr = (srcStack, formulaMap, cellRender, cellList) => {
172186 let top = stack . pop ( ) ;
173187 if ( ! Number . isNaN ( top ) ) top = Number ( top ) ;
174188 let left = stack . pop ( ) ;
175- if ( ! Number . isNaN ( left ) ) left = Number ( left ) ;
189+ if ( typeof left === 'number' && ! Number . isNaN ( left ) ) left = Number ( left ) ;
190+ if ( typeof top === 'number' && ! Number . isNaN ( top ) ) top = Number ( top ) ;
176191 let ret = false ;
177192 if ( fc === '=' ) {
178193 ret = left === top ;
179194 } else if ( expr === '>' ) {
180- ret = left > top ;
195+ ret = ( left as number ) > ( top as number ) ;
181196 } else if ( expr === '>=' ) {
182- ret = left >= top ;
197+ ret = ( left as number ) >= ( top as number ) ;
183198 } else if ( expr === '<' ) {
184- ret = left < top ;
199+ ret = ( left as number ) < ( top as number ) ;
185200 } else if ( expr === '<=' ) {
186- ret = left <= top ;
201+ ret = ( left as number ) <= ( top as number ) ;
187202 }
188203 stack . push ( ret ) ;
189204 } else if ( Array . isArray ( expr ) ) {
@@ -208,15 +223,22 @@ const evalSuffixExpr = (srcStack, formulaMap, cellRender, cellList) => {
208223 return stack [ 0 ] ;
209224} ;
210225
211- export const cellRender = ( src , formulaMap , getCellText , cellList = [ ] ) => {
226+ export const cellRender = (
227+ src : string ,
228+ formulaMap : FormulaMap ,
229+ getCellText : CellRenderFn ,
230+ cellList : string [ ] = [ ] ,
231+ ) : unknown => {
212232 if ( src [ 0 ] === '=' ) {
213233 const stack = infixExprToSuffixExpr ( src . substring ( 1 ) ) ;
214234 if ( stack . length <= 0 ) return src ;
215235 return evalSuffixExpr (
216236 stack ,
217237 formulaMap ,
218- ( x , y ) =>
219- cellRender ( getCellText ( x , y ) , formulaMap , getCellText , cellList ) ,
238+ ( x : number , y : number ) : string | number => {
239+ const text = getCellText ( x , y ) ;
240+ return cellRender ( String ( text ) , formulaMap , getCellText , cellList ) as string | number ;
241+ } ,
220242 cellList ,
221243 ) ;
222244 }
0 commit comments