mirror of
https://github.com/urbit/ares.git
synced 2024-11-22 06:32:47 +03:00
commit
8e45025228
@ -94,6 +94,11 @@ pub const URBIT_HOT_STATE: &[HotEntry] = &[
|
||||
1,
|
||||
jet_lent,
|
||||
),
|
||||
(
|
||||
&[K_139, Left(b"one"), Left(b"two"), Left(b"turn")],
|
||||
1,
|
||||
jet_turn,
|
||||
),
|
||||
(
|
||||
&[K_139, Left(b"one"), Left(b"two"), Left(b"zing")],
|
||||
1,
|
||||
|
@ -1,9 +1,11 @@
|
||||
/** Text processing jets
|
||||
*/
|
||||
use crate::interpreter::Context;
|
||||
use crate::interpreter::{interpret, Context, Error};
|
||||
use crate::jets::util::slot;
|
||||
use crate::jets::Result;
|
||||
use crate::noun::{Noun, D};
|
||||
use crate::jets::{JetErr, Result};
|
||||
use crate::noun::{Cell, Noun, D, T};
|
||||
use bitvec::order::Lsb0;
|
||||
use bitvec::slice::BitSlice;
|
||||
|
||||
crate::gdb!();
|
||||
|
||||
@ -24,6 +26,97 @@ pub fn jet_zing(context: &mut Context, subject: Noun) -> Result {
|
||||
util::zing(stack, list)
|
||||
}
|
||||
|
||||
pub fn jet_turn(context: &mut Context, subject: Noun) -> Result {
|
||||
let sample = slot(subject, 6)?;
|
||||
let mut list = slot(sample, 2)?;
|
||||
let mut gate = slot(sample, 3)?;
|
||||
let mut gate_battery = slot(gate, 2)?;
|
||||
let gate_context = slot(gate, 7)?;
|
||||
let mut res = D(0);
|
||||
let mut dest: *mut Noun = &mut res; // Mutable pointer because we cannot guarantee initialized
|
||||
|
||||
// Since the gate doesn't change, we can do a single jet check and use that through the whole
|
||||
// loop
|
||||
if let Some((jet, _path)) = context
|
||||
.warm
|
||||
.find_jet(&mut context.stack, &mut gate, &mut gate_battery)
|
||||
.filter(|(_jet, mut path)| {
|
||||
// check that 7 is a prefix of the parent battery axis,
|
||||
// to ensure that the sample (axis 6) is not part of the jet match.
|
||||
//
|
||||
// XX TODO this check is pessimized since there could be multiple ways to match the
|
||||
// jet and we only actually match one of them, but we check all of them and run
|
||||
// unjetted if any have an axis outside 7.
|
||||
let axis_7_bits: &BitSlice<u64, Lsb0> = BitSlice::from_element(&7u64);
|
||||
let batteries_list = context.cold.find(&mut context.stack, &mut path);
|
||||
let mut ret = true;
|
||||
for mut batteries in batteries_list {
|
||||
if let Some((_battery, parent_axis)) = batteries.next() {
|
||||
let parent_axis_prefix_bits = &parent_axis.as_bitslice()[0..3];
|
||||
if parent_axis_prefix_bits == axis_7_bits {
|
||||
continue;
|
||||
} else {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret
|
||||
})
|
||||
{
|
||||
loop {
|
||||
if let Ok(list_cell) = list.as_cell() {
|
||||
list = list_cell.tail();
|
||||
let element_subject = T(
|
||||
&mut context.stack,
|
||||
&[gate_battery, list_cell.head(), gate_context],
|
||||
);
|
||||
unsafe {
|
||||
let (new_cell, new_mem) = Cell::new_raw_mut(&mut context.stack);
|
||||
(*new_mem).head = jet(context, element_subject)?;
|
||||
*dest = new_cell.as_noun();
|
||||
dest = &mut (*new_mem).tail;
|
||||
}
|
||||
} else {
|
||||
if unsafe { !list.raw_equals(D(0)) } {
|
||||
return Err(JetErr::Fail(Error::Deterministic(D(0))));
|
||||
}
|
||||
unsafe {
|
||||
*dest = D(0);
|
||||
};
|
||||
return Ok(res);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
loop {
|
||||
if let Ok(list_cell) = list.as_cell() {
|
||||
list = list_cell.tail();
|
||||
let element_subject = T(
|
||||
&mut context.stack,
|
||||
&[gate_battery, list_cell.head(), gate_context],
|
||||
);
|
||||
unsafe {
|
||||
let (new_cell, new_mem) = Cell::new_raw_mut(&mut context.stack);
|
||||
(*new_mem).head = interpret(context, element_subject, gate_battery)?;
|
||||
*dest = new_cell.as_noun();
|
||||
dest = &mut (*new_mem).tail;
|
||||
}
|
||||
} else {
|
||||
if unsafe { !list.raw_equals(D(0)) } {
|
||||
return Err(JetErr::Fail(Error::Deterministic(D(0))));
|
||||
}
|
||||
unsafe {
|
||||
*dest = D(0);
|
||||
};
|
||||
return Ok(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
use crate::interpreter::Error;
|
||||
use crate::jets::{JetErr, Result};
|
||||
|
Loading…
Reference in New Issue
Block a user