mirror of
https://github.com/urbit/shrub.git
synced 2024-12-19 00:13:12 +03:00
Adds %meme and %xray hints.
%meme reports mem usage at callsite. %xray prints the vere bytecode of the hoon tree wrapped by the hint.
This commit is contained in:
parent
460e7c8800
commit
2dfde98b0f
@ -2,7 +2,7 @@
|
|||||||
:: there is no need to include the hints for dynamic %bout
|
:: there is no need to include the hints for dynamic %bout
|
||||||
:: since all hoon tests exersize dynamic %bout
|
:: since all hoon tests exersize dynamic %bout
|
||||||
|%
|
|%
|
||||||
:: these test that the hilt-trace hints
|
:: these test that the hilt trace hints
|
||||||
:: are safe to run or ignore
|
:: are safe to run or ignore
|
||||||
++ test-hela-hilt
|
++ test-hela-hilt
|
||||||
~> %hela
|
~> %hela
|
||||||
@ -10,7 +10,12 @@
|
|||||||
++ test-nara-hilt
|
++ test-nara-hilt
|
||||||
~> %nara
|
~> %nara
|
||||||
~
|
~
|
||||||
:: these test that the hint-trace hints
|
:: test that the hilt memory-report hint
|
||||||
|
:: is safe to run or ignore
|
||||||
|
++ test-meme-hilt
|
||||||
|
~> %meme
|
||||||
|
~
|
||||||
|
:: these test that the hint trace hints
|
||||||
:: are safe to run or ignore
|
:: are safe to run or ignore
|
||||||
++ test-hela-hint
|
++ test-hela-hint
|
||||||
~> %hela.[1 leaf+"test-hela-trace-hint"]
|
~> %hela.[1 leaf+"test-hela-trace-hint"]
|
||||||
@ -18,4 +23,9 @@
|
|||||||
++ test-nara-hint
|
++ test-nara-hint
|
||||||
~> %nara.[1 leaf+"test-nara-trace-hint"]
|
~> %nara.[1 leaf+"test-nara-trace-hint"]
|
||||||
~
|
~
|
||||||
|
:: test that the hilt memory-report hint
|
||||||
|
:: is safe to run or ignore
|
||||||
|
++ test-meme-hint
|
||||||
|
~> %meme.[1 leaf+"test-meme-hint"]
|
||||||
|
~
|
||||||
--
|
--
|
||||||
|
@ -1296,6 +1296,7 @@
|
|||||||
# define c3__wtts c3_s4('w','t','t','s')
|
# define c3__wtts c3_s4('w','t','t','s')
|
||||||
# define c3__wtzp c3_s4('w','t','z','p')
|
# define c3__wtzp c3_s4('w','t','z','p')
|
||||||
# define c3__wyrd c3_s4('w','y','r','d')
|
# define c3__wyrd c3_s4('w','y','r','d')
|
||||||
|
# define c3__xray c3_s4('x','r','a','y')
|
||||||
# define c3__yell c3_s4('y','e','l','l')
|
# define c3__yell c3_s4('y','e','l','l')
|
||||||
# define c3__yelp c3_s4('y','e','l','p')
|
# define c3__yelp c3_s4('y','e','l','p')
|
||||||
# define c3__z c3_s1('z')
|
# define c3__z c3_s1('z')
|
||||||
|
@ -154,8 +154,37 @@
|
|||||||
void
|
void
|
||||||
u3t_slog_hela(c3_l pri_l);
|
u3t_slog_hela(c3_l pri_l);
|
||||||
|
|
||||||
/** Globals.
|
/* u3t_meme(): report memory stats at call time
|
||||||
**/
|
*/
|
||||||
|
void
|
||||||
|
u3t_slog_meme(c3_l pri_l);
|
||||||
|
|
||||||
|
/* u3t_xray(): collect the bytecode data
|
||||||
|
** for the expression wrapped in the 'calling' hint
|
||||||
|
** and print it to the terminal
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u3t_slog_xray(c3_l pri_l, u3_noun inf);
|
||||||
|
|
||||||
|
/* u3t_slog_xray_raw(): this is for me to hack on
|
||||||
|
** it must be replace with u3t_xray() before release.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u3t_slog_xray_raw(c3_l pri_l, u3_noun fol, c3_w ip_w);
|
||||||
|
|
||||||
|
/* u3t_slog_memory():
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u3t_slog_memory(c3_l pri_l, c3_c* cap_c, float percent, c3_w wor_w);
|
||||||
|
|
||||||
|
/* u3t_slog_steps():
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u3t_slog_steps(c3_l pri_l, c3_c* cap_c, c3_d sep_d);
|
||||||
|
|
||||||
|
|
||||||
|
/* Globals.
|
||||||
|
*/
|
||||||
/* u3_Trace / u3C: global memory control.
|
/* u3_Trace / u3C: global memory control.
|
||||||
*/
|
*/
|
||||||
c3_global u3t_trace u3t_Trace;
|
c3_global u3t_trace u3t_Trace;
|
||||||
|
@ -1136,11 +1136,17 @@ u3m_soft_run(u3_noun gul,
|
|||||||
u3t_off(coy_o);
|
u3t_off(coy_o);
|
||||||
pro = fun_f(aga, agb);
|
pro = fun_f(aga, agb);
|
||||||
|
|
||||||
|
/*
|
||||||
#ifdef U3_CPU_DEBUG
|
#ifdef U3_CPU_DEBUG
|
||||||
|
// TODO: maybe this should just go away since the %meme hint reports this better
|
||||||
if ( u3R->all.max_w > 1000000 ) {
|
if ( u3R->all.max_w > 1000000 ) {
|
||||||
|
// the old interupting way
|
||||||
u3a_print_memory(stderr, "execute: run", u3R->all.max_w);
|
u3a_print_memory(stderr, "execute: run", u3R->all.max_w);
|
||||||
|
// the new well behaved way
|
||||||
|
u3t_slog_memory(2, "execute: run", 0.0, u3R->all.max_w*4);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
/* Today you can't run -g without memory debug, but you should be
|
/* Today you can't run -g without memory debug, but you should be
|
||||||
* able to.
|
* able to.
|
||||||
@ -1830,7 +1836,8 @@ u3m_boot(c3_c* dir_c)
|
|||||||
if ( c3n == nuu_o ) {
|
if ( c3n == nuu_o ) {
|
||||||
u3j_ream();
|
u3j_ream();
|
||||||
u3n_ream();
|
u3n_ream();
|
||||||
|
// TODO: remove me before PR
|
||||||
|
u3m_reclaim();
|
||||||
return u3A->eve_d;
|
return u3A->eve_d;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -388,102 +388,107 @@ _n_nock_on(u3_noun bus, u3_noun fol)
|
|||||||
// the opcode's enum name, string representation, and computed goto into a
|
// the opcode's enum name, string representation, and computed goto into a
|
||||||
// single structure.
|
// single structure.
|
||||||
#define OPCODES \
|
#define OPCODES \
|
||||||
/* general purpose */ \
|
/* non-nock bytecodes */ \
|
||||||
X(HALT, "halt", &&do_halt), /* 0 */ \
|
X(HALT, "halt", &&do_halt), /* 0: terminator, end of bytcode program */ \
|
||||||
X(BAIL, "bail", &&do_bail), /* 1 */ \
|
X(BAIL, "bail", &&do_bail), /* 1: deterministic crash */ \
|
||||||
|
/* stack manipulation */ \
|
||||||
X(COPY, "copy", &&do_copy), /* 2 */ \
|
X(COPY, "copy", &&do_copy), /* 2 */ \
|
||||||
X(SWAP, "swap", &&do_swap), /* 3 */ \
|
X(SWAP, "swap", &&do_swap), /* 3 */ \
|
||||||
X(TOSS, "toss", &&do_toss), /* 4 */ \
|
X(TOSS, "toss", &&do_toss), /* 4 */ \
|
||||||
X(AUTO, "auto", &&do_auto), /* 5 */ \
|
/* auto-cons */ \
|
||||||
X(AULT, "ault", &&do_ault), /* 6 */ \
|
X(AUTO, "auto", &&do_auto), /* 5: keep */ \
|
||||||
X(SNOC, "snoc", &&do_snoc), /* 7 */ \
|
X(AULT, "ault", &&do_ault), /* 6: lose */ \
|
||||||
X(SNOL, "snol", &&do_snol), /* 8 */ \
|
/* general purposes */ \
|
||||||
X(HEAD, "head", &&do_head), /* 9 */ \
|
X(SNOC, "snoc", &&do_snoc), /* 7: keep */ \
|
||||||
X(HELD, "held", &&do_held), /* 10 */ \
|
X(SNOL, "snol", &&do_snol), /* 8: lose */ \
|
||||||
X(TAIL, "tail", &&do_tail), /* 11 */ \
|
/* nock 0: head */ \
|
||||||
X(TALL, "tall", &&do_tall), /* 12 */ \
|
X(HEAD, "head", &&do_head), /* 9: keep */ \
|
||||||
/* fragment (keep) */ \
|
X(HELD, "held", &&do_held), /* 10: lose */ \
|
||||||
X(FABK, "fabk", &&do_fabk), /* 13 */ \
|
/* nock 0: tail */ \
|
||||||
X(FASK, "fask", &&do_fask), /* 14 */ \
|
X(TAIL, "tail", &&do_tail), /* 11: keep */ \
|
||||||
X(FIBK, "fibk", &&do_fibk), /* 15 */ \
|
X(TALL, "tall", &&do_tall), /* 12: lose */ \
|
||||||
X(FISK, "fisk", &&do_fisk), /* 16 */ \
|
/* nock 0: fragment (keep) */ \
|
||||||
/* fragment (lose) */ \
|
X(FABK, "fabk", &&do_fabk), /* 13: c3_y */ \
|
||||||
X(FABL, "fabl", &&do_fabl), /* 17 */ \
|
X(FASK, "fask", &&do_fask), /* 14: c3_s */ \
|
||||||
X(FASL, "fasl", &&do_fasl), /* 18 */ \
|
X(FIBK, "fibk", &&do_fibk), /* 15: c3_y */ \
|
||||||
X(FIBL, "fibl", &&do_fibl), /* 19 */ \
|
X(FISK, "fisk", &&do_fisk), /* 16: c3_s */ \
|
||||||
X(FISL, "fisl", &&do_fisl), /* 20 */ \
|
/* nock 0: fragment (lose) */ \
|
||||||
/* literal (keep) */ \
|
X(FABL, "fabl", &&do_fabl), /* 17: c3_y */ \
|
||||||
X(LIT0, "lit0", &&do_lit0), /* 21 */ \
|
X(FASL, "fasl", &&do_fasl), /* 18: c3_s */ \
|
||||||
X(LIT1, "lit1", &&do_lit1), /* 22 */ \
|
X(FIBL, "fibl", &&do_fibl), /* 19: c3_y */ \
|
||||||
X(LITB, "litb", &&do_litb), /* 23 */ \
|
X(FISL, "fisl", &&do_fisl), /* 20: c3_s */ \
|
||||||
X(LITS, "lits", &&do_lits), /* 24 */ \
|
/* nock 1: literal (keep) */ \
|
||||||
X(LIBK, "libk", &&do_libk), /* 25 */ \
|
X(LIT0, "lit0", &&do_lit0), /* 21: a literal 0 */ \
|
||||||
X(LISK, "lisk", &&do_lisk), /* 26 */ \
|
X(LIT1, "lit1", &&do_lit1), /* 22: a literal 1 */ \
|
||||||
/* literal (lose) */ \
|
X(LITB, "litb", &&do_litb), /* 23: c3_y */ \
|
||||||
X(LIL0, "lil0", &&do_lil0), /* 27 */ \
|
X(LITS, "lits", &&do_lits), /* 24: c3_s */ \
|
||||||
X(LIL1, "lil1", &&do_lil1), /* 28 */ \
|
X(LIBK, "libk", &&do_libk), /* 25: c3_y */ \
|
||||||
X(LILB, "lilb", &&do_lilb), /* 29 */ \
|
X(LISK, "lisk", &&do_lisk), /* 26: c3_s */ \
|
||||||
X(LILS, "lils", &&do_lils), /* 30 */ \
|
/* nock 1: literal (lose) */ \
|
||||||
X(LIBL, "libl", &&do_libl), /* 31 */ \
|
X(LIL0, "lil0", &&do_lil0), /* 27: a literal 0 */ \
|
||||||
X(LISL, "lisl", &&do_lisl), /* 32 */ \
|
X(LIL1, "lil1", &&do_lil1), /* 28: a literal 1 */ \
|
||||||
/* nock */ \
|
X(LILB, "lilb", &&do_lilb), /* 29: c3_y */ \
|
||||||
|
X(LILS, "lils", &&do_lils), /* 30: c3_s */ \
|
||||||
|
X(LIBL, "libl", &&do_libl), /* 31: c3_y */ \
|
||||||
|
X(LISL, "lisl", &&do_lisl), /* 32: c3_s */ \
|
||||||
|
/* nock 2: nock (lose) */ \
|
||||||
X(NOLK, "nolk", &&do_nolk), /* 33 */ \
|
X(NOLK, "nolk", &&do_nolk), /* 33 */ \
|
||||||
X(NOCT, "noct", &&do_noct), /* 34 */ \
|
X(NOCT, "noct", &&do_noct), /* 34 */ \
|
||||||
X(NOCK, "nock", &&do_nock), /* 35 */ \
|
X(NOCK, "nock", &&do_nock), /* 35 */ \
|
||||||
/* 3 & 4 */ \
|
/* nock 3 & 4 */ \
|
||||||
X(DEEP, "deep", &&do_deep), /* 36 */ \
|
X(DEEP, "deep", &&do_deep), /* 36 */ \
|
||||||
X(BUMP, "bump", &&do_bump), /* 37 */ \
|
X(BUMP, "bump", &&do_bump), /* 37 */ \
|
||||||
/* equality */ \
|
/* nock 5: equality */ \
|
||||||
X(SAM0, "sam0", &&do_sam0), /* 38 */ \
|
X(SAM0, "sam0", &&do_sam0), /* 38: test that it is equal to 0 */ \
|
||||||
X(SAM1, "sam1", &&do_sam1), /* 39 */ \
|
X(SAM1, "sam1", &&do_sam1), /* 39: test that it is equal to 1 */ \
|
||||||
X(SAMB, "samb", &&do_samb), /* 40 */ \
|
X(SAMB, "samb", &&do_samb), /* 40: test equality for vars size c3_b */ \
|
||||||
X(SAMS, "sams", &&do_sams), /* 41 */ \
|
X(SAMS, "sams", &&do_sams), /* 41: test equality for vars size c3_s */ \
|
||||||
X(SANB, "sanb", &&do_sanb), /* 42 */ \
|
X(SANB, "sanb", &&do_sanb), /* 42: test equality for vars size c3_b */ \
|
||||||
X(SANS, "sans", &&do_sans), /* 43 */ \
|
X(SANS, "sans", &&do_sans), /* 43: test equality for vars size c3_s */ \
|
||||||
X(SAME, "same", &&do_same), /* 44 */ \
|
X(SAME, "same", &&do_same), /* 44 */ \
|
||||||
X(SALM, "salm", &&do_salm), /* 45 */ \
|
X(SALM, "salm", &&do_salm), /* 45 */ \
|
||||||
X(SAMC, "samc", &&do_samc), /* 46 */ \
|
X(SAMC, "samc", &&do_samc), /* 46 */ \
|
||||||
/* unconditional skips */ \
|
/* related to nock 6: unconditional skips */ \
|
||||||
X(SBIP, "sbip", &&do_sbip), /* 47 */ \
|
X(SBIP, "sbip", &&do_sbip), /* 47: c3_b */ \
|
||||||
X(SIPS, "sips", &&do_sips), /* 48 */ \
|
X(SIPS, "sips", &&do_sips), /* 48: c3_s */ \
|
||||||
X(SWIP, "swip", &&do_swip), /* 49 */ \
|
X(SWIP, "swip", &&do_swip), /* 49: c3_l */ \
|
||||||
/* conditional skips */ \
|
/* related to nock 6: conditional skips */ \
|
||||||
X(SBIN, "sbin", &&do_sbin), /* 50 */ \
|
X(SBIN, "sbin", &&do_sbin), /* 50: c3_b */ \
|
||||||
X(SINS, "sins", &&do_sins), /* 51 */ \
|
X(SINS, "sins", &&do_sins), /* 51: c3_s */ \
|
||||||
X(SWIN, "swin", &&do_swin), /* 52 */ \
|
X(SWIN, "swin", &&do_swin), /* 52: c3_l */ \
|
||||||
/* nock 9 */ \
|
/* nock 9 */ \
|
||||||
X(KICB, "kicb", &&do_kicb), /* 53 */ \
|
X(KICB, "kicb", &&do_kicb), /* 53: c3_b */ \
|
||||||
X(KICS, "kics", &&do_kics), /* 54 */ \
|
X(KICS, "kics", &&do_kics), /* 54: c3_s */ \
|
||||||
X(TICB, "ticb", &&do_ticb), /* 55 */ \
|
X(TICB, "ticb", &&do_ticb), /* 55: c3_b */ \
|
||||||
X(TICS, "tics", &&do_tics), /* 56 */ \
|
X(TICS, "tics", &&do_tics), /* 56: c3_s */ \
|
||||||
/* nock 12 */ \
|
/* nock 12: scry (only defined in arvo, not in base nock spec) */ \
|
||||||
X(WILS, "wils", &&do_wils), /* 57 */ \
|
X(WILS, "wils", &&do_wils), /* 57 */ \
|
||||||
X(WISH, "wish", &&do_wish), /* 58 */ \
|
X(WISH, "wish", &&do_wish), /* 58 */ \
|
||||||
/* hint processing */ \
|
/* nock 11: hint processing */ \
|
||||||
X(BUSH, "bush", &&do_bush), /* 59 */ \
|
X(BUSH, "bush", &&do_bush), /* 59: c3_b */ \
|
||||||
X(SUSH, "sush", &&do_sush), /* 60 */ \
|
X(SUSH, "sush", &&do_sush), /* 60: c3_s */ \
|
||||||
X(DROP, "drop", &&do_drop), /* 61 */ \
|
X(DROP, "drop", &&do_drop), /* 61 */ \
|
||||||
X(HECK, "heck", &&do_heck), /* 62 */ \
|
X(HECK, "heck", &&do_heck), /* 62 */ \
|
||||||
X(SLOG, "slog", &&do_slog), /* 63 */ \
|
X(SLOG, "slog", &&do_slog), /* 63 */ \
|
||||||
/* fast (keep) */ \
|
/* nock 11: fast (keep) */ \
|
||||||
X(BAST, "bast", &&do_bast), /* 64 */ \
|
X(BAST, "bast", &&do_bast), /* 64: c3_b */ \
|
||||||
X(SAST, "sast", &&do_sast), /* 65 */ \
|
X(SAST, "sast", &&do_sast), /* 65: c3_s */ \
|
||||||
/* fast (lose) */ \
|
/* nock 11: fast (lose) */ \
|
||||||
X(BALT, "balt", &&do_balt), /* 66 */ \
|
X(BALT, "balt", &&do_balt), /* 66: c3_b */ \
|
||||||
X(SALT, "salt", &&do_salt), /* 67 */ \
|
X(SALT, "salt", &&do_salt), /* 67: c3_s */ \
|
||||||
/* memo (keep) */ \
|
/* nock 11: memo (keep) */ \
|
||||||
X(SKIB, "skib", &&do_skib), /* 68 */ \
|
X(SKIB, "skib", &&do_skib), /* 68: c3_b */ \
|
||||||
X(SKIS, "skis", &&do_skis), /* 69 */ \
|
X(SKIS, "skis", &&do_skis), /* 69: c3_s */ \
|
||||||
/* memo (lose) */ \
|
/* nock 11: memo (lose) */ \
|
||||||
X(SLIB, "slib", &&do_slib), /* 70 */ \
|
X(SLIB, "slib", &&do_slib), /* 70: c3_b */ \
|
||||||
X(SLIS, "slis", &&do_slis), /* 71 */ \
|
X(SLIS, "slis", &&do_slis), /* 71: c3_s */ \
|
||||||
X(SAVE, "save", &&do_save), /* 72 */ \
|
X(SAVE, "save", &&do_save), /* 72 */ \
|
||||||
/* before formula */ \
|
/* nock 11: before formula */ \
|
||||||
X(HILB, "hilb", &&do_hilb), /* 73: atomic, byte */ \
|
X(HILB, "hilb", &&do_hilb), /* 73: atomic, byte */ \
|
||||||
X(HILS, "hils", &&do_hils), /* 74: atomic, short */ \
|
X(HILS, "hils", &&do_hils), /* 74: atomic, short */ \
|
||||||
X(HINB, "hinb", &&do_hinb), /* 75: arbitrary, byte */ \
|
X(HINB, "hinb", &&do_hinb), /* 75: arbitrary, byte */ \
|
||||||
X(HINS, "hins", &&do_hins), /* 76: arbitrary, short */ \
|
X(HINS, "hins", &&do_hins), /* 76: arbitrary, short */ \
|
||||||
/* after formula */ \
|
/* nock 11: after formula */ \
|
||||||
X(HILK, "hilk", &&do_hilk), /* 77: atomic, keep */ \
|
X(HILK, "hilk", &&do_hilk), /* 77: atomic, keep */ \
|
||||||
X(HILL, "hill", &&do_hill), /* 78: atomic, lose */ \
|
X(HILL, "hill", &&do_hill), /* 78: atomic, lose */ \
|
||||||
X(HINK, "hink", &&do_hink), /* 79: arbitrary, keep */ \
|
X(HINK, "hink", &&do_hink), /* 79: arbitrary, keep */ \
|
||||||
@ -495,20 +500,20 @@ _n_nock_on(u3_noun bus, u3_noun fol)
|
|||||||
X(KUTT, "kutt", &&do_kutt), /* 84 */ \
|
X(KUTT, "kutt", &&do_kutt), /* 84 */ \
|
||||||
X(MUSM, "musm", &&do_musm), /* 85 */ \
|
X(MUSM, "musm", &&do_musm), /* 85 */ \
|
||||||
X(KUSM, "kusm", &&do_kusm), /* 86 */ \
|
X(KUSM, "kusm", &&do_kusm), /* 86 */ \
|
||||||
X(MUTB, "mutb", &&do_mutb), /* 87 */ \
|
X(MUTB, "mutb", &&do_mutb), /* 87: c3_b */ \
|
||||||
X(MUTS, "muts", &&do_muts), /* 88 */ \
|
X(MUTS, "muts", &&do_muts), /* 88: c3_s */ \
|
||||||
X(MITB, "mitb", &&do_mitb), /* 89 */ \
|
X(MITB, "mitb", &&do_mitb), /* 89: c3_b */ \
|
||||||
X(MITS, "mits", &&do_mits), /* 90 */ \
|
X(MITS, "mits", &&do_mits), /* 90: c3_s, seems unused in codebase */ \
|
||||||
X(KUTB, "kutb", &&do_kutb), /* 91 */ \
|
X(KUTB, "kutb", &&do_kutb), /* 91: c3_b */ \
|
||||||
X(KUTS, "kuts", &&do_kuts), /* 92 */ \
|
X(KUTS, "kuts", &&do_kuts), /* 92: c3_s */ \
|
||||||
X(KITB, "kitb", &&do_kitb), /* 93 */ \
|
X(KITB, "kitb", &&do_kitb), /* 93: c3_b */ \
|
||||||
X(KITS, "kits", &&do_kits), /* 94 */ \
|
X(KITS, "kits", &&do_kits), /* 94: c3_s, seems unused in codebase */ \
|
||||||
X(LAST, NULL, NULL), /* 95 */
|
X(LAST, NULL, NULL), /* 95 */
|
||||||
|
|
||||||
// Opcodes. Define X to select the enum name from OPCODES.
|
// Opcodes. Define X to select the enum name from OPCODES.
|
||||||
#define X(opcode, name, indirect_jump) opcode
|
#define X(opcode, name, indirect_jump) opcode
|
||||||
enum { OPCODES };
|
enum { OPCODES };
|
||||||
#undef X
|
#undef X
|
||||||
|
/* TODO: opcodes for nock 7 & 8 seem to be missing */
|
||||||
|
|
||||||
/* _n_arg(): return the size (in bytes) of an opcode's argument
|
/* _n_arg(): return the size (in bytes) of an opcode's argument
|
||||||
*/
|
*/
|
||||||
@ -779,7 +784,8 @@ _n_prog_asm(u3_noun ops, u3n_prog* pog_u, u3_noun sip)
|
|||||||
if ( c3y == u3ud(op) ) {
|
if ( c3y == u3ud(op) ) {
|
||||||
switch ( op ) {
|
switch ( op ) {
|
||||||
default:
|
default:
|
||||||
buf_y[i_w] = (c3_y) u3h(ops);
|
// just reuse op
|
||||||
|
buf_y[i_w] = (c3_y) op;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* registration site index args */
|
/* registration site index args */
|
||||||
@ -877,6 +883,49 @@ _n_prog_asm(u3_noun ops, u3n_prog* pog_u, u3_noun sip)
|
|||||||
case BUSH: case SANB:
|
case BUSH: case SANB:
|
||||||
case KITB: case MITB:
|
case KITB: case MITB:
|
||||||
case HILB: case HINB:
|
case HILB: case HINB:
|
||||||
|
/* TODO:
|
||||||
|
** check tail of op for being xray
|
||||||
|
** if so call a rendering and cons to tail of op
|
||||||
|
** like sip list in melt?
|
||||||
|
** take interpret buffy upto nef_w
|
||||||
|
*/
|
||||||
|
|
||||||
|
// check tail of op for being xray
|
||||||
|
/*if ( c3__xray == u3k(u3t(op)) ) {
|
||||||
|
// TODO: render everything called until this point
|
||||||
|
// ie take whatever the analog of fol is, and run it through
|
||||||
|
// something like _slog_bytecode without sloging it, to convert
|
||||||
|
// it to a u3i_string, then store that to the tail of op
|
||||||
|
// TODO: cons the rendered data to tail of op
|
||||||
|
// TODO: slog out info on what is compiling right now
|
||||||
|
u3_noun op_string = u3i_string("xray");
|
||||||
|
switch ( cod ) {
|
||||||
|
default: break;
|
||||||
|
case FIBK: u3t_slog_cap(1, u3i_string("FIBK"), op_string); break;
|
||||||
|
case FIBL: u3t_slog_cap(1, u3i_string("FIBL"), op_string); break;
|
||||||
|
case LIBK: u3t_slog_cap(1, u3i_string("LIBK"), op_string); break;
|
||||||
|
case LIBL: u3t_slog_cap(1, u3i_string("LIBL"), op_string); break;
|
||||||
|
case BUSH: u3t_slog_cap(1, u3i_string("BUSH"), op_string); break;
|
||||||
|
case SANB: u3t_slog_cap(1, u3i_string("SANB"), op_string); break;
|
||||||
|
case KITB: u3t_slog_cap(1, u3i_string("KITB"), op_string); break;
|
||||||
|
case MITB: u3t_slog_cap(1, u3i_string("MITB"), op_string); break;
|
||||||
|
case HILB: u3t_slog_cap(1, u3i_string("HILB"), op_string); break;
|
||||||
|
case HINB: u3t_slog_cap(1, u3i_string("HINB"), op_string); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_n_prog_asm_inx(buf_y, &i_w, lit_s, cod);
|
||||||
|
pog_u->lit_u.non[lit_s++] = u3k(u3t(op));
|
||||||
|
|
||||||
|
// NOTE: buf_y is pog_u->byc_u.ops_y ie it is arg #1 for render bytecode
|
||||||
|
// NOTE: ___ is arg #2 for render_bytecode (aka c3_w her_w)
|
||||||
|
// i_W
|
||||||
|
_slog_bytecode(1, buf_y, 0);
|
||||||
|
_slog_bytecode(1, pog_u->byc_u.ops_y, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_n_prog_asm_inx(buf_y, &i_w, lit_s, cod);
|
||||||
|
pog_u->lit_u.non[lit_s++] = u3k(u3t(op));
|
||||||
|
}*/
|
||||||
_n_prog_asm_inx(buf_y, &i_w, lit_s, cod);
|
_n_prog_asm_inx(buf_y, &i_w, lit_s, cod);
|
||||||
pog_u->lit_u.non[lit_s++] = u3k(u3t(op));
|
pog_u->lit_u.non[lit_s++] = u3k(u3t(op));
|
||||||
break;
|
break;
|
||||||
@ -956,12 +1005,12 @@ static void _n_print_stack(u3p(u3_noun) empty) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VERBOSE_BYTECODE
|
//#ifdef VERBOSE_BYTECODE
|
||||||
// Define X to select the opcode string representation from OPCODES.
|
// Define X to select the opcode string representation from OPCODES.
|
||||||
# define X(opcode, name, indirect_jump) name
|
# define X(opcode, name, indirect_jump) name
|
||||||
static c3_c* opcode_names[] = { OPCODES };
|
static c3_c* opcode_names[] = { OPCODES };
|
||||||
# undef X
|
# undef X
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
/* _n_apen(): emit the instructions contained in src to dst
|
/* _n_apen(): emit the instructions contained in src to dst
|
||||||
*/
|
*/
|
||||||
@ -998,6 +1047,12 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o)
|
|||||||
default: {
|
default: {
|
||||||
return _n_comp(ops, nef, los_o, tel_o);
|
return _n_comp(ops, nef, los_o, tel_o);
|
||||||
}
|
}
|
||||||
|
/* TODO:
|
||||||
|
** for case xray pack more info into HILB
|
||||||
|
** place nef_w into HILB trel
|
||||||
|
*/
|
||||||
|
case c3__xray:
|
||||||
|
case c3__meme:
|
||||||
case c3__nara:
|
case c3__nara:
|
||||||
case c3__hela:
|
case c3__hela:
|
||||||
case c3__bout: {
|
case c3__bout: {
|
||||||
@ -1009,7 +1064,7 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o)
|
|||||||
++nef_w; _n_emit(&fen, u3nc(SBIP, 1));
|
++nef_w; _n_emit(&fen, u3nc(SBIP, 1));
|
||||||
|
|
||||||
// call hilt_fore
|
// call hilt_fore
|
||||||
// HILB overflows to HILS
|
// HILB overflows to HILS - NOTE: this becomes hin
|
||||||
++tot_w; _n_emit(ops, u3nc(HILB, u3nc(u3k(hif), u3k(nef))));
|
++tot_w; _n_emit(ops, u3nc(HILB, u3nc(u3k(hif), u3k(nef))));
|
||||||
// if fore return c3n, skip fen
|
// if fore return c3n, skip fen
|
||||||
++tot_w; _n_emit(ops, u3nc(SBIN, nef_w));
|
++tot_w; _n_emit(ops, u3nc(SBIN, nef_w));
|
||||||
@ -1034,6 +1089,12 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o)
|
|||||||
++tot_w; _n_emit(ops, TOSS);
|
++tot_w; _n_emit(ops, TOSS);
|
||||||
tot_w += _n_comp(ops, nef, los_o, tel_o);
|
tot_w += _n_comp(ops, nef, los_o, tel_o);
|
||||||
} break;
|
} break;
|
||||||
|
/* TODO:
|
||||||
|
** for case xray pack more info into HILB
|
||||||
|
** place nef_w into HINB trel
|
||||||
|
*/
|
||||||
|
case c3__xray:
|
||||||
|
case c3__meme:
|
||||||
case c3__nara:
|
case c3__nara:
|
||||||
case c3__hela:
|
case c3__hela:
|
||||||
case c3__bout: {
|
case c3__bout: {
|
||||||
@ -1047,7 +1108,7 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o)
|
|||||||
// push clue
|
// push clue
|
||||||
tot_w += _n_comp(ops, hod, c3n, c3n);
|
tot_w += _n_comp(ops, hod, c3n, c3n);
|
||||||
// call hint_fore
|
// call hint_fore
|
||||||
// HINB overflows to HINS
|
// HINB overflows to HINS - NOTE: does this also becom hin?
|
||||||
++tot_w; _n_emit(ops, u3nc(HINB, u3nc(u3k(zep), u3k(nef))));
|
++tot_w; _n_emit(ops, u3nc(HINB, u3nc(u3k(zep), u3k(nef))));
|
||||||
// if fore return c3n, skip fen
|
// if fore return c3n, skip fen
|
||||||
++tot_w; _n_emit(ops, u3nc(SBIN, nef_w));
|
++tot_w; _n_emit(ops, u3nc(SBIN, nef_w));
|
||||||
@ -1192,11 +1253,11 @@ _n_comp(u3_noun* ops, u3_noun fol, c3_o los_o, c3_o tel_o)
|
|||||||
u3_noun cod, arg, hed, tel;
|
u3_noun cod, arg, hed, tel;
|
||||||
u3x_cell(fol, &cod, &arg);
|
u3x_cell(fol, &cod, &arg);
|
||||||
if ( c3y == u3du(cod) ) {
|
if ( c3y == u3du(cod) ) {
|
||||||
tot_w += _n_comp(ops, cod, c3n, c3n);
|
tot_w += _n_comp(ops, cod, c3n, c3n); // [hed bus ..] // compute head: don't lose, not in tail
|
||||||
++tot_w; _n_emit(ops, SWAP);
|
++tot_w; _n_emit(ops, SWAP); // [bus hed ..]
|
||||||
tot_w += _n_comp(ops, arg, c3n, c3n);
|
tot_w += _n_comp(ops, arg, c3n, c3n); // [tel bus hed ..] // compute tail: don't lose, not in tail
|
||||||
++tot_w; _n_emit(ops, (c3y == los_o ) ? AULT : AUTO);
|
++tot_w; _n_emit(ops, (c3y == los_o ) ? AULT : AUTO); // [[hed tel] ..]
|
||||||
}
|
} // [[hed tel] bus ..]
|
||||||
else switch ( cod ) {
|
else switch ( cod ) {
|
||||||
case 0:
|
case 0:
|
||||||
if ( c3n == u3ud(arg) ) {
|
if ( c3n == u3ud(arg) ) {
|
||||||
@ -1230,12 +1291,12 @@ _n_comp(u3_noun* ops, u3_noun fol, c3_o los_o, c3_o tel_o)
|
|||||||
case 1:
|
case 1:
|
||||||
switch ( arg ) {
|
switch ( arg ) {
|
||||||
case 0:
|
case 0:
|
||||||
++tot_w; _n_emit(ops, (c3y == los_o) ? LIL0 : LIT0);
|
++tot_w; _n_emit(ops, (c3y == los_o) ? LIL0 : LIT0); // an actual value of 0
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
++tot_w; _n_emit(ops, (c3y == los_o) ? LIL1 : LIT1);
|
++tot_w; _n_emit(ops, (c3y == los_o) ? LIL1 : LIT1); // an actual value of 1
|
||||||
break;
|
break;
|
||||||
default:
|
default: // these are all indexes
|
||||||
op_y = (c3y == los_o)
|
op_y = (c3y == los_o)
|
||||||
? (arg <= 0xFF ? LILB : arg <= 0xFFFF ? LILS : LIBL) // overflows to LISL
|
? (arg <= 0xFF ? LILB : arg <= 0xFFFF ? LILS : LIBL) // overflows to LISL
|
||||||
: (arg <= 0xFF ? LITB : arg <= 0xFFFF ? LITS : LIBK); // overflows to LISK
|
: (arg <= 0xFF ? LITB : arg <= 0xFFFF ? LITS : LIBK); // overflows to LISK
|
||||||
@ -1665,6 +1726,139 @@ u3n_find(u3_noun key, u3_noun fol)
|
|||||||
return pog_p;
|
return pog_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------DANE------
|
||||||
|
/* _n_prog_free(): free memory retained by program
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_n_prog_free_willy(u3n_prog* pog_u)
|
||||||
|
{
|
||||||
|
c3_w i_w;
|
||||||
|
for ( i_w = 0; i_w < pog_u->lit_u.len_w; ++i_w ) {
|
||||||
|
u3z(pog_u->lit_u.non[i_w]);
|
||||||
|
}
|
||||||
|
for ( i_w = 0; i_w < pog_u->mem_u.len_w; ++i_w ) {
|
||||||
|
u3z(pog_u->mem_u.sot_u[i_w].key);
|
||||||
|
}
|
||||||
|
for ( i_w = 0; i_w < pog_u->cal_u.len_w; ++i_w ) {
|
||||||
|
u3j_site_lose(&(pog_u->cal_u.sit_u[i_w]));
|
||||||
|
}
|
||||||
|
for ( i_w = 0; i_w < pog_u->reg_u.len_w; ++i_w ) {
|
||||||
|
u3j_rite_lose(&(pog_u->reg_u.rit_u[i_w]));
|
||||||
|
}
|
||||||
|
u3a_free(pog_u);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_intlen (int value)
|
||||||
|
{
|
||||||
|
int x=!value;
|
||||||
|
while(value){
|
||||||
|
value/=10;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _is_valid_op(int go) {
|
||||||
|
return (go == 0 || go == 1 || go == 2 | go == 4);
|
||||||
|
}
|
||||||
|
int _is_pair_op(int go) {
|
||||||
|
return (go == 1 || go == 2 | go == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_slog_bytecode(c3_l pri_l, c3_y* pog, c3_w her_w) {
|
||||||
|
c3_w ip_w = 0;
|
||||||
|
// NOTE: if we change the main loop, we should c/p
|
||||||
|
// it back up here to replace this loop,
|
||||||
|
// then replace all string ops with increments
|
||||||
|
// thats how I did it in the first place.
|
||||||
|
// lets count the chars in this string
|
||||||
|
unsigned int s_ln = 1; // opening "{"
|
||||||
|
// set go to an invalid value, so we can break imeadately if needed
|
||||||
|
unsigned int go = 5;
|
||||||
|
while ( pog[ip_w] ) {
|
||||||
|
go = _n_arg(pog[ip_w]);
|
||||||
|
// no need to stay here if we cant print it
|
||||||
|
if (!_is_valid_op(go)) break;
|
||||||
|
ip_w++; // move ip_w for reading a opcode name
|
||||||
|
s_ln += 4; // opcode name, which is always 4 char long
|
||||||
|
if (_is_pair_op(go)) {
|
||||||
|
// add the len of the number
|
||||||
|
s_ln += _intlen(
|
||||||
|
go == 4 ? _n_rewo(pog, &ip_w):
|
||||||
|
go == 2 ? _n_resh(pog, &ip_w):
|
||||||
|
pog[ip_w++]);
|
||||||
|
s_ln+= 3; // "[", the space between the opcode and number, "]"
|
||||||
|
}
|
||||||
|
s_ln++; // add trailing space before next word in string
|
||||||
|
if (ip_w == her_w) s_ln +=3; // add "[*]" before next word
|
||||||
|
}
|
||||||
|
s_ln += 5; //add "halt}" to end of the bytecode
|
||||||
|
|
||||||
|
// reset ip_w so we can loop again
|
||||||
|
ip_w = 0;
|
||||||
|
c3_c str_c[s_ln];
|
||||||
|
str_c[0] = 0;
|
||||||
|
strcat(str_c, "{");
|
||||||
|
go = 5;
|
||||||
|
while ( pog[ip_w] ) {
|
||||||
|
go = _n_arg(pog[ip_w]);
|
||||||
|
// no need to stay here if we cant print it
|
||||||
|
if (!_is_valid_op(go)) break;
|
||||||
|
|
||||||
|
// add open brace if the opcode pairs with a number
|
||||||
|
if (_is_pair_op(go)) strcat(str_c, "[");
|
||||||
|
|
||||||
|
// add the opcode name
|
||||||
|
strncat(str_c, opcode_names[pog[ip_w++]], 4);
|
||||||
|
|
||||||
|
// finish the pair
|
||||||
|
if (_is_pair_op(go)) {
|
||||||
|
// add the space
|
||||||
|
strcat(str_c, " ");
|
||||||
|
// get the number
|
||||||
|
int num =
|
||||||
|
go == 4 ? _n_rewo(pog, &ip_w):
|
||||||
|
go == 2 ? _n_resh(pog, &ip_w):
|
||||||
|
pog[ip_w++];
|
||||||
|
if (num == 0) {
|
||||||
|
// handle a litteral zero
|
||||||
|
strcat(str_c, "0");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// add underscores to the buffer for the number
|
||||||
|
for (int x = _intlen(num); x > 0; x--) strcat(str_c, "_");
|
||||||
|
// get the index of the last underscore we added
|
||||||
|
int f = strlen(str_c)-1;
|
||||||
|
// add num to the string by decrementing into str_c,
|
||||||
|
// stuffing the tail of num into each slot
|
||||||
|
while (num > 0) {
|
||||||
|
str_c[f--] = (num%10)+'0';
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add the closing brace
|
||||||
|
strcat(str_c, "]");
|
||||||
|
}
|
||||||
|
strcat(str_c, " ");
|
||||||
|
if (ip_w == her_w) strcat(str_c, "[*]");
|
||||||
|
}
|
||||||
|
strcat(str_c, "halt}");
|
||||||
|
u3t_slog_cap(pri_l, u3i_string("bytecode"), u3i_string(str_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_xray(c3_l pri_l, u3_noun fol) {
|
||||||
|
u3n_prog* pog_u = _n_bite(fol);
|
||||||
|
c3_y* pog = pog_u->byc_u.ops_y;
|
||||||
|
_slog_bytecode(pri_l, pog, pog_u->byc_u.len_w-1);
|
||||||
|
_n_prog_free_willy(pog_u);
|
||||||
|
}
|
||||||
|
// ---------------END DANEs EDIT -----
|
||||||
|
|
||||||
/* _n_hilt_fore(): literal (atomic) dynamic hint, before formula evaluation.
|
/* _n_hilt_fore(): literal (atomic) dynamic hint, before formula evaluation.
|
||||||
** hin: [hint-atom, formula]. TRANSFER
|
** hin: [hint-atom, formula]. TRANSFER
|
||||||
** bus: subject. RETAIN
|
** bus: subject. RETAIN
|
||||||
@ -1695,6 +1889,16 @@ _n_hilt_fore(u3_noun hin, u3_noun bus, u3_noun* out)
|
|||||||
*out = u3_nul;
|
*out = u3_nul;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case c3__meme : {
|
||||||
|
u3t_slog_meme(0);
|
||||||
|
*out = u3_nul;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case c3__xray : {
|
||||||
|
_xray(0, fol);
|
||||||
|
*out = u3_nul;
|
||||||
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
*out = u3_nul;
|
*out = u3_nul;
|
||||||
} break;
|
} break;
|
||||||
@ -1769,6 +1973,28 @@ _n_hint_fore(u3_cell hin, u3_noun bus, u3_noun* clu)
|
|||||||
*clu = u3_nul;
|
*clu = u3_nul;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case c3__meme : {
|
||||||
|
u3_noun pri, tan;
|
||||||
|
if ( c3y == u3r_cell(*clu, &pri, &tan) ) {
|
||||||
|
c3_l pri_l = c3y == u3a_is_cat(pri) ? pri : 0;
|
||||||
|
u3t_slog_cap(pri_l, u3i_string("memeory profile at"), u3k(tan));
|
||||||
|
u3t_slog_meme(pri_l);
|
||||||
|
}
|
||||||
|
u3z(*clu);
|
||||||
|
*clu = u3_nul;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case c3__xray : {
|
||||||
|
u3_noun pri, tan;
|
||||||
|
if ( c3y == u3r_cell(*clu, &pri, &tan) ) {
|
||||||
|
c3_l pri_l = c3y == u3a_is_cat(pri) ? pri : 0;
|
||||||
|
u3t_slog_cap(pri_l, u3i_string("bytecode of"), u3k(tan));
|
||||||
|
_xray(pri_l, fol);
|
||||||
|
}
|
||||||
|
u3z(*clu);
|
||||||
|
*clu = u3_nul;
|
||||||
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
u3z(*clu);
|
u3z(*clu);
|
||||||
*clu = u3_nul;
|
*clu = u3_nul;
|
||||||
@ -2987,3 +3213,4 @@ u3n_nock_an(u3_noun bus, u3_noun fol)
|
|||||||
|
|
||||||
return u3n_nock_et(gul, bus, fol);
|
return u3n_nock_et(gul, bus, fol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,6 +609,24 @@ u3t_slog_cap(c3_l pri_l, u3_noun cap, u3_noun tan)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* _slog_blank(): slog out a blank line with
|
||||||
|
** a given priority c3_l (assumed 0-3).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_slog_blank(c3_l pri_l)
|
||||||
|
{
|
||||||
|
u3t_slog(
|
||||||
|
u3nc(
|
||||||
|
pri_l,
|
||||||
|
u3nt(
|
||||||
|
c3__rose,
|
||||||
|
u3nt(u3nt(' ', ' ', u3_nul), u3_nul, u3_nul),
|
||||||
|
u3nt(u3i_string(" "), u3i_string(" "), u3_nul)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* u3t_slog_trace(): given a c3_l priority pri and a raw stack tax
|
/* u3t_slog_trace(): given a c3_l priority pri and a raw stack tax
|
||||||
** flop the order into start-to-end, render, and slog each item
|
** flop the order into start-to-end, render, and slog each item
|
||||||
@ -620,7 +638,7 @@ u3t_slog_trace(c3_l pri_l, u3_noun tax)
|
|||||||
// render the stack
|
// render the stack
|
||||||
// Note: ton is a reference to a data struct
|
// Note: ton is a reference to a data struct
|
||||||
// we have just allocated
|
// we have just allocated
|
||||||
// lit is a used as a moving cursor pointer through
|
// lit is used as a moving cursor pointer through
|
||||||
// that allocated struct
|
// that allocated struct
|
||||||
// once we finish lit will be null, but ton will still
|
// once we finish lit will be null, but ton will still
|
||||||
// point to the whole valid allocated data structure
|
// point to the whole valid allocated data structure
|
||||||
@ -673,3 +691,421 @@ u3t_slog_hela(c3_l pri_l)
|
|||||||
u3t_slog_trace(pri_l, tax);
|
u3t_slog_trace(pri_l, tax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* _roundf(): truncate a float to preciscon
|
||||||
|
** equivalant to %.2f
|
||||||
|
*/
|
||||||
|
float
|
||||||
|
_roundf(float percent)
|
||||||
|
{
|
||||||
|
// scale the percentage so that all siginificant digits
|
||||||
|
// would be retained when truncted to an int, then add 0.5
|
||||||
|
// to account for rounding without using round or roundf
|
||||||
|
float percent_big_f = (percent*10000)+0.5;
|
||||||
|
// truncate to int
|
||||||
|
int percent_big_i = (int) percent_big_f;
|
||||||
|
// convert to float and scale down such that
|
||||||
|
// our last to digits are right of the decimal
|
||||||
|
float percent_truncated_f = (float) percent_big_i/100.0;
|
||||||
|
return percent_truncated_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
_meme_percent(unsigned int small, unsigned int large)
|
||||||
|
{
|
||||||
|
// get the percentage of our inputs as a float
|
||||||
|
float percent_raw_f = (float) small/large;
|
||||||
|
return _roundf(percent_raw_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void
|
||||||
|
_slog_free_discrepancy( )
|
||||||
|
{
|
||||||
|
c3_w fre_w = u3a_idle(u3R);
|
||||||
|
if ( fre_w != u3R->all.fre_w ) {
|
||||||
|
char* s;
|
||||||
|
int result = asprintf(&s,
|
||||||
|
"%x\n\t\t\tfre_w: %x\n\t\t all.fre_w: %x\n\t\t\t diff: %x",
|
||||||
|
u3R->par_p,
|
||||||
|
fre_w,
|
||||||
|
u3R->all.fre_w,
|
||||||
|
(u3R->all.fre_w - fre_w)
|
||||||
|
);
|
||||||
|
if (0 <= result) {
|
||||||
|
u3t_slog_cap(2, u3i_string(" free discrepancy at par_p"), u3i_string(s));
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _slog_road_depth(c3_l pri_l, u3_road* r, int i) {
|
||||||
|
if (r == &(u3H->rod_u)) {
|
||||||
|
// slog the info
|
||||||
|
unsigned int x = 0;
|
||||||
|
char s[8] = " 0";
|
||||||
|
while (i > 0 && x < 8) {
|
||||||
|
s[6-x] = (i%10)+'0';
|
||||||
|
i /= 10;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
u3t_slog_cap(pri_l, u3i_string(" road depth"), u3i_string(s));
|
||||||
|
} else {
|
||||||
|
// recurse
|
||||||
|
_slog_road_depth(pri_l, u3tn(u3_road, r->par_p), ++i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int _all_heap_size(u3_road* r) {
|
||||||
|
if (r == &(u3H->rod_u)) {
|
||||||
|
return u3a_heap(r)*4;
|
||||||
|
} else {
|
||||||
|
// recurse
|
||||||
|
return (u3a_heap(r)*4) + _all_heap_size(u3tn(u3_road, r->par_p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct
|
||||||
|
_report_bar {
|
||||||
|
char s[105];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
bar_item {
|
||||||
|
unsigned int index;
|
||||||
|
unsigned int lower;
|
||||||
|
float og;
|
||||||
|
float dif;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
bar_items {
|
||||||
|
struct bar_item s[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
float
|
||||||
|
_boost_small(float x)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
// we want zero to be zero,
|
||||||
|
// and anything between zero and one to be one
|
||||||
|
// all else goes as normal
|
||||||
|
0.0 >= x ? 0.0:
|
||||||
|
1.0 > x ? 1.0:
|
||||||
|
x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_global_difference(struct bar_items item)
|
||||||
|
{
|
||||||
|
unsigned int lower_sum = 0;
|
||||||
|
for (unsigned int i=0; i < 6; i++) lower_sum += item.s[i].lower;
|
||||||
|
return 100 - lower_sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bar_items
|
||||||
|
_get_roundoff_error(struct bar_items item)
|
||||||
|
{
|
||||||
|
for (unsigned int i=0; i < 6; i++) {
|
||||||
|
item.s[i].dif = item.s[i].og - item.s[i].lower;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bar_items
|
||||||
|
_sort_by_roundoff_error(struct bar_items item)
|
||||||
|
{
|
||||||
|
struct bar_item temp;
|
||||||
|
for (unsigned int i=1; i < 6; i++) {
|
||||||
|
for (unsigned int j=0; j < 6-i; j++) {
|
||||||
|
if (item.s[j+1].dif > item.s[j].dif) {
|
||||||
|
temp = item.s[j];
|
||||||
|
item.s[j] = item.s[j+1];
|
||||||
|
item.s[j+1] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bar_items
|
||||||
|
_sort_by_index(struct bar_items item)
|
||||||
|
{
|
||||||
|
struct bar_item temp;
|
||||||
|
for (unsigned int i=1; i < 6; i++) {
|
||||||
|
for (unsigned int j=0; j < 6-i; j++) {
|
||||||
|
if (item.s[j+1].index < item.s[j].index) {
|
||||||
|
temp = item.s[j];
|
||||||
|
item.s[j] = item.s[j+1];
|
||||||
|
item.s[j+1] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_print_bar_items(struct bar_items item)
|
||||||
|
{
|
||||||
|
const char symbol[6] = "=-%#+~";
|
||||||
|
for (int i=0; i < 6; i++) printf(
|
||||||
|
"item:%c,%2u, %6.2f,%6.2f, %2u\n",
|
||||||
|
symbol[i],
|
||||||
|
item.s[i].index,
|
||||||
|
item.s[i].og,
|
||||||
|
item.s[i].dif,
|
||||||
|
item.s[i].lower
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bar_items
|
||||||
|
_reduce_error(struct bar_items item, int difference)
|
||||||
|
{
|
||||||
|
for (unsigned int i=0; i < 6; i++) {
|
||||||
|
if (item.s[i].lower == 0) continue;
|
||||||
|
if (item.s[i].lower == 1) continue;
|
||||||
|
if (difference > 0) {
|
||||||
|
item.s[i].lower++;
|
||||||
|
difference--;
|
||||||
|
}
|
||||||
|
if (difference < 0) {
|
||||||
|
item.s[i].lower--;
|
||||||
|
difference++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct _report_bar
|
||||||
|
_report_bargraph(float ih, float sh, float fh, float op, float sk, float ik)
|
||||||
|
{
|
||||||
|
float in[6];
|
||||||
|
in[0] = _boost_small(ih);
|
||||||
|
in[1] = _boost_small(sh);
|
||||||
|
in[2] = _boost_small(fh);
|
||||||
|
in[3] = _boost_small(op);
|
||||||
|
in[4] = _boost_small(sk);
|
||||||
|
in[5] = _boost_small(ik);
|
||||||
|
|
||||||
|
const char symbol[6] = "=-%#+~";
|
||||||
|
|
||||||
|
// init the list of structs
|
||||||
|
struct bar_items item;
|
||||||
|
for (unsigned int i=0; i < 6; i++) {
|
||||||
|
item.s[i].index = i;
|
||||||
|
item.s[i].og = in[i];
|
||||||
|
item.s[i].lower = (int) item.s[i].og;
|
||||||
|
}
|
||||||
|
|
||||||
|
int difference = 0;
|
||||||
|
for (int x=0; x<100; x++) {
|
||||||
|
item = _get_roundoff_error(item);
|
||||||
|
difference = _global_difference(item);
|
||||||
|
if (difference == 0) break;
|
||||||
|
item = _sort_by_roundoff_error(item);
|
||||||
|
item = _reduce_error(item, difference);
|
||||||
|
}
|
||||||
|
item = _sort_by_index(item);
|
||||||
|
|
||||||
|
struct _report_bar bar = {
|
||||||
|
.s = "[ ]"
|
||||||
|
};
|
||||||
|
|
||||||
|
// create our bar chart
|
||||||
|
int x = 0, y = 0;
|
||||||
|
for (int i=0; i < 6; i++) {
|
||||||
|
x++;
|
||||||
|
for (int j=0; j < item.s[i].lower; j++) {
|
||||||
|
bar.s[x+j] = symbol[i];
|
||||||
|
y = x+j;
|
||||||
|
}
|
||||||
|
if (y > 0) x = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* u3t_meme(): report memory stats at call time */
|
||||||
|
void
|
||||||
|
u3t_slog_meme(c3_l pri_l)
|
||||||
|
{
|
||||||
|
c3_w low = 0,
|
||||||
|
top = u3a_bytes,
|
||||||
|
full = u3a_full(u3R)*4,
|
||||||
|
fred = u3a_idle(u3R)*4,
|
||||||
|
temp = u3a_temp(u3R)*4,
|
||||||
|
heap = u3a_heap(u3R)*4,
|
||||||
|
open = u3a_open(u3R)*4;
|
||||||
|
c3_w imut = top-full;
|
||||||
|
c3_w solid = heap-fred;
|
||||||
|
|
||||||
|
float imut_p = _meme_percent(imut, top),
|
||||||
|
heap_p = _meme_percent(solid, top),
|
||||||
|
free_p = _meme_percent(fred, top),
|
||||||
|
open_p = _meme_percent(open, top),
|
||||||
|
stak_p = _meme_percent(temp, top);
|
||||||
|
float full_p = heap_p + free_p + open_p + stak_p;
|
||||||
|
|
||||||
|
// TODO: replace all calls of free() with calls of u3a_free() or its alias.
|
||||||
|
|
||||||
|
c3_w imut_heap = _all_heap_size(u3R) - heap;
|
||||||
|
c3_w imut_stak = imut - imut_heap;
|
||||||
|
float imut_heap_p = _meme_percent(imut_heap, top),
|
||||||
|
imut_stak_p = _meme_percent(imut_stak, top);
|
||||||
|
|
||||||
|
u3t_slog_cap(pri_l, u3i_string("Legend | Report"), u3i_string(" "));
|
||||||
|
u3t_slog_memory(pri_l, " loom", 100.0, top);
|
||||||
|
u3t_slog_memory(pri_l, " road", full_p, full);
|
||||||
|
_slog_blank(pri_l);
|
||||||
|
u3t_slog_memory(pri_l, " = immutable heap", imut_heap_p, imut_heap);
|
||||||
|
u3t_slog_memory(pri_l, " - solid heap", heap_p, solid);
|
||||||
|
u3t_slog_memory(pri_l," \% freed heap", free_p, fred);
|
||||||
|
u3t_slog_memory(pri_l, " # open space", open_p, open);
|
||||||
|
u3t_slog_memory(pri_l, " + stack", stak_p, temp);
|
||||||
|
u3t_slog_memory(pri_l, " ~ immutable stack", imut_stak_p, imut_stak);
|
||||||
|
_slog_blank(pri_l);
|
||||||
|
u3t_slog_memory(pri_l, " $ allocation frame", imut_heap_p, imut_heap);
|
||||||
|
#ifdef U3_CPU_DEBUG
|
||||||
|
/* iff we are using CPU_DEBUG env var
|
||||||
|
** we can report more facts:
|
||||||
|
** max_w: max allocated on the current road (not global, not including child roads)
|
||||||
|
** cel_d: max cells allocated in current road (inc closed kids, but not parents)
|
||||||
|
** nox_d: nock steps performed in current road, less caching
|
||||||
|
*/
|
||||||
|
c3_w max = (u3R->all.max_w*4)+imut;
|
||||||
|
float max_p = _meme_percent(max, top);
|
||||||
|
c3_d cells = u3R->pro.cel_d;
|
||||||
|
c3_d nox = u3R->pro.nox_d;
|
||||||
|
u3t_slog_memory(pri_l, " | road max memory", max_p, max);
|
||||||
|
_slog_blank(pri_l);
|
||||||
|
u3t_slog_steps(pri_l, " road cells made", cells);
|
||||||
|
u3t_slog_steps(pri_l, " road nocks made", nox);
|
||||||
|
#endif
|
||||||
|
if ( u3a_is_north(u3R) == c3y ) {
|
||||||
|
u3t_slog_cap(pri_l, u3i_string(" road direction"), u3i_string(" North"));
|
||||||
|
} else {
|
||||||
|
u3t_slog_cap(pri_l, u3i_string(" road direction"), u3i_string(" South"));
|
||||||
|
}
|
||||||
|
_slog_road_depth(pri_l, u3R, 1);
|
||||||
|
_slog_blank(pri_l);
|
||||||
|
|
||||||
|
// warn if any sanity checks have failed
|
||||||
|
if (full_p != (100.0 - imut_p))
|
||||||
|
u3t_slog_cap(3, u3i_string("error"), u3i_string("road != (loom - immutable)"));
|
||||||
|
if (100.0 < (imut_heap_p + heap_p + free_p + open_p + stak_p + imut_stak_p))
|
||||||
|
u3t_slog_cap(3, u3i_string("error"), u3i_string("loom sums over 100%"));
|
||||||
|
|
||||||
|
struct _report_bar bar = _report_bargraph(
|
||||||
|
imut_heap_p,
|
||||||
|
heap_p,
|
||||||
|
free_p,
|
||||||
|
open_p,
|
||||||
|
stak_p,
|
||||||
|
imut_stak_p
|
||||||
|
);
|
||||||
|
int dol = (int) _roundf(imut_heap_p/100);
|
||||||
|
bar.s[dol] = '$';
|
||||||
|
#ifdef U3_CPU_DEBUG
|
||||||
|
// iff we have a max_p we will render it into the bar graph
|
||||||
|
// in other words iff we have max_p it will always replace something
|
||||||
|
c3_w inc_max = (max_p > imut_heap_p+1.0) ? (c3_w) max_p+0.5 : (c3_w) imut_heap_p+1.5;
|
||||||
|
if (max_p > 0.0) bar.s[inc_max] = '|';
|
||||||
|
#endif
|
||||||
|
// TODO: not sure we really need _slog_free_discrepancy()
|
||||||
|
//_slog_free_discrepancy();
|
||||||
|
u3t_slog_cap(pri_l, u3i_string("Loom"), u3i_string(bar.s));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_size_prefix(unsigned int wor_w)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(wor_w / 1000000000) ? 'G':
|
||||||
|
(wor_w % 1000000000) / 1000000 ? 'M':
|
||||||
|
(wor_w % 1000000) / 1000 ? 'K':
|
||||||
|
(wor_w % 1000) ? ' ':
|
||||||
|
'X';
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a struct to allow passing around a fixed size string
|
||||||
|
struct _report {
|
||||||
|
char s[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _report
|
||||||
|
report_string(unsigned int wor_w)
|
||||||
|
{
|
||||||
|
struct _report r = {
|
||||||
|
.s = " "
|
||||||
|
};
|
||||||
|
// add the G/M/K prefix
|
||||||
|
r.s[24] = _size_prefix(wor_w);
|
||||||
|
// consume wor_w into a string one base-10 digit at a time
|
||||||
|
// including dot formatting
|
||||||
|
unsigned int i = 0, j = 0;
|
||||||
|
while (wor_w > 0) {
|
||||||
|
if (j == 3) {
|
||||||
|
r.s[22-i] = '.';
|
||||||
|
i++;
|
||||||
|
j = 0;
|
||||||
|
} else {
|
||||||
|
r.s[22-i] = (wor_w%10)+'0';
|
||||||
|
wor_w /= 10;
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// return our fixed size string within a struct
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
u3t_slog_memory(c3_l pri_l, c3_c* cap_c, float percent, c3_w wor_w)
|
||||||
|
{
|
||||||
|
// create the report string and apply it to our char array s
|
||||||
|
struct _report r = report_string(wor_w);
|
||||||
|
// add the Bytes postfix to the size report
|
||||||
|
r.s[25] = 'B';
|
||||||
|
|
||||||
|
// add the space-percentage into the report
|
||||||
|
r.s[2] = '0', r.s[3] = '.', r.s[4] = '0', r.s[5] = '0';
|
||||||
|
int per_int = (int) (percent*100);
|
||||||
|
unsigned int i = 0;
|
||||||
|
while (per_int > 0 && i < 6) {
|
||||||
|
if (i == 2) {
|
||||||
|
r.s[5-i] = '.';
|
||||||
|
} else {
|
||||||
|
r.s[5-i] = (per_int%10)+'0';
|
||||||
|
per_int /= 10;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
// add the percent sign
|
||||||
|
r.s[6] = '%';
|
||||||
|
// slog it and go home
|
||||||
|
u3t_slog_cap(pri_l, u3i_string(cap_c), u3i_string(r.s));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
u3t_slog_steps(c3_l pri_l, c3_c* cap_c, c3_d sep_d)
|
||||||
|
{
|
||||||
|
struct _report r = report_string(sep_d);
|
||||||
|
u3t_slog_cap(pri_l, u3i_string(cap_c), u3i_string(r.s));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* u3t_render_bytecode(): collect the bytecode data
|
||||||
|
** for the expression wrapped in the calling hint
|
||||||
|
** and
|
||||||
|
*
|
||||||
|
u3_noun
|
||||||
|
u3t_render_bytecode(c3_y* pog, c3_w her_w)
|
||||||
|
{
|
||||||
|
//NOTE: this is basically the slog_byecode() function in nock.c
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user