[ares] add pill to run azimuth events

Also includes various functions changes to allow printing nouns in gdb,
printing direct atoms as ascii when possible, etc.
This commit is contained in:
Philip Monk 2023-02-15 01:12:56 -07:00
parent a96ea5ffba
commit ff603d01f6
16 changed files with 2623 additions and 43 deletions

View File

@ -0,0 +1,835 @@
:: A small pill that runs a snasphot of azimuth state against a few
:: tens of thousands of logs. Requires naive-cradle.hoon,
:: mainnet.azimuth-snapshot, and log.jam from this scaffolding
:: directory.
::
/+ naive=naive-cradle, orig-naive=naive, ethereum, dice
/* snap %azimuth-snapshot /lib/mainnet/azimuth-snapshot
/* logs %jam /lib/logs/jam
!.
=/ processed-logs
=/ net (get-network:dice %mainnet)
=/ logs ((list event-log:rpc:ethereum) (cue logs))
|- ^- (list ^input:orig-naive)
?~ logs
~
?~ mined.i.logs
$(logs t.logs)
:- :- block-number.u.mined.i.logs
?: =(azimuth.net address.i.logs)
=/ data (data-to-hex:dice data.i.logs)
=/ =event-log:orig-naive
[address.i.logs data topics.i.logs]
[%log event-log]
?~ input.u.mined.i.logs
[%bat *@]
[%bat u.input.u.mined.i.logs]
$(logs t.logs)
=/ core
=> ~
!=
=/ crad
=> %a50
~% %a.50 ~ ~
|%
:: Types
::
+$ ship @p
+$ life @ud
+$ rift @ud
+$ pass @
+$ bloq @
+$ step _`@u`1
+$ bite $@(bloq [=bloq =step])
+$ octs [p=@ud q=@]
+$ mold $~(* $-(* *))
++ unit |$ [item] $@(~ [~ u=item])
++ list |$ [item] $@(~ [i=item t=(list item)])
++ lest |$ [item] [i=item t=(list item)]
++ tree |$ [node] $@(~ [n=node l=(tree node) r=(tree node)])
++ pair |$ [head tail] [p=head q=tail]
++ map
|$ [key value]
$| (tree (pair key value))
|=(a=(tree (pair)) ?:(=(~ a) & ~(apt by a)))
::
++ set
|$ [item]
$| (tree item)
|=(a=(tree) ?:(=(~ a) & ~(apt in a)))
::
++ jug |$ [key value] (map key (set value))
::
:: Bits
::
++ dec :: decrement
~/ %dec
|= a=@
~> %sham.%dec
~_ leaf+"decrement-underflow"
?< =(0 a)
=+ b=0
|- ^- @
?: =(a +(b)) b
$(b +(b))
::
++ add :: plus
~/ %add
|= [a=@ b=@]
~> %sham.%add
^- @
?: =(0 a) b
$(a (dec a), b +(b))
::
++ sub :: subtract
~/ %sub
|= [a=@ b=@]
~> %sham.%sub
~_ leaf+"subtract-underflow"
:: difference
^- @
?: =(0 b) a
$(a (dec a), b (dec b))
::
++ mul :: multiply
~/ %mul
|: [a=`@`1 b=`@`1]
~> %sham.%mul
^- @
=+ c=0
|-
?: =(0 a) c
$(a (dec a), c (add b c))
::
++ div :: divide
~/ %div
|: [a=`@`1 b=`@`1]
~> %sham.%div
^- @
~_ leaf+"divide-by-zero"
?< =(0 b)
=+ c=0
|-
?: (lth a b) c
$(a (sub a b), c +(c))
::
++ dvr :: divide w/remainder
~/ %dvr
|: [a=`@`1 b=`@`1]
~> %sham.%dvr
^- [p=@ q=@]
[(div a b) (mod a b)]
::
++ mod :: modulus
~/ %mod
|: [a=`@`1 b=`@`1]
~> %sham.%mod
^- @
?< =(0 b)
(sub a (mul b (div a b)))
::
++ bex :: binary exponent
~/ %bex
|= a=bloq
~> %sham.%bex
^- @
?: =(0 a) 1
(mul 2 $(a (dec a)))
::
++ lsh :: left-shift
~/ %lsh
|= [a=bite b=@]
~> %sham.%lsh
=/ [=bloq =step] ?^(a a [a *step])
(mul b (bex (mul (bex bloq) step)))
::
++ rsh :: right-shift
~/ %rsh
|= [a=bite b=@]
~> %sham.%rsh
=/ [=bloq =step] ?^(a a [a *step])
(div b (bex (mul (bex bloq) step)))
::
++ con :: binary or
~/ %con
|= [a=@ b=@]
~> %sham.%con
=+ [c=0 d=0]
|- ^- @
?: ?&(=(0 a) =(0 b)) d
%= $
a (rsh 0 a)
b (rsh 0 b)
c +(c)
d %+ add d
%+ lsh [0 c]
?& =(0 (end 0 a))
=(0 (end 0 b))
==
==
::
++ dis :: binary and
~/ %dis
|= [a=@ b=@]
~> %sham.%dis
=| [c=@ d=@]
|- ^- @
?: ?|(=(0 a) =(0 b)) d
%= $
a (rsh 0 a)
b (rsh 0 b)
c +(c)
d %+ add d
%+ lsh [0 c]
?| =(0 (end 0 a))
=(0 (end 0 b))
==
==
::
++ mix :: binary xor
~/ %mix
|= [a=@ b=@]
~> %sham.%mix
^- @
=+ [c=0 d=0]
|-
?: ?&(=(0 a) =(0 b)) d
%= $
a (rsh 0 a)
b (rsh 0 b)
c +(c)
d (add d (lsh [0 c] =((end 0 a) (end 0 b))))
==
::
++ lth :: less
~/ %lth
|= [a=@ b=@]
~> %sham.%lth
^- ?
?& !=(a b)
|-
?| =(0 a)
?& !=(0 b)
$(a (dec a), b (dec b))
== == ==
::
++ lte :: less or equal
~/ %lte
|= [a=@ b=@]
~> %sham.%lte
|(=(a b) (lth a b))
::
++ gte :: greater or equal
~/ %gte
|= [a=@ b=@]
~> %sham.%gte
^- ?
!(lth a b)
::
++ gth :: greater
~/ %gth
|= [a=@ b=@]
~> %sham.%gth
^- ?
!(lte a b)
::
++ swp :: naive rev bloq order
~/ %swp
|= [a=bloq b=@]
~> %sham.%swp
(rep a (flop (rip a b)))
::
++ met :: measure
~/ %met
|= [a=bloq b=@]
~> %sham.%met
^- @
=+ c=0
|-
?: =(0 b) c
$(b (rsh a b), c +(c))
::
++ end :: tail
~/ %end
|= [a=bite b=@]
~> %sham.%end
=/ [=bloq =step] ?^(a a [a *step])
(mod b (bex (mul (bex bloq) step)))
::
++ cat :: concatenate
~/ %cat
|= [a=bloq b=@ c=@]
~> %sham.%cat
(add (lsh [a (met a b)] c) b)
::
++ cut :: slice
~/ %cut
|= [a=bloq [b=step c=step] d=@]
~> %sham.%cut
(end [a c] (rsh [a b] d))
::
++ can :: assemble
~/ %can
|= [a=bloq b=(list [p=step q=@])]
~> %sham.%can
^- @
?~ b 0
(add (end [a p.i.b] q.i.b) (lsh [a p.i.b] $(b t.b)))
::
++ cad :: assemble specific
~/ %cad
|= [a=bloq b=(list [p=step q=@])]
~> %sham.%cad
^- [=step @]
:_ (can a b)
|-
?~ b
0
(add p.i.b $(b t.b))
::
++ rep :: assemble fixed
~/ %rep
|= [a=bite b=(list @)]
~> %sham.%rep
=/ [=bloq =step] ?^(a a [a *step])
=| i=@ud
|- ^- @
?~ b 0
%+ add $(i +(i), b t.b)
(lsh [bloq (mul step i)] (end [bloq step] i.b))
::
++ rip :: disassemble
~/ %rip
|= [a=bite b=@]
~> %sham.%rip
^- (list @)
?: =(0 b) ~
[(end a b) $(b (rsh a b))]
::
::
:: Lists
::
++ lent :: length
~/ %lent
|= a=(list)
~> %sham.%lent
^- @
=+ b=0
|-
?~ a b
$(a t.a, b +(b))
::
++ slag :: suffix
~/ %slag
|* [a=@ b=(list)]
~> %sham.%slag
|- ^+ b
?: =(0 a) b
?~ b ~
$(b t.b, a (dec a))
::
++ snag :: index
~/ %snag
|* [a=@ b=(list)]
~> %sham.%snag
|- ^+ ?>(?=(^ b) i.b)
?~ b
~_ leaf+"snag-fail"
!!
?: =(0 a) i.b
$(b t.b, a (dec a))
::
++ homo :: homogenize
|* a=(list)
^+ =< $
|@ ++ $ ?:(*? ~ [i=(snag 0 a) t=$])
--
a
::
++ flop :: reverse
~/ %flop
|* a=(list)
~> %sham.%flop
=> .(a (homo a))
^+ a
=+ b=`_a`~
|-
?~ a b
$(a t.a, b [i.a b])
::
++ welp :: concatenate
~/ %welp
=| [* *]
~> %sham.%welp
|@
++ $
?~ +<-
+<-(. +<+)
+<-(+ $(+<- +<->))
--
::
++ reap :: replicate
~/ %reap
|* [a=@ b=*]
~> %sham.%reap
|- ^- (list _b)
?~ a ~
[b $(a (dec a))]
::
:: Modular arithmetic
::
++ fe :: modulo bloq
|_ a=bloq
++ rol |= [b=bloq c=@ d=@] ^- @ :: roll left
=+ e=(sit d)
=+ f=(bex (sub a b))
=+ g=(mod c f)
(sit (con (lsh [b g] e) (rsh [b (sub f g)] e)))
++ sum |=([b=@ c=@] (sit (add b c))) :: wrapping add
++ sit |=(b=@ (end a b)) :: enforce modulo
--
::
:: Hashes
::
++ muk :: standard murmur3
~% %muk ..muk ~
=+ ~(. fe 5)
|= [syd=@ len=@ key=@]
=. syd (end 5 syd)
=/ pad (sub len (met 3 key))
=/ data (welp (rip 3 key) (reap pad 0))
=/ nblocks (div len 4) :: intentionally off-by-one
=/ h1 syd
=+ [c1=0xcc9e.2d51 c2=0x1b87.3593]
=/ blocks (rip 5 key)
=/ i nblocks
=. h1 =/ hi h1 |-
?: =(0 i) hi
=/ k1 (snag (sub nblocks i) blocks) :: negative array index
=. k1 (sit (mul k1 c1))
=. k1 (rol 0 15 k1)
=. k1 (sit (mul k1 c2))
=. hi (mix hi k1)
=. hi (rol 0 13 hi)
=. hi (sum (sit (mul hi 5)) 0xe654.6b64)
$(i (dec i))
=/ tail (slag (mul 4 nblocks) data)
=/ k1 0
=/ tlen (dis len 3)
=. h1
?+ tlen h1 :: fallthrough switch
%3 =. k1 (mix k1 (lsh [0 16] (snag 2 tail)))
=. k1 (mix k1 (lsh [0 8] (snag 1 tail)))
=. k1 (mix k1 (snag 0 tail))
=. k1 (sit (mul k1 c1))
=. k1 (rol 0 15 k1)
=. k1 (sit (mul k1 c2))
(mix h1 k1)
%2 =. k1 (mix k1 (lsh [0 8] (snag 1 tail)))
=. k1 (mix k1 (snag 0 tail))
=. k1 (sit (mul k1 c1))
=. k1 (rol 0 15 k1)
=. k1 (sit (mul k1 c2))
(mix h1 k1)
%1 =. k1 (mix k1 (snag 0 tail))
=. k1 (sit (mul k1 c1))
=. k1 (rol 0 15 k1)
=. k1 (sit (mul k1 c2))
(mix h1 k1)
==
=. h1 (mix h1 len)
|^ (fmix32 h1)
++ fmix32
|= h=@
=. h (mix h (rsh [0 16] h))
=. h (sit (mul h 0x85eb.ca6b))
=. h (mix h (rsh [0 13] h))
=. h (sit (mul h 0xc2b2.ae35))
=. h (mix h (rsh [0 16] h))
h
--
::
++ mug :: mug with murmur3
~/ %mug
|= a=*
~> %sham.%mug
|^ ?@ a (mum 0xcafe.babe 0x7fff a)
=/ b (cat 5 $(a -.a) $(a +.a))
(mum 0xdead.beef 0xfffe b)
::
++ mum
|= [syd=@uxF fal=@F key=@]
=/ wyd (met 3 key)
=| i=@ud
|- ^- @F
?: =(8 i) fal
=/ haz=@F (muk syd wyd key)
=/ ham=@F (mix (rsh [0 31] haz) (end [0 31] haz))
?.(=(0 ham) ham $(i +(i), syd +(syd)))
--
::
++ gor :: mug order
~/ %gor
|= [a=* b=*]
~> %sham.%gor
^- ?
=+ [c=(mug a) d=(mug b)]
?: =(c d)
(dor a b)
(lth c d)
::
++ mor :: more mug order
~/ %mor
|= [a=* b=*]
~> %sham.%mor
^- ?
=+ [c=(mug (mug a)) d=(mug (mug b))]
?: =(c d)
(dor a b)
(lth c d)
::
++ dor :: tree order
~/ %dor
|= [a=* b=*]
~> %sham.%dor
^- ?
?: =(a b) &
?. ?=(@ a)
?: ?=(@ b) |
?: =(-.a -.b)
$(a +.a, b +.b)
$(a -.a, b -.b)
?. ?=(@ b) &
(lth a b)
::
++ por :: parent order
~/ %por
|= [a=@p b=@p]
~> %sham.%por
^- ?
?: =(a b) &
=| i=@
|-
?: =(i 2)
:: second two bytes
(lte a b)
:: first two bytes
=+ [c=(end 3 a) d=(end 3 b)]
?: =(c d)
$(a (rsh 3 a), b (rsh 3 b), i +(i))
(lth c d)
::
:: Maps
::
++ by
~/ %by
=| a=(tree (pair)) :: (map)
~> %sham.%by
=* node ?>(?=(^ a) n.a)
|@
++ get
~/ %get
|* b=*
~> %sham.%get
=> .(b `_?>(?=(^ a) p.n.a)`b)
|- ^- (unit _?>(?=(^ a) q.n.a))
?~ a
~
?: =(b p.n.a)
`q.n.a
?: (gor b p.n.a)
$(a l.a)
$(a r.a)
::
++ put
~/ %put
|* [b=* c=*]
~> %sham.%put
|- ^+ a
?~ a
[[b c] ~ ~]
?: =(b p.n.a)
?: =(c q.n.a)
a
a(n [b c])
?: (gor b p.n.a)
=+ d=$(a l.a)
?> ?=(^ d)
?: (mor p.n.a p.n.d)
a(l d)
d(r a(l r.d))
=+ d=$(a r.a)
?> ?=(^ d)
?: (mor p.n.a p.n.d)
a(r d)
d(l a(r l.d))
::
++ del
~/ %del
|* b=*
~> %sham.%del
|- ^+ a
?~ a
~
?. =(b p.n.a)
?: (gor b p.n.a)
a(l $(a l.a))
a(r $(a r.a))
|- ^- [$?(~ _a)]
?~ l.a r.a
?~ r.a l.a
?: (mor p.n.l.a p.n.r.a)
l.a(r $(l.a r.l.a))
r.a(l $(r.a l.r.a))
::
++ apt
=< $
~/ %apt
=| [l=(unit) r=(unit)]
~> %sham.%apt
|. ^- ?
?~ a &
?& ?~(l & &((gor p.n.a u.l) !=(p.n.a u.l)))
?~(r & &((gor u.r p.n.a) !=(u.r p.n.a)))
?~ l.a &
&((mor p.n.a p.n.l.a) !=(p.n.a p.n.l.a) $(a l.a, l `p.n.a))
?~ r.a &
&((mor p.n.a p.n.r.a) !=(p.n.a p.n.r.a) $(a r.a, r `p.n.a))
==
--
::
++ on :: ordered map
~/ %on
|* [key=mold val=mold]
~> %sham.%on
=> |%
+$ item [key=key val=val]
--
::
~% %comp +>+ ~
|= compare=$-([key key] ?)
~% %core + ~
|%
::
++ apt
~/ %apt
|= a=(tree item)
~> %sham.%apt
=| [l=(unit key) r=(unit key)]
|- ^- ?
?~ a %.y
?& ?~(l %.y (compare key.n.a u.l))
?~(r %.y (compare u.r key.n.a))
?~(l.a %.y &((mor key.n.a key.n.l.a) $(a l.a, l `key.n.a)))
?~(r.a %.y &((mor key.n.a key.n.r.a) $(a r.a, r `key.n.a)))
==
::
++ get
~/ %get
|= [a=(tree item) b=key]
~> %sham.%get
^- (unit val)
?~ a ~
?: =(b key.n.a)
`val.n.a
?: (compare b key.n.a)
$(a l.a)
$(a r.a)
::
++ has
~/ %has
|= [a=(tree item) b=key]
~> %sham.%has
^- ?
!=(~ (get a b))
::
++ put
~/ %put
|= [a=(tree item) =key =val]
~> %sham.%put
^- (tree item)
?~ a [n=[key val] l=~ r=~]
?: =(key.n.a key) a(val.n val)
?: (compare key key.n.a)
=/ l $(a l.a)
?> ?=(^ l)
?: (mor key.n.a key.n.l)
a(l l)
l(r a(l r.l))
=/ r $(a r.a)
?> ?=(^ r)
?: (mor key.n.a key.n.r)
a(r r)
r(l a(r l.r))
--
::
:: Sets
::
++ in
~/ %in
=| a=(tree) :: (set)
~> %sham.%in
|@
++ put
~/ %put
|* b=*
~> %sham.%put
|- ^+ a
?~ a
[b ~ ~]
?: =(b n.a)
a
?: (gor b n.a)
=+ c=$(a l.a)
?> ?=(^ c)
?: (mor n.a n.c)
a(l c)
c(r a(l r.c))
=+ c=$(a r.a)
?> ?=(^ c)
?: (mor n.a n.c)
a(r c)
c(l a(r l.c))
::
++ del
~/ %del
|* b=*
~> %sham.%del
|- ^+ a
?~ a
~
?. =(b n.a)
?: (gor b n.a)
a(l $(a l.a))
a(r $(a r.a))
|- ^- [$?(~ _a)]
?~ l.a r.a
?~ r.a l.a
?: (mor n.l.a n.r.a)
l.a(r $(l.a r.l.a))
r.a(l $(r.a l.r.a))
::
++ apt
=< $
~/ %apt
=| [l=(unit) r=(unit)]
~> %sham.%apt
|. ^- ?
?~ a &
?& ?~(l & (gor n.a u.l))
?~(r & (gor u.r n.a))
?~(l.a & ?&((mor n.a n.l.a) $(a l.a, l `n.a)))
?~(r.a & ?&((mor n.a n.r.a) $(a r.a, r `n.a)))
==
--
::
:: Jugs
::
++ ju
=| a=(tree (pair * (tree))) :: (jug)
|@
++ get
|* b=*
=+ c=(~(get by a) b)
?~(c ~ u.c)
::
++ del
|* [b=* c=*]
^+ a
=+ d=(get b)
=+ e=(~(del in d) c)
?~ e
(~(del by a) b)
(~(put by a) b e)
::
++ put
|* [b=* c=*]
^+ a
=+ d=(get b)
(~(put by a) b (~(put in d) c))
--
--
=>
|%
+$ card (cask)
++ cask |$ [a] (pair mark a)
+$ knot @ta
++ list |$ [item] $@(~ [i=item t=(list item)])
+$ mark @tas
+$ ovum [=wire =card]
++ pair |$ [head tail] [p=head q=tail]
+$ path (list knot)
+$ wire path
++ verifier |=([[@ @] @ @ @] `0x123)
-- =>
::
=| naive=*
=| snap=*
|%
++ load !!
++ peek _~
++ wish !!
++ poke
|= [now=@da ovo=ovum]
^- ^
:: ~> %slog.[0 'got']
:: ~> %slog.[0 -.card.ovo]
?: =(%naive -.card.ovo)
~> %slog.[0 'storing naive formula']
`..poke(naive +.card.ovo)
?: =(%snap -.card.ovo)
~> %slog.[0 'storing azimuth snapshot']
`..poke(snap +.card.ovo)
?: =(%logs -.card.ovo)
~> %slog.[0 'running logs']
=/ logs +.card.ovo
=| n=@
=. snap
=/ nave .*(0 naive)
!.
|-
=+ ?: =(0 (mod:crad n 1.000))
~> %slog.[0 'ran a thousand logs']
~
~
?~ logs
snap
=. snap
:: (naive verifier 1 snap i.logs)
+:.*([nave verifier snap -.logs] [9 2 10 [6 [0 6] [1 1] [0 14] [0 15]] 0 2])
$(logs +.logs, n +(n))
~> %slog.[0 'done']
`..poke
=/ fec [//term/1 %blit [%put "effect"] [%nel ~] ~]
[[fec ~] ..poke]
--
::
|= [now=@da ovo=ovum]
^- *
.(+> +:(poke now ovo))
::
|%
++ aeon
^- *
=> *[arvo=* epic=*]
!=
=+ [arvo epic]=.*(epic arvo)
|- ^- *
?@ epic arvo
%= $
epic +.epic
arvo .*([arvo -.epic] [%9 2 %10 [6 %0 3] %0 2])
==
--
!.
:+ %pill %baby
:_ [~ ~]
:~ aeon
=> *[arvo-formula=^ installed=^ tale=*]
!=(=+(.*(0 arvo-formula) [installed tale]))
core
.*(0 core)
[*@da / %naive naive]
[*@da / %snap nas.snap]
[*@da / %logs processed-logs]
==

BIN
hoon/scaffolding/logs.jam Normal file

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,8 @@ use bitvec::prelude::{BitSlice, Lsb0};
use either::Either::*; use either::Either::*;
use num_traits::cast::{FromPrimitive, ToPrimitive}; use num_traits::cast::{FromPrimitive, ToPrimitive};
crate::gdb!();
#[derive(Copy, Clone, FromPrimitive, ToPrimitive, Debug)] #[derive(Copy, Clone, FromPrimitive, ToPrimitive, Debug)]
#[repr(u64)] #[repr(u64)]
enum NockWork { enum NockWork {
@ -522,7 +524,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
} }
} }
} else { } else {
panic!("Bad formula: atoms are not formulas: {:?}", formula); panic!("Bad formula: atoms are not formulas: {}", formula);
} }
} }
@ -549,7 +551,7 @@ pub fn slot(mut noun: Noun, axis: &BitSlice<u64, Lsb0>) -> Noun {
noun = cell.head(); noun = cell.head();
} }
} else { } else {
panic!("Axis tried to descend through atom: {:?}", noun); panic!("Axis tried to descend through atom: {}", noun);
}; };
} }
noun noun
@ -590,7 +592,7 @@ fn edit(
(*cellmem).tail = tree_cell.tail(); (*cellmem).tail = tree_cell.tail();
dest = &mut ((*cellmem).head); dest = &mut ((*cellmem).head);
} }
tree = tree_cell.tail(); tree = tree_cell.head();
} }
} else { } else {
panic!("Invalid axis for edit"); panic!("Invalid axis for edit");
@ -639,21 +641,26 @@ fn match_pre_hint(
tas!(b"sham") => { tas!(b"sham") => {
let jet_formula = cell.tail().as_cell()?; let jet_formula = cell.tail().as_cell()?;
let jet_name = jet_formula.tail(); let jet_name = jet_formula.tail();
let jet = jets::get_jet(jet_name)?;
let mut jet_res = jet(stack, subject)?; // Punt all errors to Nock
// if in test mode, check that the jet returns the same result as the raw nock let jet = jets::get_jet(jet_name)?;
if jets::get_jet_test_mode(jet_name) { if let Ok(mut jet_res) = jet(stack, subject) {
let mut nock_res = interpret(stack, newt, subject, formula); // if in test mode, check that the jet returns the same result as the raw nock
if unsafe { !unifying_equality(stack, &mut nock_res, &mut jet_res) } { if jets::get_jet_test_mode(jet_name) {
eprintln!( let mut nock_res = interpret(stack, newt, subject, formula);
"\rJet {:?} failed, raw: {:?}, jetted: {:?}", if unsafe { !unifying_equality(stack, &mut nock_res, &mut jet_res) } {
jet_name, nock_res, jet_res eprintln!(
); "\rJet {} failed, raw: {}, jetted: {}",
return Err(()); jet_name, nock_res, jet_res
);
return Err(());
}
} }
return Ok(jet_res);
} else {
// Print jet errors and punt to Nock
eprintln!("\rJet {} failed", jet_name);
return Err(());
} }
return Ok(jet_res);
} }
_ => Err(()), _ => Err(()),
} }
@ -676,7 +683,7 @@ fn match_post_hint(
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!("slog: {} {}", pri, tank);
} }
Err(()) Err(())
} }

View File

@ -1,10 +1,12 @@
mod math; pub mod math;
use crate::jets::math::*; use crate::jets::math::*;
use crate::mem::NockStack; use crate::mem::NockStack;
use crate::noun::Noun; use crate::noun::Noun;
use ares_macros::tas; use ares_macros::tas;
crate::gdb!();
/// Return Err if the computation crashed or should punt to Nock /// Return Err if the computation crashed or should punt to Nock
pub type Jet = fn(&mut NockStack, Noun) -> Result<Noun, JetErr>; pub type Jet = fn(&mut NockStack, Noun) -> Result<Noun, JetErr>;
@ -62,8 +64,7 @@ pub fn get_jet(jet_name: Noun) -> Result<Jet, ()> {
pub fn get_jet_test_mode(jet_name: Noun) -> bool { pub fn get_jet_test_mode(jet_name: Noun) -> bool {
match jet_name.as_direct().unwrap().data() { match jet_name.as_direct().unwrap().data() {
tas!(b"cut") => true, // tas!(b"cut") => true,
tas!(b"rsh") => true,
_ => false, _ => false,
} }
} }

View File

@ -24,6 +24,8 @@ use ibig::UBig;
use num_traits::identities::One; use num_traits::identities::One;
use std::cmp; use std::cmp;
crate::gdb!();
pub fn jet_dec(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> { pub fn jet_dec(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
let arg = raw_slot(subject, 6); let arg = raw_slot(subject, 6);
if let Ok(atom) = arg.as_atom() { if let Ok(atom) = arg.as_atom() {
@ -709,7 +711,7 @@ mod tests {
fn assert_noun_eq(stack: &mut NockStack, mut a: Noun, mut b: Noun) { fn assert_noun_eq(stack: &mut NockStack, mut a: Noun, mut b: Noun) {
let eq = unsafe { unifying_equality(stack, &mut a, &mut b) }; let eq = unsafe { unifying_equality(stack, &mut a, &mut b) };
assert!(eq, "got: {:?}, need: {:?}", a, b); assert!(eq, "got: {}, need: {}", a, b);
} }
fn assert_jet(stack: &mut NockStack, jet: Jet, sam: Noun, res: Noun) { fn assert_jet(stack: &mut NockStack, jet: Jet, sam: Noun, res: Noun) {
@ -754,7 +756,7 @@ mod tests {
let jet_res = jet(stack, sam); let jet_res = jet(stack, sam);
assert!( assert!(
jet_res.is_err(), jet_res.is_err(),
"with sample: {:?}, expected err: {:?}, got: {:?}", "with sample: {}, expected err: {:?}, got: {:?}",
sam, sam,
err, err,
&jet_res &jet_res
@ -762,7 +764,7 @@ mod tests {
let jet_err = jet_res.unwrap_err(); let jet_err = jet_res.unwrap_err();
assert_eq!( assert_eq!(
jet_err, err, jet_err, err,
"with sample: {:?}, expected err: {:?}, got: {:?}", "with sample: {}, expected err: {:?}, got: {:?}",
sam, err, jet_err sam, err, jet_err
); );
} }

View File

@ -10,6 +10,30 @@ pub mod serf;
pub mod serialization; pub mod serialization;
pub mod snapshot; pub mod snapshot;
/** Introduce useful functions for debugging
*
* The main difficulty with these is that rust wants to strip them out if they're not used in the
* code. Even if you get it past the compiler, the linker will get rid of them. The solution here
* is to call use_gdb() from main.rs on each module. This is ugly, but I haven't found another way
* that keeps these available in the debugger.
*
* Thus, every file that touches nouns should include `crate::gdb!();` at the top, and main.rs should
* call use_gdb on that module.
*/
macro_rules! gdb {
() => {
fn pretty_noun(noun: crate::noun::Noun) -> String {
noun.to_string()
}
pub fn use_gdb() {
pretty_noun(crate::noun::D(0));
}
};
}
pub(crate) use gdb;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -15,6 +15,20 @@ use std::ptr::write_bytes;
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
let filename = env::args().nth(1).expect("Must provide input filename"); let filename = env::args().nth(1).expect("Must provide input filename");
if filename == "see gdb! definition in lib.rs about this" {
ares::interpreter::use_gdb();
ares::jets::use_gdb();
ares::jets::math::use_gdb();
ares::mem::use_gdb();
ares::mug::use_gdb();
ares::newt::use_gdb();
ares::noun::use_gdb();
ares::serf::use_gdb();
ares::serialization::use_gdb();
ares::snapshot::use_gdb();
}
if filename == "serf" { if filename == "serf" {
return serf(); return serf();
} }
@ -38,7 +52,7 @@ fn main() -> io::Result<()> {
.expect("Input must be jam of subject/formula pair"); .expect("Input must be jam of subject/formula pair");
let result = interpret(&mut stack, &mut None, input_cell.head(), input_cell.tail()); let result = interpret(&mut stack, &mut None, input_cell.head(), input_cell.tail());
if let Ok(atom) = result.as_atom() { if let Ok(atom) = result.as_atom() {
println!("Result: {:?}", atom); println!("Result: {}", atom);
} }
let jammed_result = jam(&mut stack, result); let jammed_result = jam(&mut stack, result);
let f_out = OpenOptions::new() let f_out = OpenOptions::new()

View File

@ -7,6 +7,8 @@ use std::mem;
use std::ptr; use std::ptr;
use std::ptr::copy_nonoverlapping; use std::ptr::copy_nonoverlapping;
crate::gdb!();
/** Utility function to get size in words */ /** Utility function to get size in words */
pub const fn word_size_of<T>() -> usize { pub const fn word_size_of<T>() -> usize {
(mem::size_of::<T>() + 7) >> 3 (mem::size_of::<T>() + 7) >> 3
@ -425,7 +427,7 @@ impl NockStack {
} }
} }
*self.previous_stack_pointer_pointer_east() = other_stack_pointer; *self.previous_stack_pointer_pointer_east() = other_stack_pointer;
assert_acyclic!(*noun); // assert_acyclic!(*noun);
} }
/** Copy a result noun and its subnouns from a west frame to its parent east frame /** Copy a result noun and its subnouns from a west frame to its parent east frame
@ -792,15 +794,15 @@ unsafe fn senior_pointer_first<T>(
} else { } else {
match polarity { match polarity {
Polarity::East => { Polarity::East => {
high_pointer = *(frame_pointer.sub(2)) as *const T; high_pointer = *(frame_pointer.sub(1)) as *const T;
low_pointer = *(frame_pointer.sub(1)) as *const T; low_pointer = *(frame_pointer.sub(2)) as *const T;
frame_pointer = *(frame_pointer.sub(2)) as *const u64; frame_pointer = *(frame_pointer.sub(2)) as *const u64;
polarity = Polarity::West; polarity = Polarity::West;
continue; continue;
} }
Polarity::West => { Polarity::West => {
high_pointer = *frame_pointer as *const T; high_pointer = *(frame_pointer.add(1)) as *const T;
low_pointer = *(frame_pointer.add(1)) as *const T; low_pointer = *(frame_pointer.add(0)) as *const T;
frame_pointer = *(frame_pointer.add(1)) as *const u64; frame_pointer = *(frame_pointer.add(1)) as *const u64;
polarity = Polarity::East; polarity = Polarity::East;
continue; continue;

View File

@ -4,6 +4,8 @@ use crate::noun::{Allocated, Atom, DirectAtom, Noun};
use either::Either::*; use either::Either::*;
use murmur3::murmur3_32_nocopy; use murmur3::murmur3_32_nocopy;
crate::gdb!();
// Murmur3 hash an atom with a given padded length // Murmur3 hash an atom with a given padded length
fn muk_u32(syd: u32, len: usize, key: Atom) -> u32 { fn muk_u32(syd: u32, len: usize, key: Atom) -> u32 {
match key.as_either() { match key.as_either() {

View File

@ -59,6 +59,8 @@ use std::io::{Read, Write};
use std::os::unix::prelude::FromRawFd; use std::os::unix::prelude::FromRawFd;
use std::ptr::copy_nonoverlapping; use std::ptr::copy_nonoverlapping;
crate::gdb!();
pub struct Newt { pub struct Newt {
input: std::fs::File, input: std::fs::File,
output: std::fs::File, output: std::fs::File,

View File

@ -6,6 +6,8 @@ use std::fmt;
use std::ptr; use std::ptr;
use std::slice::{from_raw_parts, from_raw_parts_mut}; use std::slice::{from_raw_parts, from_raw_parts_mut};
crate::gdb!();
/** Tag for a direct atom. */ /** Tag for a direct atom. */
const DIRECT_TAG: u64 = 0x0; const DIRECT_TAG: u64 = 0x0;
@ -41,7 +43,7 @@ pub const NO: Noun = D(1);
#[macro_export] #[macro_export]
macro_rules! assert_acyclic { macro_rules! assert_acyclic {
( $x:expr ) => { ( $x:expr ) => {
assert!(acyclic_noun($x)); assert!(crate::noun::acyclic_noun($x));
}; };
} }
@ -157,9 +159,32 @@ impl DirectAtom {
} }
} }
impl fmt::Debug for DirectAtom { impl fmt::Display for DirectAtom {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0) if self.0 == 0 {
return write!(f, "0");
}
let mut null = false;
let mut n = 0;
let bytes = self.0.to_le_bytes();
for byte in bytes.iter() {
if *byte == 0 {
null = true;
continue;
}
if (null && *byte != 0) || *byte < 33 || *byte > 126 {
return write!(f, "{}", self.0);
}
n += 1;
}
if n > 1 {
write!(f, "%{}", unsafe {
std::str::from_utf8_unchecked(&bytes[..n])
})
} else {
write!(f, "{}", self.0)
}
} }
} }
@ -375,7 +400,7 @@ impl IndirectAtom {
} }
} }
impl fmt::Debug for IndirectAtom { impl fmt::Display for IndirectAtom {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "0x")?; write!(f, "0x")?;
let mut i = self.size() - 1; let mut i = self.size() - 1;
@ -485,19 +510,19 @@ impl Cell {
} }
} }
impl fmt::Debug for Cell { impl fmt::Display for Cell {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[")?; write!(f, "[")?;
let mut cell = *self; let mut cell = *self;
loop { loop {
write!(f, "{:?}", cell.head())?; write!(f, "{}", cell.head())?;
match cell.tail().as_cell() { match cell.tail().as_cell() {
Ok(next_cell) => { Ok(next_cell) => {
write!(f, " ")?; write!(f, " ")?;
cell = next_cell; cell = next_cell;
} }
Err(_) => { Err(_) => {
write!(f, " {:?}]", cell.tail())?; write!(f, " {}]", cell.tail())?;
break; break;
} }
} }
@ -641,7 +666,7 @@ impl Atom {
} }
} }
impl fmt::Debug for Atom { impl fmt::Display for Atom {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_noun().fmt(f) self.as_noun().fmt(f)
} }
@ -716,7 +741,7 @@ impl Allocated {
} }
} }
impl fmt::Debug for Allocated { impl fmt::Display for Allocated {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_noun().fmt(f) self.as_noun().fmt(f)
} }
@ -818,18 +843,24 @@ impl Noun {
} }
impl fmt::Debug for Noun { impl fmt::Debug for Noun {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Display for Noun {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
unsafe { unsafe {
if self.is_direct() { if self.is_direct() {
write!(f, "{:?}", self.direct) write!(f, "{}", self.direct)
} else if self.is_indirect() { } else if self.is_indirect() {
write!(f, "{:?}", self.indirect) write!(f, "{}", self.indirect)
} else if self.is_cell() { } else if self.is_cell() {
write!(f, "{:?}", self.cell) write!(f, "{}", self.cell)
} else if self.allocated.forwarding_pointer().is_some() { } else if self.allocated.forwarding_pointer().is_some() {
write!( write!(
f, f,
"Noun::Forwarding({:?})", "Noun::Forwarding({})",
self.allocated.forwarding_pointer().unwrap() self.allocated.forwarding_pointer().unwrap()
) )
} else { } else {

View File

@ -9,6 +9,8 @@ use std::fs::create_dir_all;
use std::io; use std::io;
use std::path::PathBuf; use std::path::PathBuf;
crate::gdb!();
#[allow(dead_code)] #[allow(dead_code)]
const LOAD_AXIS: u64 = 4; const LOAD_AXIS: u64 = 4;
const PEEK_AXIS: u64 = 22; const PEEK_AXIS: u64 = 22;
@ -29,7 +31,7 @@ pub fn serf() -> io::Result<()> {
snap_path.push("chk"); snap_path.push("chk");
create_dir_all(&snap_path)?; create_dir_all(&snap_path)?;
let ref mut stack = NockStack::new(8 << 10 << 10, 0); let ref mut stack = NockStack::new(21 << 10 << 10, 0);
let ref mut newt = Newt::new(); let ref mut newt = Newt::new();
let mut event_number; let mut event_number;
let mut arvo; let mut arvo;
@ -112,7 +114,7 @@ pub fn serf() -> io::Result<()> {
newt.work_done(stack, event_number, 0, fec); newt.work_done(stack, event_number, 0, fec);
} }
_ => panic!("got message with unknown tag {:?}", tag), _ => panic!("got message with unknown tag {}", tag),
}; };
} }

View File

@ -7,6 +7,8 @@ use bitvec::prelude::{BitSlice, Lsb0};
use either::Either::{Left, Right}; use either::Either::{Left, Right};
use intmap::IntMap; use intmap::IntMap;
crate::gdb!();
pub fn met0_usize(atom: Atom) -> usize { pub fn met0_usize(atom: Atom) -> usize {
let atom_bitslice = atom.as_bitslice(); let atom_bitslice = atom.as_bitslice();
match atom_bitslice.last_one() { match atom_bitslice.last_one() {

View File

@ -24,6 +24,8 @@ use std::path::PathBuf;
use std::ptr::copy_nonoverlapping; use std::ptr::copy_nonoverlapping;
use std::ptr::write_bytes; use std::ptr::write_bytes;
crate::gdb!();
pub fn save(stack: &mut NockStack, mut snap_path: PathBuf, event_number: u64, arvo: Noun) { pub fn save(stack: &mut NockStack, mut snap_path: PathBuf, event_number: u64, arvo: Noun) {
// Find the latest valid snapshot, and write to the other file. // Find the latest valid snapshot, and write to the other file.
let prev_snap = if let Ok((prev_snap, _, _)) = latest_snapshot(stack, snap_path.clone()) { let prev_snap = if let Ok((prev_snap, _, _)) = latest_snapshot(stack, snap_path.clone()) {