mirror of
https://github.com/urbit/ares.git
synced 2024-11-23 09:06:23 +03:00
ares: refactor hints to use option; fix hint tag bug
This commit is contained in:
parent
b804a549a8
commit
bae335275b
@ -318,28 +318,27 @@ pub fn interpret(
|
||||
}
|
||||
}
|
||||
Nock11ComputeHint => {
|
||||
let hint = *stack.local_noun_pointer(1);
|
||||
if let Ok(hint_cell) = hint.as_cell() {
|
||||
let formula = *stack.local_noun_pointer(2);
|
||||
if let Ok(found) =
|
||||
match_pre_hint(stack, newt, subject, hint_cell, formula, &cache)
|
||||
{
|
||||
res = found;
|
||||
let hint = (*stack.local_noun_pointer(1))
|
||||
.as_cell()
|
||||
.expect("IMPOSSIBLE: tried to compute a dynamic hint but hint is an atom");
|
||||
let formula = *stack.local_noun_pointer(2);
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.frame_pop();
|
||||
} else {
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock11ComputeResult);
|
||||
push_formula(stack, hint_cell.tail());
|
||||
}
|
||||
if let Some(found) =
|
||||
match_hint_pre_hint(stack, newt, subject, hint, formula, &cache)
|
||||
{
|
||||
res = found;
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
stack.frame_pop();
|
||||
} else {
|
||||
panic!("IMPOSSIBLE: tried to compute a dynamic hint but hint is an atom");
|
||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock11ComputeResult);
|
||||
push_formula(stack, hint.tail());
|
||||
}
|
||||
}
|
||||
Nock11ComputeResult => {
|
||||
let hint = *stack.local_noun_pointer(1);
|
||||
if let Ok(found) = match_post_hint(stack, newt, subject, hint, res) {
|
||||
|
||||
if let Some(found) = match_hint_pre_nock(stack, newt, subject, hint, res) {
|
||||
res = found;
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
@ -353,7 +352,11 @@ pub fn interpret(
|
||||
}
|
||||
Nock11Done => {
|
||||
let hint = *stack.local_noun_pointer(1);
|
||||
let _ = match_post_hinted(stack, subject, hint, res, &mut cache);
|
||||
|
||||
if let Some(found) = match_hint_post_nock(stack, subject, hint, res, &mut cache)
|
||||
{
|
||||
res = found;
|
||||
}
|
||||
|
||||
stack.preserve(&mut cache);
|
||||
stack.preserve(&mut res);
|
||||
@ -638,23 +641,24 @@ pub fn inc(stack: &mut NockStack, atom: Atom) -> Atom {
|
||||
}
|
||||
}
|
||||
|
||||
/** Match hints which apply before the formula is evaluated */
|
||||
fn match_pre_hint(
|
||||
/** Match dynamic hints before the hint formula is evaluated */
|
||||
fn match_hint_pre_hint(
|
||||
stack: &mut NockStack,
|
||||
newt: &mut Option<&mut Newt>,
|
||||
subject: Noun,
|
||||
cell: Cell,
|
||||
hint: Cell,
|
||||
formula: Noun,
|
||||
cache: &Hamt<Noun>,
|
||||
) -> Result<Noun, ()> {
|
||||
let direct = cell.head().as_direct()?;
|
||||
match direct.data() {
|
||||
) -> Option<Noun> {
|
||||
let tag = hint.head().direct()?;
|
||||
|
||||
match tag.data() {
|
||||
// %sham hints are scaffolding until we have a real jet dashboard
|
||||
tas!(b"sham") => {
|
||||
let jet_formula = cell.tail().as_cell()?;
|
||||
let jet_formula = hint.tail().cell()?;
|
||||
let jet_name = jet_formula.tail();
|
||||
|
||||
let jet = jets::get_jet(jet_name).ok_or(())?;
|
||||
let jet = jets::get_jet(jet_name)?;
|
||||
if let Ok(mut jet_res) = jet(stack, subject) {
|
||||
// if in test mode, check that the jet returns the same result as the raw nock
|
||||
if jets::get_jet_test_mode(jet_name) {
|
||||
@ -664,69 +668,73 @@ fn match_pre_hint(
|
||||
"\rJet {} failed, raw: {}, jetted: {}",
|
||||
jet_name, nock_res, jet_res
|
||||
);
|
||||
return Err(());
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Ok(jet_res)
|
||||
Some(jet_res)
|
||||
} else {
|
||||
// Print jet errors and punt to Nock
|
||||
eprintln!("\rJet {} failed", jet_name);
|
||||
Err(())
|
||||
eprintln!("\rJet {} failed: ", jet_name);
|
||||
None
|
||||
}
|
||||
}
|
||||
tas!(b"memo") => {
|
||||
let formula = unsafe { *stack.local_noun_pointer(2) };
|
||||
let mut key = Cell::new(stack, subject, formula).as_noun();
|
||||
if let Some(res) = cache.lookup(stack, &mut key) {
|
||||
Ok(res)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
cache.lookup(stack, &mut key)
|
||||
}
|
||||
_ => Err(()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/** Match static hints and dynamic hints after they're evaluated */
|
||||
fn match_post_hint(
|
||||
/** Match static and dynamic hints before the nock formula is evaluated */
|
||||
fn match_hint_pre_nock(
|
||||
stack: &mut NockStack,
|
||||
newt: &mut Option<&mut Newt>,
|
||||
_subject: Noun,
|
||||
hint: Noun,
|
||||
res: Noun,
|
||||
) -> Result<Noun, ()> {
|
||||
let direct = hint.as_cell()?.head().as_direct()?;
|
||||
match direct.data() {
|
||||
) -> Option<Noun> {
|
||||
let tag = hint
|
||||
.as_either_atom_cell()
|
||||
.either(|a| a.direct(), |c| c.head().direct())?;
|
||||
|
||||
match tag.data() {
|
||||
tas!(b"slog") => {
|
||||
let slog_cell = res.as_cell()?;
|
||||
let pri = slog_cell.head().as_direct()?.data();
|
||||
let slog_cell = res.cell()?;
|
||||
let pri = slog_cell.head().direct()?.data();
|
||||
let tank = slog_cell.tail();
|
||||
if let Some(not) = newt {
|
||||
not.slog(stack, pri, tank);
|
||||
} else {
|
||||
println!("slog: {} {}", pri, tank);
|
||||
println!("raw slog: {} {}", pri, tank);
|
||||
}
|
||||
Err(())
|
||||
|
||||
None
|
||||
}
|
||||
_ => Err(()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn match_post_hinted(
|
||||
/** Match static and dynamic hints after the nock formula is evaluated */
|
||||
fn match_hint_post_nock(
|
||||
stack: &mut NockStack,
|
||||
subject: Noun,
|
||||
hint: Noun,
|
||||
res: Noun,
|
||||
cache: &mut Hamt<Noun>,
|
||||
) -> Result<(), ()> {
|
||||
let direct = hint.as_cell()?.head().as_direct()?;
|
||||
match direct.data() {
|
||||
) -> Option<Noun> {
|
||||
let tag = hint
|
||||
.as_either_atom_cell()
|
||||
.either(|a| a.direct(), |c| c.head().direct())?;
|
||||
|
||||
match tag.data() {
|
||||
tas!(b"memo") => {
|
||||
let formula = unsafe { *stack.local_noun_pointer(2) };
|
||||
let mut key = Cell::new(stack, subject, formula).as_noun();
|
||||
*cache = cache.insert(stack, &mut key, res);
|
||||
Ok(())
|
||||
None
|
||||
}
|
||||
_ => Err(()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -678,6 +678,22 @@ impl Atom {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn direct(&self) -> Option<DirectAtom> {
|
||||
if self.is_direct() {
|
||||
unsafe { Some(self.direct) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indirect(&self) -> Option<IndirectAtom> {
|
||||
if self.is_indirect() {
|
||||
unsafe { Some(self.indirect) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
match self.as_either() {
|
||||
Either::Left(_direct) => 1,
|
||||
@ -882,6 +898,46 @@ impl Noun {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn atom(&self) -> Option<Atom> {
|
||||
if self.is_atom() {
|
||||
unsafe { Some(self.atom) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cell(&self) -> Option<Cell> {
|
||||
if self.is_cell() {
|
||||
unsafe { Some(self.cell) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn direct(&self) -> Option<DirectAtom> {
|
||||
if self.is_direct() {
|
||||
unsafe { Some(self.direct) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indirect(&self) -> Option<IndirectAtom> {
|
||||
if self.is_indirect() {
|
||||
unsafe { Some(self.indirect) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allocated(&self) -> Option<Allocated> {
|
||||
if self.is_allocated() {
|
||||
unsafe { Some(self.allocated) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/** Are these the same noun */
|
||||
pub unsafe fn raw_equals(self, other: Noun) -> bool {
|
||||
self.raw == other.raw
|
||||
|
Loading…
Reference in New Issue
Block a user