Re: show subscripts in dump - help and ideas requested - solved
- Posted by petelomax May 14, 2015
- 1729 views
Minor cleanup, same output:
constant MAXLINELEN = 77 -- -- Of course the first notion is to print things as and when lines get full, however -- consider s = repeat(0,20); s[10] = repeat(0,20): if, as I do, you want to see: -- s[1..9] = {0,0,0,0,0,0,0,0,0} -- s[10] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -- s[11..20] = {0,0,0,0,0,0,0,0,0,0,0} -- (assuming that 20 was enough to break past MAXLINELEN and force the linebreaks) -- then while printing (or splitting) s[10] you've got 9 elements in hand, somewhere -- higher up the call stack, that you haven't had reason to print yet, and of course -- with longer and more deeply nested structures things can get far worse. Instead, -- just append things to a "printstack" along with a key to sort everything into the -- right order before printing. The routines below chuck around a fair few partial -- results, start and current indexes, and return the same in subtly different ways -- depending on what just happened, that I would struggle to explain any better than -- the source code itself does. -- sequence printstack -- each element contains 3 items: -- indicii - for sorting, eg {21,1} -- name - eg "symtab[21][1..11]" (matches that {21,1}) -- text - the formatted value procedure addtostack(sequence idii, integer idxr, string name, string text) idii[$] = idxr -- if idii={11} then ?9/0 end if printstack = append(printstack,{idii,name,text}) end procedure function subscr(string prev, string name, integer prst, integer prdx) -- Helper routine for setting subscripts, typically for things -- that are just about to be chucked onto the printstack. -- Note this is not meant to be called for any [1..$] cases. if prst=prdx then name = sprintf("%s[%d]",{name,prst}) else name = sprintf("%s[%d..%d]",{name,prst,prdx}) prev = "{"&prev&"}" end if return {prev,name} end function function cdi(string name, string prev, integer prst, integer prdx, object o, sequence idii) -- -- Clever display of i'th item. Recursive. -- name is eg "symtab", but may get "symtab[1]", "symtab[1][1]", etc. -- prev is previously collected stuff to output: concatenate to it, or split the line. -- prst is a staring index where (a non-empty) prev began. -- prdx is the element index of name that we just got passed in o. -- idii is a list of (start) indexes, to be used in the final sort. -- -- Returns extended or purged {prst,prev} -- -- ps: not totally sure I got return "1,2,3" vs return "{1,2,3}" precisely right, -- but, touch wood, it seems fine in all the cases I have tested so far... -- string this -- Scratch var: string representation of o or next element of o. -- In the key recursive call below, "this" gets passed to "prev", -- and grows/shrinks from what that returns rather than directly. string namedx -- Scratch var: name with some or other idx tacked on the end. integer newprst, -- Scratch/innner version of prst. lo, -- length(o) shorthand lp, -- length(prev) shorthand lt, -- length(name)+4+lp+length(this) shorthand wasstacklen = length(printstack) -- to check if something got dumped if atom(o) then this = sprintf("%.10g", o) if integer(o) then if o>=#20 and o<=#FF then this &= sprintf("'%s'",o) end if elsif not find('.',this) and not find('e',this) -- eg 1e308 and not find('n',this) then -- (inf/nan) -- -- Ensure you can tell 5 and 5.000000000001 apart. -- Note that while you can infer from the presence -- of ".0" it is "not integer", in no way does the -- /absence/ mean anything at all about whether a -- variable was declared integer/atom/object/udt. -- this &= ".0" end if elsif string(o) then this = '"'&o&'"' else if length(idii) then namedx = sprintf("%s[%d]",{name,prdx}) else namedx = name end if this = "" newprst = 1 for i=1 to length(o) do {newprst,this} = cdi(namedx,this,newprst,i,o[i],idii&i) end for if newprst>1 or (length(idii) and wasstacklen<length(printstack)) then -- -- Something just got printed, so empty prev and -- force linebreaks all the way back up the call -- stack (which is done by returning prdx+1) -- if length(prev) then {prev,namedx} = subscr(prev,name,prst,prdx-1) addtostack(idii,prst,namedx,prev) end if lo = length(o) if newprst<=lo then if prdx!=-1 then name = sprintf("%s[%d]",{name,prdx}) end if {this,name} = subscr(this,name,newprst,lo) addtostack(idii&newprst,newprst,name,this) end if return {prdx+1,""} end if this = "{"&this&"}" end if lp = length(prev) lt = length(name)+4+lp+length(this) -- (+4 is for " = " and a ',') if lp=0 then if not string(o) -- (any splitting already done) or lt<MAXLINELEN then -- (or no need to split string) return {prst,this} end if elsif lt<MAXLINELEN then -- note that we are clearly returning a partial result here, -- of say "1,2,3" rather than "{1,2,3}". return {prst,prev&','&this} else {prev,namedx} = subscr(prev,name,prst,prdx-1) addtostack(idii,prst,namedx,prev) end if if string(o) then -- -- One that wouldn't fit, so split if needed and -- force linebreaks all the way back up the call -- stack (which is done by returning prdx+1) -- if prdx!=-1 then name = sprintf("%s[%d]",{name,prdx}) end if newprst = 1 idii &= 1 lo = length(o) while lo-newprst+length(name)+13>MAXLINELEN do lp = newprst+MAXLINELEN-14-length(name) this = '"'&o[newprst..lp]&'"' namedx = sprintf("%s[%d..%d]",{name,newprst,lp}) addtostack(idii,newprst,namedx,this) newprst = lp+1 end while if newprst!=1 then name = sprintf("%s[%d..%d]",{name,newprst,lo}) this = '"'&o[newprst..lo]&'"' end if addtostack(idii,newprst,name,this) return {prdx+1,""} end if return {prdx,this} end function procedure clever_dump(string name, object o) -- -- Display "name = sprint(o)" but with indexes -- as needed, together with smart line splitting. -- integer prst string s printstack = {} {prst,s} = cdi(name,"",1,-1,o,{}) if length(s) then addtostack({prst},prst,name,s) end if printstack = sort(printstack) for i=1 to length(printstack) do printf(1,"%s = %s\n",printstack[i][2..3]) end for end procedure constant symtab = {1,0,3,4,0,0,0,8,0,0,0,12,0,0,15, {"C:\\Program Files (x86)\\Phix\\builtins\\", "C:\\Program Files (x86)\\Phix\\", "C:\\Program Files (x86)\\Phix\\demo\\misc\\eubins-mingw32\\"}, {{3, "someotherfile.exw"}, {3, "somefile.e"}, {1, "prtnid2.e"}, {1, "psprint.e"}, {1, "pprntf.e"}}, 26,2, {-1073741819,0,32463637,32017528,253,32049420,0,0}, {-1,8,1,2304,0,253, "P", 0,0,0,32452560, {0,-77,28,35,38,-1,41,46,-1,49,52, 55,-1,58,-1,124,155,163,210,256,259,280, 291,307,345,352,396,434,-1,436,478,483,-2,501,550, -1,561,-3,577,625,662,700,712,727,738,-1,744,782, 790,808,852,890,905,950,-2,957,962,970,972,983,-2, 991,1033,1038,1048}, 1,0}, 0} clever_dump("symtab",symtab) clever_dump("simple",1) clever_dump("text","text") clever_dump("shortsq",{-1,0,1}) sequence t = repeat(0,10) t[5] = repeat('t',200) clever_dump("t",t) t = repeat('t',200) clever_dump("longtext",t) if getc(0) then end if abort(0)