Skip to content

Commit fc3a325

Browse files
committed
implement interpreter
1 parent 45d5f71 commit fc3a325

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

internal/interpreter/api.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use i_slint_core::model::{Model, ModelExt, ModelRc};
1111
use i_slint_core::window::WindowInner;
1212
use i_slint_core::{PathData, SharedVector};
1313
use smol_str::SmolStr;
14+
use std::cell::RefCell;
1415
use std::collections::HashMap;
1516
use std::future::Future;
1617
use std::path::{Path, PathBuf};
@@ -28,6 +29,7 @@ pub use i_slint_core::graphics::{
2829
use i_slint_core::items::*;
2930

3031
use crate::dynamic_item_tree::{ErasedItemTreeBox, WindowOptions};
32+
use crate::eval::EvalLocalContext;
3133

3234
/// This enum represents the different public variants of the [`Value`] enum, without
3335
/// the contained values.
@@ -128,6 +130,8 @@ pub enum Value {
128130
#[doc(hidden)]
129131
/// Correspond to the `component-factory` type in .slint
130132
ComponentFactory(ComponentFactory) = 12,
133+
/// A predicate
134+
Predicate(Rc<RefCell<dyn FnMut(&mut EvalLocalContext, &Value) -> Value>>) = 13,
131135
}
132136

133137
impl Value {
@@ -173,6 +177,7 @@ impl PartialEq for Value {
173177
Value::ComponentFactory(lhs) => {
174178
matches!(other, Value::ComponentFactory(rhs) if lhs == rhs)
175179
}
180+
Value::Predicate(p) => matches!(other, Value::Predicate(q) if Rc::ptr_eq(p, q)),
176181
}
177182
}
178183
}
@@ -197,6 +202,7 @@ impl std::fmt::Debug for Value {
197202
Value::EnumerationValue(n, v) => write!(f, "Value::EnumerationValue({n:?}, {v:?})"),
198203
Value::LayoutCache(v) => write!(f, "Value::LayoutCache({v:?})"),
199204
Value::ComponentFactory(factory) => write!(f, "Value::ComponentFactory({factory:?})"),
205+
Value::Predicate(_) => write!(f, "Value::Predicate(...)"),
200206
}
201207
}
202208
}
@@ -239,6 +245,7 @@ declare_value_conversion!(PathData => [PathData]);
239245
declare_value_conversion!(EasingCurve => [i_slint_core::animations::EasingCurve]);
240246
declare_value_conversion!(LayoutCache => [SharedVector<f32>] );
241247
declare_value_conversion!(ComponentFactory => [ComponentFactory] );
248+
declare_value_conversion!(Predicate => [Rc<RefCell<dyn FnMut(&mut EvalLocalContext, &Value) -> Value>>]);
242249

243250
/// Implement From / TryFrom for Value that convert a `struct` to/from `Value::Struct`
244251
macro_rules! declare_value_struct_conversion {

internal/interpreter/eval.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use i_slint_core as corelib;
2222
use i_slint_core::input::FocusReason;
2323
use i_slint_core::items::ItemRc;
2424
use smol_str::SmolStr;
25+
use std::cell::RefCell;
2526
use std::collections::HashMap;
2627
use std::rc::Rc;
2728

@@ -408,7 +409,17 @@ pub fn eval_expression(expression: &Expression, local_context: &mut EvalLocalCon
408409
}
409410
Expression::EmptyComponentFactory => Value::ComponentFactory(Default::default()),
410411
Expression::DebugHook { expression, .. } => eval_expression(expression, local_context),
411-
Expression::Predicate { arg_name, expression } => todo!(),
412+
Expression::Predicate { arg_name, expression } => {
413+
let arg_name = arg_name.clone();
414+
let expression = expression.clone();
415+
let predicate: Rc<RefCell<dyn Fn(&mut EvalLocalContext<'_, '_>, &Value) -> Value + 'static>> =
416+
Rc::new(RefCell::new(move |local_context: &mut EvalLocalContext<'_, '_>, value: &Value| {
417+
local_context.local_variables.insert(arg_name.clone(), value.clone());
418+
eval_expression(&expression, local_context)
419+
}));
420+
421+
Value::Predicate(predicate)
422+
},
412423
}
413424
}
414425

@@ -1369,8 +1380,37 @@ fn call_builtin_function(
13691380
panic!("internal error: argument to RestartTimer must be an element")
13701381
}
13711382
}
1372-
BuiltinFunction::ArrayAny => todo!(),
1373-
BuiltinFunction::ArrayAll => todo!(),
1383+
BuiltinFunction::ArrayAny => {
1384+
let model: ModelRc<Value> =
1385+
eval_expression(&arguments[0], local_context).try_into().unwrap();
1386+
let predicate: Rc<RefCell<dyn FnMut(&mut EvalLocalContext, &Value) -> Value>> =
1387+
eval_expression(&arguments[1], local_context).try_into().unwrap();
1388+
let mut predicate = predicate.borrow_mut();
1389+
1390+
for x in model.iter() {
1391+
if predicate(local_context, &x).try_into().unwrap() {
1392+
return Value::Bool(true);
1393+
}
1394+
}
1395+
1396+
Value::Bool(false)
1397+
}
1398+
BuiltinFunction::ArrayAll => {
1399+
let model: ModelRc<Value> =
1400+
eval_expression(&arguments[0], local_context).try_into().unwrap();
1401+
let predicate: Rc<RefCell<dyn FnMut(&mut EvalLocalContext, &Value) -> Value>> =
1402+
eval_expression(&arguments[1], local_context).try_into().unwrap();
1403+
let mut predicate = predicate.borrow_mut();
1404+
1405+
for x in model.iter() {
1406+
let result: bool = predicate(local_context, &x).try_into().unwrap();
1407+
if !result {
1408+
return Value::Bool(false);
1409+
}
1410+
}
1411+
1412+
Value::Bool(true)
1413+
}
13741414
}
13751415
}
13761416

0 commit comments

Comments
 (0)