Skip to content

Commit 66fe662

Browse files
committed
Fixed function arguments
1 parent 84fe8e1 commit 66fe662

File tree

5 files changed

+269
-82
lines changed

5 files changed

+269
-82
lines changed

src/calc/interpreter.rs

+147-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use std::{collections::HashMap, fmt::Display};
22

3-
use crate::{CellValue, Sheet};
3+
use crate::{calc::parser::BinOp, CellValue, Sheet};
44

55
use super::{
6-
parser::{Call, Expr, Literal},
6+
parser::{Call, Closure, Expr, Literal},
77
Token,
88
};
99

@@ -13,6 +13,19 @@ pub enum Interpret {
1313
Text(String),
1414
Values(Vec<Interpret>),
1515
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+
}
1629
}
1730

1831
#[derive(PartialEq, Debug, Clone)]
@@ -24,6 +37,9 @@ pub enum InterpretError {
2437
FunctionNotExist,
2538
InvalidFunction,
2639
InvalidArgument,
40+
ClosureBinOp,
41+
ClosureInvalidArg,
42+
ExpectedArg(String),
2743
}
2844

2945
impl Display for InterpretError {
@@ -36,14 +52,21 @@ impl Display for InterpretError {
3652
InterpretError::FunctionNotExist => "Function does not exist",
3753
InterpretError::InvalidFunction => "Trying to call a function with invalid name",
3854
InterpretError::InvalidArgument => "Invalid argument for function",
55+
InterpretError::ClosureBinOp => todo!(),
56+
InterpretError::ClosureInvalidArg => todo!(),
57+
InterpretError::ExpectedArg(_) => todo!(),
3958
})
4059
}
4160
}
4261

4362
type CalcFunction = Box<dyn Fn(&[Interpret]) -> Result<Interpret, InterpretError>>;
63+
struct CalcFunctionImplement {
64+
fun: CalcFunction,
65+
args_type: Vec<&'static str>,
66+
}
4467

4568
struct FunctionRegistry {
46-
functions: HashMap<String, CalcFunction>,
69+
functions: HashMap<String, CalcFunctionImplement>,
4770
}
4871

4972
impl FunctionRegistry {
@@ -53,18 +76,34 @@ impl FunctionRegistry {
5376
}
5477
}
5578

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>)
5780
where
5881
F: Fn(&[Interpret]) -> Result<Interpret, InterpretError> + 'static,
5982
{
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);
6188
}
6289

6390
fn call(&self, name: &str, args: &[Interpret]) -> Result<Interpret, InterpretError> {
64-
self.functions
91+
let function = self
92+
.functions
6593
.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)
68107
}
69108
}
70109

@@ -81,6 +120,8 @@ fn count(args: &[Interpret]) -> Result<Interpret, InterpretError> {
81120
}
82121
Err(InterpretError::InvalidArgument)
83122
}
123+
124+
//fn count_if(args: &[Interpret]) -> Result<Interpret, InterpretError> {}
84125
pub struct Interpreter<'a> {
85126
function_registry: FunctionRegistry,
86127
sheet: &'a Sheet,
@@ -89,7 +130,7 @@ pub struct Interpreter<'a> {
89130
impl<'a> Interpreter<'a> {
90131
pub fn new(sheet: &'a Sheet) -> Self {
91132
let mut registry = FunctionRegistry::new();
92-
registry.register("count", count);
133+
registry.register("count", count, vec!["Range"]);
93134
Self {
94135
function_registry: registry,
95136
sheet,
@@ -206,6 +247,7 @@ impl<'a> Interpreter<'a> {
206247
None => Ok(Interpret::Text(i.to_string())),
207248
},
208249
},
250+
Expr::Closure(closure) => Ok(Interpret::Closure(closure.clone())),
209251
}
210252
}
211253

@@ -235,6 +277,102 @@ impl Display for Interpret {
235277
.join(","),
236278
),
237279
Interpret::Bool(b) => write!(f, "{}", b),
280+
Interpret::Closure(_) => todo!(),
238281
}
239282
}
240283
}
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+
}

src/calc/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub enum Token {
2525
False,
2626
LeftParen,
2727
RightParen,
28+
Bar,
2829
}
2930

3031
impl Display for Token {
@@ -49,6 +50,8 @@ impl Display for Token {
4950
Token::False => "FALSE",
5051
Token::LeftParen => "(",
5152
Token::RightParen => ")",
53+
Token::EqualEqual => "==",
54+
Token::Bar => "|",
5255
_ => unreachable!(),
5356
}),
5457
};

0 commit comments

Comments
 (0)