Skip to content

Commit

Permalink
dedicated pre-aggregated "closure" op
Browse files Browse the repository at this point in the history
It also includes a list of parameter names for proper parameter evaluation
  • Loading branch information
divarvel committed Jan 2, 2024
1 parent ccc8612 commit 91c852a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 61 deletions.
87 changes: 31 additions & 56 deletions biscuit-auth/src/datalog/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ pub enum Op {
Value(Term),
Unary(Unary),
Binary(Binary),
Suspend,
Unsuspend,
Param(u8),
Param(String),
Closure(Vec<String>, Vec<Op>),
}

/// Unary operation code
Expand Down Expand Up @@ -91,35 +90,36 @@ impl Binary {
&self,
left: Term,
mut right: Vec<Op>,
params: &[String],
ops: &mut Vec<Op>,
values: &HashMap<u32, Term>,
symbols: &mut TemporarySymbolTable,
) -> Result<Term, error::Expression> {
match (self, left) {
(Binary::Or, Term::Bool(true)) => Ok(Term::Bool(true)),
(Binary::Or, Term::Bool(false)) => {
match (self, left, params) {
(Binary::Or, Term::Bool(true), []) => Ok(Term::Bool(true)),
(Binary::Or, Term::Bool(false), []) => {
ops.push(Op::Binary(Binary::Or));
right.reverse();
for op in right {
ops.push(op);
}
Ok(Term::Bool(false))
}
(Binary::And, Term::Bool(false)) => Ok(Term::Bool(false)),
(Binary::And, Term::Bool(true)) => {
(Binary::And, Term::Bool(false), []) => Ok(Term::Bool(false)),
(Binary::And, Term::Bool(true), []) => {
ops.push(Op::Binary(Binary::And));
for op in right {
ops.push(op);
}
Ok(Term::Bool(true))
}
(Binary::Any, Term::Set(set_values)) => {
(Binary::Any, Term::Set(set_values), [param_name]) => {
for value in set_values.iter() {
let ops = right
.clone()
.iter()
.map(|op| match op {
Op::Param(0) => Op::Value(value.clone()),
Op::Param(p) if p == param_name => Op::Value(value.clone()),
_ => op.clone(),
})
.collect::<Vec<_>>();
Expand All @@ -132,7 +132,7 @@ impl Binary {
}
Ok(Term::Bool(false))
}
(_, _) => Err(error::Expression::InvalidType),
(_, _, _) => Err(error::Expression::InvalidType),
}
}
fn evaluate(
Expand Down Expand Up @@ -297,7 +297,7 @@ impl Binary {

#[derive(Clone, Debug)]
enum StackElem {
Closure(Vec<Op>),
Closure(Vec<String>, Vec<Op>),
Term(Term),
}

Expand All @@ -308,36 +308,14 @@ impl Expression {
symbols: &mut TemporarySymbolTable,
) -> Result<Term, error::Expression> {
let mut stack: Vec<StackElem> = Vec::new();
let mut depth = 0usize;

let mut ops = self.ops.clone();
ops.reverse();

while let Some(op) = ops.pop() {
println!("ops: {ops:?}");
println!("op: {:?}\t| stack: {:?}", op, stack);
if depth == 1 && op == Op::Unsuspend {
match stack.last_mut() {
Some(StackElem::Closure(_)) => {
depth = 0;
continue;
}
_ => return Err(error::Expression::InvalidStack),
}
} else if depth > 0 {
match stack.last_mut() {
Some(StackElem::Closure(ops)) => {
ops.push(op.clone());
if op == Op::Suspend {
depth += 1;
} else if op == Op::Unsuspend {
depth -= 1;
}
continue;
}
_ => return Err(error::Expression::InvalidStack),
}
}

match op {
Op::Value(Term::Variable(i)) => match values.get(&i) {
Some(term) => stack.push(StackElem::Term(term.clone())),
Expand All @@ -361,22 +339,21 @@ impl Expression {
.push(StackElem::Term(
binary.evaluate(left_term, right_term, symbols)?,
)),
(Some(StackElem::Closure(right_ops)), Some(StackElem::Term(left_term))) => {
stack.push(StackElem::Term(binary.evaluate_with_closure(
left_term, right_ops, &mut ops, values, symbols,
)?))
}
(
Some(StackElem::Closure(params, right_ops)),
Some(StackElem::Term(left_term)),
) => stack.push(StackElem::Term(binary.evaluate_with_closure(
left_term, right_ops, &params, &mut ops, values, symbols,
)?)),

_ => {
//println!("expected two values on the stack");
return Err(error::Expression::InvalidStack);
}
},
Op::Suspend => {
stack.push(StackElem::Closure(vec![]));
depth = 1;
Op::Closure(param, ops) => {
stack.push(StackElem::Closure(param, ops));
}
Op::Unsuspend => {}
Op::Param(_) => todo!(),
}
}
Expand Down Expand Up @@ -407,8 +384,7 @@ impl Expression {
(Some(right), Some(left)) => stack.push(binary.print(left, right, symbols)),
_ => return None,
},
Op::Suspend => {}
Op::Unsuspend => {}
Op::Closure(_, _) => stack.push("todo".to_owned()),
Op::Param(_) => {}
}
}
Expand Down Expand Up @@ -600,13 +576,14 @@ mod tests {

let ops2 = vec![
Op::Value(Term::Bool(false)),
Op::Suspend,
Op::Value(Term::Bool(true)),
Op::Suspend,
Op::Value(Term::Bool(true)),
Op::Unsuspend,
Op::Binary(Binary::And),
Op::Unsuspend,
Op::Closure(
vec![],
vec![
Op::Value(Term::Bool(true)),
Op::Closure(vec![], vec![Op::Value(Term::Bool(true))]),
Op::Binary(Binary::And),
],
),
Op::Binary(Binary::Or),
];
let e2 = Expression { ops: ops2 };
Expand All @@ -622,9 +599,7 @@ mod tests {

let ops1 = vec![
Op::Value(Term::Set([Term::Bool(false), Term::Bool(true)].into())),
Op::Suspend,
Op::Param(0),
Op::Unsuspend,
Op::Closure(vec!["0".to_owned()], vec![Op::Param("0".to_owned())]),
Op::Binary(Binary::Any),
];
let e1 = Expression { ops: ops1 };
Expand Down
5 changes: 2 additions & 3 deletions biscuit-auth/src/format/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,9 +620,8 @@ pub mod v2 {
} as i32,
})
}
Op::Suspend => todo!(),
Op::Unsuspend => todo!(),
Op::Param(_)=> todo!(),
Op::Closure(_, _) => todo!(),
Op::Param(_) => todo!(),
};

schema::Op {
Expand Down
3 changes: 1 addition & 2 deletions biscuit-auth/src/token/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -920,8 +920,7 @@ impl Convert<datalog::Op> for Op {
datalog::Op::Value(t) => Op::Value(Term::convert_from(t, symbols)?),
datalog::Op::Unary(u) => Op::Unary(u.clone()),
datalog::Op::Binary(b) => Op::Binary(b.clone()),
datalog::Op::Suspend => todo!(),
datalog::Op::Unsuspend => todo!(),
datalog::Op::Closure(_, _) => todo!(),
datalog::Op::Param(_) => todo!(),
})
}
Expand Down

0 comments on commit 91c852a

Please sign in to comment.