1
1
use std:: { collections:: HashMap , fmt:: Display } ;
2
2
3
- use crate :: { CellValue , Sheet } ;
3
+ use crate :: { calc :: parser :: BinOp , CellValue , Sheet } ;
4
4
5
5
use super :: {
6
- parser:: { Call , Expr , Literal } ,
6
+ parser:: { Call , Closure , Expr , Literal } ,
7
7
Token ,
8
8
} ;
9
9
@@ -13,6 +13,19 @@ pub enum Interpret {
13
13
Text ( String ) ,
14
14
Values ( Vec < Interpret > ) ,
15
15
Bool ( bool ) ,
16
+ Closure ( Closure ) ,
17
+ }
18
+
19
+ impl Interpret {
20
+ fn get_type ( & self ) -> & ' static str {
21
+ match self {
22
+ Interpret :: Number ( _) => "Number" ,
23
+ Interpret :: Text ( _) => "Text" ,
24
+ Interpret :: Values ( _) => "Range" ,
25
+ Interpret :: Bool ( _) => "Bool" ,
26
+ Interpret :: Closure ( _) => "Closure" ,
27
+ }
28
+ }
16
29
}
17
30
18
31
#[ derive( PartialEq , Debug , Clone ) ]
@@ -24,6 +37,9 @@ pub enum InterpretError {
24
37
FunctionNotExist ,
25
38
InvalidFunction ,
26
39
InvalidArgument ,
40
+ ClosureBinOp ,
41
+ ClosureInvalidArg ,
42
+ ExpectedArg ( String ) ,
27
43
}
28
44
29
45
impl Display for InterpretError {
@@ -36,14 +52,21 @@ impl Display for InterpretError {
36
52
InterpretError :: FunctionNotExist => "Function does not exist" ,
37
53
InterpretError :: InvalidFunction => "Trying to call a function with invalid name" ,
38
54
InterpretError :: InvalidArgument => "Invalid argument for function" ,
55
+ InterpretError :: ClosureBinOp => todo ! ( ) ,
56
+ InterpretError :: ClosureInvalidArg => todo ! ( ) ,
57
+ InterpretError :: ExpectedArg ( _) => todo ! ( ) ,
39
58
} )
40
59
}
41
60
}
42
61
43
62
type CalcFunction = Box < dyn Fn ( & [ Interpret ] ) -> Result < Interpret , InterpretError > > ;
63
+ struct CalcFunctionImplement {
64
+ fun : CalcFunction ,
65
+ args_type : Vec < & ' static str > ,
66
+ }
44
67
45
68
struct FunctionRegistry {
46
- functions : HashMap < String , CalcFunction > ,
69
+ functions : HashMap < String , CalcFunctionImplement > ,
47
70
}
48
71
49
72
impl FunctionRegistry {
@@ -53,18 +76,34 @@ impl FunctionRegistry {
53
76
}
54
77
}
55
78
56
- fn register < F > ( & mut self , name : & str , func : F )
79
+ fn register < F > ( & mut self , name : & str , func : F , args_types : Vec < & ' static str > )
57
80
where
58
81
F : Fn ( & [ Interpret ] ) -> Result < Interpret , InterpretError > + ' static ,
59
82
{
60
- self . functions . insert ( name. to_string ( ) , Box :: new ( func) ) ;
83
+ let fun_insert = CalcFunctionImplement {
84
+ fun : Box :: new ( func) ,
85
+ args_type : args_types,
86
+ } ;
87
+ self . functions . insert ( name. to_string ( ) , fun_insert) ;
61
88
}
62
89
63
90
fn call ( & self , name : & str , args : & [ Interpret ] ) -> Result < Interpret , InterpretError > {
64
- self . functions
91
+ let function = self
92
+ . functions
65
93
. get ( name)
66
- . ok_or ( InterpretError :: FunctionNotExist )
67
- . and_then ( |f| f ( args) )
94
+ . ok_or ( InterpretError :: FunctionNotExist ) ?;
95
+
96
+ if function. args_type . len ( ) != args. len ( ) {
97
+ return Err ( InterpretError :: InvalidArgument ) ;
98
+ }
99
+
100
+ for ( expected_type, arg) in function. args_type . iter ( ) . zip ( args) {
101
+ if * expected_type != arg. get_type ( ) {
102
+ return Err ( InterpretError :: ExpectedArg ( expected_type. to_string ( ) ) ) ;
103
+ }
104
+ }
105
+
106
+ ( function. fun ) ( args)
68
107
}
69
108
}
70
109
@@ -81,6 +120,8 @@ fn count(args: &[Interpret]) -> Result<Interpret, InterpretError> {
81
120
}
82
121
Err ( InterpretError :: InvalidArgument )
83
122
}
123
+
124
+ //fn count_if(args: &[Interpret]) -> Result<Interpret, InterpretError> {}
84
125
pub struct Interpreter < ' a > {
85
126
function_registry : FunctionRegistry ,
86
127
sheet : & ' a Sheet ,
@@ -89,7 +130,7 @@ pub struct Interpreter<'a> {
89
130
impl < ' a > Interpreter < ' a > {
90
131
pub fn new ( sheet : & ' a Sheet ) -> Self {
91
132
let mut registry = FunctionRegistry :: new ( ) ;
92
- registry. register ( "count" , count) ;
133
+ registry. register ( "count" , count, vec ! [ "Range" ] ) ;
93
134
Self {
94
135
function_registry : registry,
95
136
sheet,
@@ -206,6 +247,7 @@ impl<'a> Interpreter<'a> {
206
247
None => Ok ( Interpret :: Text ( i. to_string ( ) ) ) ,
207
248
} ,
208
249
} ,
250
+ Expr :: Closure ( closure) => Ok ( Interpret :: Closure ( closure. clone ( ) ) ) ,
209
251
}
210
252
}
211
253
@@ -235,6 +277,102 @@ impl Display for Interpret {
235
277
. join ( "," ) ,
236
278
) ,
237
279
Interpret :: Bool ( b) => write ! ( f, "{}" , b) ,
280
+ Interpret :: Closure ( _) => todo ! ( ) ,
238
281
}
239
282
}
240
283
}
284
+
285
+ #[ cfg( test) ]
286
+ mod tests {
287
+
288
+ use crate :: calc:: interpreter:: Interpreter ;
289
+ use crate :: calc:: parser:: Parser ;
290
+ use crate :: { Cell , Sheet } ;
291
+
292
+ #[ test]
293
+ fn test_range_inter ( ) {
294
+ let mut sheet = Sheet :: new ( ) ;
295
+
296
+ sheet. insert (
297
+ ( 0 , 0 ) ,
298
+ Cell {
299
+ val : crate :: CellValue :: Number ( 10.0 ) ,
300
+ format : crate :: CellFormat { } ,
301
+ } ,
302
+ ) ;
303
+
304
+ sheet. insert (
305
+ ( 0 , 1 ) ,
306
+ Cell {
307
+ val : crate :: CellValue :: Number ( 20.0 ) ,
308
+ format : crate :: CellFormat { } ,
309
+ } ,
310
+ ) ;
311
+
312
+ let inter = Interpreter :: new ( & sheet) ;
313
+
314
+ let expr = Parser :: parse_string ( "(A1:A2)" . to_string ( ) ) . unwrap ( ) ;
315
+ let expr = inter. interpret ( & expr) . unwrap ( ) . to_string ( ) ;
316
+
317
+ let expected = String :: from ( "10,20" ) ;
318
+ assert_eq ! ( expr, expected) ;
319
+ }
320
+
321
+ #[ test]
322
+ fn test_count ( ) {
323
+ let mut sheet = Sheet :: new ( ) ;
324
+
325
+ sheet. insert (
326
+ ( 0 , 0 ) ,
327
+ Cell {
328
+ val : crate :: CellValue :: Number ( 10.0 ) ,
329
+ format : crate :: CellFormat { } ,
330
+ } ,
331
+ ) ;
332
+
333
+ sheet. insert (
334
+ ( 0 , 1 ) ,
335
+ Cell {
336
+ val : crate :: CellValue :: Number ( 20.0 ) ,
337
+ format : crate :: CellFormat { } ,
338
+ } ,
339
+ ) ;
340
+
341
+ let inter = Interpreter :: new ( & sheet) ;
342
+
343
+ let expr = Parser :: parse_string ( "count((A1:A2))" . to_string ( ) ) . unwrap ( ) ;
344
+ let expr = inter. interpret ( & expr) . unwrap ( ) . to_string ( ) ;
345
+
346
+ let expected = String :: from ( "30" ) ;
347
+ assert_eq ! ( expr, expected) ;
348
+ }
349
+
350
+ //[test]
351
+ //fn test_count_if() {
352
+ //let mut sheet = Sheet::new();
353
+
354
+ //sheet.insert(
355
+ //(0, 0),
356
+ //Cell {
357
+ //val: crate::CellValue::Number(10.0),
358
+ //format: crate::CellFormat {},
359
+ //},
360
+ //);
361
+
362
+ //sheet.insert(
363
+ //(0, 1),
364
+ //Cell {
365
+ //val: crate::CellValue::Number(20.0),
366
+ //format: crate::CellFormat {},
367
+ //},
368
+ //);
369
+
370
+ //let inter = Interpreter::new(&sheet);
371
+
372
+ //let expr = Parser::parse_string("count_if(A1:A2, |v| v > 10)".to_string()).unwrap();
373
+ //let expr = inter.interpret(&expr).unwrap().to_string();
374
+
375
+ //let expected = String::from("20");
376
+ //assert_eq!(expr, expected);
377
+ //}
378
+ }
0 commit comments