feat: compiled bytecode (#307)

* feat: compiled bytecode

* optimize bytecode

* add compiled expression struct

* add fetch fast and better abstraction

* fix

* rename evaluate_with for Expression<Unary>
This commit is contained in:
stefan-gorules
2025-02-10 10:07:24 +01:00
committed by GitHub
parent 019fc6e525
commit ae40aff163
22 changed files with 686 additions and 288 deletions
+51
View File
@@ -0,0 +1,51 @@
use pyo3::prelude::{PyDictMethods, PyListMethods};
use pyo3::types::{PyDict, PyList};
use pyo3::{Bound, IntoPyObject, IntoPyObjectExt, PyAny, PyErr, PyResult, Python};
use rust_decimal::prelude::ToPrimitive;
use zen_expression::Variable;
#[repr(transparent)]
#[derive(Clone, Debug)]
pub struct PyVariable(pub Variable);
pub fn variable_to_object<'py>(py: Python<'py>, val: &Variable) -> PyResult<Bound<'py, PyAny>> {
match val {
Variable::Null => py.None().into_bound_py_any(py),
Variable::Bool(b) => b.into_bound_py_any(py),
Variable::Number(n) => {
let of64 = n.to_f64().map(|i| i.into_bound_py_any(py));
let oi64 = n.to_i64().map(|i| i.into_bound_py_any(py));
let ou64 = n.to_u64().map(|i| i.into_bound_py_any(py));
of64.or(oi64).or(ou64).expect("number too large")
}
Variable::String(s) => s.into_bound_py_any(py),
Variable::Array(v) => {
let list = PyList::empty(py);
let b = v.borrow();
for item in b.iter() {
list.append(variable_to_object(py, item)?)?;
}
list.into_bound_py_any(py)
}
Variable::Object(m) => {
let dict = PyDict::new(py);
let b = m.borrow();
for (key, value) in b.iter() {
dict.set_item(key, variable_to_object(py, value)?)?;
}
dict.into_bound_py_any(py)
}
}
}
impl<'py> IntoPyObject<'py> for PyVariable {
type Target = PyAny;
type Output = Bound<'py, PyAny>;
type Error = PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
variable_to_object(py, &self.0)
}
}