mirror of
https://github.com/urbit/ares.git
synced 2024-11-23 17:24:52 +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 => {
|
Nock11ComputeHint => {
|
||||||
let hint = *stack.local_noun_pointer(1);
|
let hint = (*stack.local_noun_pointer(1))
|
||||||
if let Ok(hint_cell) = hint.as_cell() {
|
.as_cell()
|
||||||
let formula = *stack.local_noun_pointer(2);
|
.expect("IMPOSSIBLE: tried to compute a dynamic hint but hint is an atom");
|
||||||
if let Ok(found) =
|
let formula = *stack.local_noun_pointer(2);
|
||||||
match_pre_hint(stack, newt, subject, hint_cell, formula, &cache)
|
|
||||||
{
|
|
||||||
res = found;
|
|
||||||
|
|
||||||
stack.preserve(&mut cache);
|
if let Some(found) =
|
||||||
stack.preserve(&mut res);
|
match_hint_pre_hint(stack, newt, subject, hint, formula, &cache)
|
||||||
stack.frame_pop();
|
{
|
||||||
} else {
|
res = found;
|
||||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock11ComputeResult);
|
stack.preserve(&mut cache);
|
||||||
push_formula(stack, hint_cell.tail());
|
stack.preserve(&mut res);
|
||||||
}
|
stack.frame_pop();
|
||||||
} else {
|
} 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 => {
|
Nock11ComputeResult => {
|
||||||
let hint = *stack.local_noun_pointer(1);
|
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;
|
res = found;
|
||||||
|
|
||||||
stack.preserve(&mut cache);
|
stack.preserve(&mut cache);
|
||||||
@ -353,7 +352,11 @@ pub fn interpret(
|
|||||||
}
|
}
|
||||||
Nock11Done => {
|
Nock11Done => {
|
||||||
let hint = *stack.local_noun_pointer(1);
|
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 cache);
|
||||||
stack.preserve(&mut res);
|
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 */
|
/** Match dynamic hints before the hint formula is evaluated */
|
||||||
fn match_pre_hint(
|
fn match_hint_pre_hint(
|
||||||
stack: &mut NockStack,
|
stack: &mut NockStack,
|
||||||
newt: &mut Option<&mut Newt>,
|
newt: &mut Option<&mut Newt>,
|
||||||
subject: Noun,
|
subject: Noun,
|
||||||
cell: Cell,
|
hint: Cell,
|
||||||
formula: Noun,
|
formula: Noun,
|
||||||
cache: &Hamt<Noun>,
|
cache: &Hamt<Noun>,
|
||||||
) -> Result<Noun, ()> {
|
) -> Option<Noun> {
|
||||||
let direct = cell.head().as_direct()?;
|
let tag = hint.head().direct()?;
|
||||||
match direct.data() {
|
|
||||||
|
match tag.data() {
|
||||||
// %sham hints are scaffolding until we have a real jet dashboard
|
// %sham hints are scaffolding until we have a real jet dashboard
|
||||||
tas!(b"sham") => {
|
tas!(b"sham") => {
|
||||||
let jet_formula = cell.tail().as_cell()?;
|
let jet_formula = hint.tail().cell()?;
|
||||||
let jet_name = jet_formula.tail();
|
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 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 in test mode, check that the jet returns the same result as the raw nock
|
||||||
if jets::get_jet_test_mode(jet_name) {
|
if jets::get_jet_test_mode(jet_name) {
|
||||||
@ -664,69 +668,73 @@ fn match_pre_hint(
|
|||||||
"\rJet {} failed, raw: {}, jetted: {}",
|
"\rJet {} failed, raw: {}, jetted: {}",
|
||||||
jet_name, nock_res, jet_res
|
jet_name, nock_res, jet_res
|
||||||
);
|
);
|
||||||
return Err(());
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(jet_res)
|
Some(jet_res)
|
||||||
} else {
|
} else {
|
||||||
// Print jet errors and punt to Nock
|
// Print jet errors and punt to Nock
|
||||||
eprintln!("\rJet {} failed", jet_name);
|
eprintln!("\rJet {} failed: ", jet_name);
|
||||||
Err(())
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tas!(b"memo") => {
|
tas!(b"memo") => {
|
||||||
let formula = unsafe { *stack.local_noun_pointer(2) };
|
let formula = unsafe { *stack.local_noun_pointer(2) };
|
||||||
let mut key = Cell::new(stack, subject, formula).as_noun();
|
let mut key = Cell::new(stack, subject, formula).as_noun();
|
||||||
if let Some(res) = cache.lookup(stack, &mut key) {
|
cache.lookup(stack, &mut key)
|
||||||
Ok(res)
|
|
||||||
} else {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => Err(()),
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Match static hints and dynamic hints after they're evaluated */
|
/** Match static and dynamic hints before the nock formula is evaluated */
|
||||||
fn match_post_hint(
|
fn match_hint_pre_nock(
|
||||||
stack: &mut NockStack,
|
stack: &mut NockStack,
|
||||||
newt: &mut Option<&mut Newt>,
|
newt: &mut Option<&mut Newt>,
|
||||||
_subject: Noun,
|
_subject: Noun,
|
||||||
hint: Noun,
|
hint: Noun,
|
||||||
res: Noun,
|
res: Noun,
|
||||||
) -> Result<Noun, ()> {
|
) -> Option<Noun> {
|
||||||
let direct = hint.as_cell()?.head().as_direct()?;
|
let tag = hint
|
||||||
match direct.data() {
|
.as_either_atom_cell()
|
||||||
|
.either(|a| a.direct(), |c| c.head().direct())?;
|
||||||
|
|
||||||
|
match tag.data() {
|
||||||
tas!(b"slog") => {
|
tas!(b"slog") => {
|
||||||
let slog_cell = res.as_cell()?;
|
let slog_cell = res.cell()?;
|
||||||
let pri = slog_cell.head().as_direct()?.data();
|
let pri = slog_cell.head().direct()?.data();
|
||||||
let tank = slog_cell.tail();
|
let tank = slog_cell.tail();
|
||||||
if let Some(not) = newt {
|
if let Some(not) = newt {
|
||||||
not.slog(stack, pri, tank);
|
not.slog(stack, pri, tank);
|
||||||
} else {
|
} 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,
|
stack: &mut NockStack,
|
||||||
subject: Noun,
|
subject: Noun,
|
||||||
hint: Noun,
|
hint: Noun,
|
||||||
res: Noun,
|
res: Noun,
|
||||||
cache: &mut Hamt<Noun>,
|
cache: &mut Hamt<Noun>,
|
||||||
) -> Result<(), ()> {
|
) -> Option<Noun> {
|
||||||
let direct = hint.as_cell()?.head().as_direct()?;
|
let tag = hint
|
||||||
match direct.data() {
|
.as_either_atom_cell()
|
||||||
|
.either(|a| a.direct(), |c| c.head().direct())?;
|
||||||
|
|
||||||
|
match tag.data() {
|
||||||
tas!(b"memo") => {
|
tas!(b"memo") => {
|
||||||
let formula = unsafe { *stack.local_noun_pointer(2) };
|
let formula = unsafe { *stack.local_noun_pointer(2) };
|
||||||
let mut key = Cell::new(stack, subject, formula).as_noun();
|
let mut key = Cell::new(stack, subject, formula).as_noun();
|
||||||
*cache = cache.insert(stack, &mut key, res);
|
*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 {
|
pub fn size(&self) -> usize {
|
||||||
match self.as_either() {
|
match self.as_either() {
|
||||||
Either::Left(_direct) => 1,
|
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 */
|
/** Are these the same noun */
|
||||||
pub unsafe fn raw_equals(self, other: Noun) -> bool {
|
pub unsafe fn raw_equals(self, other: Noun) -> bool {
|
||||||
self.raw == other.raw
|
self.raw == other.raw
|
||||||
|
Loading…
Reference in New Issue
Block a user