1. show subscripts in dump - help and ideas requested - SOLVED

I am re-visiting the general purpose value dump in ex.err. What I would really like to see is something like:

symtab[1..15] = {1,0,3,4,0,0,0,8,0,0,0,12,0,0,15} 
symtab[16][1] = "C:\\Program Files (x86)\\Phix\\builtins\\" 
symtab[16][2] = "C:\\Program Files (x86)\\Phix\\" 
symtab[16][3] = "C:\\Program Files (x86)\\Phix\\demo\\misc\\eubins-mingw32\\" 
symtab[17][1..2] = {{3, "someotherfile.exw"}, {3, "somefile.e"}} 
symtab[17][3..5] = {{1, "prtnid2.e"}, {1, "psprint.e"}, {1, "pprntf.e"}} 
symtab[18..20] = {26,2,{-1073741819,0,32463637,32017528,253,32049420,0,0}} 
symtab[21][1..11] = {-1,8,1,2304,0,253, "P", 0,0,0,32452560} 
symtab[21][12][1..11] = {0,-77,28,35'#',38'&',-1,41')',46'.',-1,49'1',52'4'} 
symtab[21][12][12..22] = {55'7',-1,58':',-1,124'|',155,163,210,256,259,280} 
symtab[21][12][23..35] = {291,307,345,352,396,434,-1,436,478,483,-2,501,550} 
symtab[21][12][36..48] = {-1,561,-3,577,625,662,700,712,727,738,-1,744,782} 
symtab[21][12][49..61] = {790,808,852,890,905,950,-2,957,962,970,972,983,-2} 
symtab[21][12][62..65] = {991,1033,1038,1048} 
symtab[21][13..14] = {1,0} 
symtab[22] = 0 
simple = 1 
text = "text" 
shortsq = {-1,0-,1} 
I had a couple of goes but it is clearly a difficult thing to wrap my head around, and right now what I'm really doing is writing a statement of desired results to go and sleep on. Obviously I don't really care about details such as '#', the big problem is that what happens earlier on is dependent on what we find later. I think the above covers most of what I want, apart perhaps from splitting uber-long strings, which might get messy mid-long-sub-sequence.

Should you fancy a go, your not necessarily accurate starter for 10, for which you provide a clever_dump() routine, is:

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}) 

Oh, someone recently mentioned a /std string type which will hopefully be fine for this.

Of course I would be perfectly happy to have a simple flag which creates the older index-free style ex.err, please let me know if you think that's worthwhile doing.

And, I have to ask, does anyone else think this is a good idea, if we can do it?

Pete

new topic     » topic index » view message » categorize

2. Re: show subscripts in dump - help and ideas requested

Hi Pete,

Would this do the job?

symtab =  
.  [1] 1 
.  [2] 0 
.  [3] 3 
.  [4] 4 
.  [5] 0 
.  [6] 0 
.  [7] 0 
.  [8] 8 
.  [9] 0 
.  [10] 0 
.  [11] 0 
.  [12] 12 
.  [13] 0 
.  [14] 0 
.  [15] 15 
.  [16] 
.  .  [1] "C:\Program Files (x86)\Phix\builtins\" 
.  .  [2] "C:\Program Files (x86)\Phix\" 
.  .  [3] "C:\Program Files (x86)\Phix\demo\misc\eubins-mingw32\" 
.  [17] 
.  .  [1] 
.  .  .  [1] 3 
.  .  .  [2] "someotherfile.exw" 
.  .  [2] 
.  .  .  [1] 3 
.  .  .  [2] "somefile.e" 
.  .  [3] 
.  .  .  [1] 1 
.  .  .  [2] "prtnid2.e" 
.  .  [4] 
.  .  .  [1] 1 
.  .  .  [2] "psprint.e" 
.  .  [5] 
.  .  .  [1] 1 
.  .  .  [2] "pprntf.e" 
.  [18] 26 
.  [19] 2 
.  [20] {-1073741819,0,32463637,32017528,253,32049420,0,0} 
.  [21] 
.  .  [1] -1 
.  .  [2] 8 
.  .  [3] 1 
.  .  [4] 2304 
.  .  [5] 0 
.  .  [6] 253 
.  .  [7] "P" 
.  .  [8] 0 
.  .  [9] 0 
.  .  [10] 0 
.  .  [11] 32452560 
.  .  [12] {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} 
.  .  [13] 1 
.  .  [14] 0 
.  [22] 0 

You can even add a user-defined translation routine for whole or parts of the sequence

symtab =  
.  [1] 1 
.  [2] 0 
.  [3] 3 
.  [4] 4 
.  [5] 0 
.  [6] 0 
.  [7] 0 
.  [8] 8 
.  [9] 0 
.  [10] 0 
.  [11] 0 
.  [12] 12 
.  [13] 0 
.  [14] 0 
.  [15] 15 
.  [FOLDERS] 
.  .  [1] "C:\Program Files (x86)\Phix\builtins\" 
.  .  [2] "C:\Program Files (x86)\Phix\" 
.  .  [3] "C:\Program Files (x86)\Phix\demo\misc\eubins-mingw32\" 
.  [FILE_TABLE] 
.  .  [1] 
.  .  .  [ID] 3 
.  .  .  [FILENAME] "someotherfile.exw" 
.  .  [2] 
.  .  .  [ID] 3 
.  .  .  [FILENAME] "somefile.e" 
.  .  [3] 
.  .  .  [ID] 1 
.  .  .  [FILENAME] "prtnid2.e" 
.  .  [4] 
.  .  .  [ID] 1 
.  .  .  [FILENAME] "psprint.e" 
.  .  [5] 
.  .  .  [ID] 1 
.  .  .  [FILENAME] "pprntf.e" 
.  [18] 26 
.  [19] 2 
.  [20] {-1073741819,0,32463637,32017528,253,32049420,0,0} 
.  [21] 
.  .  [1] -1 
.  .  [2] 8 
.  .  [3] 1 
.  .  [4] 2304 
.  .  [5] 0 
.  .  [6] 253 
.  .  [7] "P" 
.  .  [8] 0 
.  .  [9] 0 
.  .  [10] 0 
.  .  [11] 32452560 
.  .  [12] {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} 
.  .  [13] 1 
.  .  [14] 0 
.  [22] 0 

Here is the code

include std/text.e 
include std/io.e 
include std/search.e 
 
global integer f_debug 
 
------------------------------------------------------------------------------ 
 
global type string(object x) 
-- checks if a sequence is a string 
  atom is_string 
  if sequence(x) then 
    is_string = 1 
    for i = 1 to length(x) do 
      if sequence(x[i]) then 
        is_string = 0 
      else 
        if (x[i] < ' ') and (x[i] != 9) and (x[i] != 13) and (x[i] != 10) then is_string = 0 end if 
        if x[i]> 254 then is_string = 0 end if 
      end if 
    end for 
  else 
    is_string = 0 
  end if 
  return is_string 
end type 
 
------------------------------------------------------------------------------ 
 
global function showPrintable(object s) 
-- returns only printable characters of a sequence 
-- non printable characters are replace by a dot 
  sequence res 
 
  res = "" 
  for i = 1 to length(s) do 
    if integer(s[i]) then 
      if (s[i] > 31) and (s[i] < 255) then 
        res &= s[i] 
      elsif s[i] = 9 then 
        res &= "\\t" 
      elsif s[i] = 13 then 
        res &= "\\r" 
      elsif s[i] = 10 then 
        res &= "\\n" 
      else 
        res &= "." 
      end if 
    else 
      res &= "." 
    end if 
  end for 
  return res 
end function 
 
------------------------------------------------------------------------------ 
 
procedure analyzeSequence(object x, sequence Name, integer Output=1, integer translator=0, sequence path={}, integer level=0, sequence prefix="") 
-- prints a sequence structure in a human readable way 
  integer subSequence 
  sequence s, offset 
 
  if level=0 then printf(Output, "%s = ", {Name}) end if 
  offset = "" 
  for i = 1 to level do offset &= ".  " end for 
  s = "" 
  if integer(x) then 
    s = sprintf(" %d", {x}) 
    puts(Output, offset&prefix&s&"\n") 
  elsif atom(x) then 
    if (x >= 0) and (x = floor(x)) then 
      s = sprintf(" %.0f", {x}) 
    elsif (x < 0) and (x = floor(x+1)) then 
      s = sprintf(" %.0f", {x}) 
    else 
      s = sprintf(" %f", {x}) 
    end if 
    puts(Output, offset&prefix&s&"\n") 
  elsif string(x) then 
    if length(x) = 0 then 
      s = "\"\"" 
    else 
      s = sprintf(" \"%s\"", {showPrintable(x)}) 
    end if 
    puts(Output, offset&prefix&s&"\n") 
  else 
    subSequence = 0 
    for i=1 to length(x) do 
      if sequence(x[i]) then 
        subSequence = 1 
        exit 
      end if 
    end for 
    if subSequence = 0 then 
      s = sprintf(" %s", {sprint(x)}) 
      puts(Output, offset&prefix&s&"\n") 
    else 
      if length(s) = 0 then 
        puts(Output, offset&prefix&"\n") 
      end if 
      for i=1 to length(x) do 
        if translator > 0 then 
          prefix = sprintf("[%s]", { call_func(translator, {path, level, i}) }) 
        else 
          prefix = sprintf("[%d]", i) 
        end if 
        analyzeSequence(x[i], Name, Output, translator, path&sprintf("[%d]", i), level+1, prefix) 
      end for 
    end if 
  end if 
  if Output=f_debug then flush(f_debug) end if 
end procedure 

Here is the test program

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}  
 
function identifySymtabComponents(sequence path, integer level, integer n) 
-- printf(f_debug, "  path: '%s', level: %d, n: %d\n", {path, level, n}) 
  if level = 0 then 
    if    n = 16 then return "FOLDERS" 
    elsif n = 17 then return "FILE_TABLE" 
    end if 
  elsif (level = 2) and begins("[17]", path) then 
    if    n = 1 then return "ID" 
    elsif n = 2 then return "FILENAME" 
    end if 
  end if 
  return sprintf("%d",n) 
end function 
 
f_debug = open("ex.err", "w") 
 
puts(f_debug, "without translator routine\n") 
analyzeSequence(symtab, "symtab", f_debug, 0) 
puts(f_debug, "\nwith translator routine\n") 
analyzeSequence(symtab, "symtab", f_debug, routine_id("identifySymtabComponents")) 
 
close(f_debug) 

Best Regards

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

3. Re: show subscripts in dump - help and ideas requested

analyzeSequence may not be the best function name as it decodes any type of euphoria objects

analyzeSequence(123, "integer") 
analyzeSequence(3.1416, "pi") 
analyzeSequence("I love OpenEuphoria", "string") 
 
integer =  123 
pi =  3.141600 
string =  "I love OpenEuphoria" 
new topic     » goto parent     » topic index » view message » categorize

4. Re: show subscripts in dump - help and ideas requested

Sorry, I did not respect the specifications. I still don't because I use object first and object name second.

If you rename analyzeSequence in clever_dump, here is what you get as asked.

clever_dump(symtab, "symtab") 
clever_dump(1, "simple")  
clever_dump("text","text")  
clever_dump({-1,0,1},"shortsq")  
symtab =  
.  [1] 1 
.  [2] 0 
.  [3] 3 
.  [4] 4 
.  [5] 0 
.  [6] 0 
.  [7] 0 
.  [8] 8 
.  [9] 0 
.  [10] 0 
.  [11] 0 
.  [12] 12 
.  [13] 0 
.  [14] 0 
.  [15] 15 
.  [16] 
.  .  [1] "C:\Program Files (x86)\Phix\builtins\" 
.  .  [2] "C:\Program Files (x86)\Phix\" 
.  .  [3] "C:\Program Files (x86)\Phix\demo\misc\eubins-mingw32\" 
.  [17] 
.  .  [1] 
.  .  .  [1] 3 
.  .  .  [2] "someotherfile.exw" 
.  .  [2] 
.  .  .  [1] 3 
.  .  .  [2] "somefile.e" 
.  .  [3] 
.  .  .  [1] 1 
.  .  .  [2] "prtnid2.e" 
.  .  [4] 
.  .  .  [1] 1 
.  .  .  [2] "psprint.e" 
.  .  [5] 
.  .  .  [1] 1 
.  .  .  [2] "pprntf.e" 
.  [18] 26 
.  [19] 2 
.  [20] {-1073741819,0,32463637,32017528,253,32049420,0,0} 
.  [21] 
.  .  [1] -1 
.  .  [2] 8 
.  .  [3] 1 
.  .  [4] 2304 
.  .  [5] 0 
.  .  [6] 253 
.  .  [7] "P" 
.  .  [8] 0 
.  .  [9] 0 
.  .  [10] 0 
.  .  [11] 32452560 
.  .  [12] {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} 
.  .  [13] 1 
.  .  [14] 0 
.  [22] 0 
simple =  1 
text =  "text" 
shortsq =  {-1,0,1} 

You can still specify a debug_file and a user-defined translation as stated before.

clever_dump(symtab, "symtab", f_debug) 
clever_dump(symtab, "symtab", f_debug, routine_id("identifySymtabComponents")) 
new topic     » goto parent     » topic index » view message » categorize

5. Re: show subscripts in dump - help and ideas requested

jmduro said...

Hi Pete,

Would this do the job?

symtab =  
.  [1] 1 
.  [2] 0 
.  [3] 3 
.  [4] 4 
.  [5] 0 
.  [6] 0 

Erm, I really wanted something a little more compact. Not to worry, my plan, of writing it down, publicly voicing it to force some kind of deadline, then letting my unconscious subconscious mull it over, worked a treat. Woke up and could see partial bits of text and start and current indexes being passed back and forth, and before finishing my first cuppa the second penny had dropped: don't fret about when you print things, instead chuck anything generated as and when you like into a big table along with the right numbers for a plain sort before a final print. Not too pretty, could suffer some cleanup, but here it is:

-- note: only tested on Phix 
constant MAXLINELEN = 77 
 
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, string name, string text) 
--  if idii={11} then ?9/0 end if 
    printstack = append(printstack,{idii,name,text}) 
end procedure 
 
function cdi(string name, string prev, integer prst, integer prdx, object o, sequence idii) 
-- ps: not totally sure I've 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, namedx 
integer newprst, lo, lp, wasstacklen 
    wasstacklen = length(printstack) 
    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) 
            -- 
            -- (Ensures you can tell 5 and 5.00000000001 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 
            if length(prev) then 
                if prst=prdx-1 then 
                    namedx = sprintf("%s[%d]",{name,prst}) 
                else 
                    namedx = sprintf("%s[%d..%d]",{name,prst,prdx-1}) 
                    prev = "{"&prev&"}" 
                end if 
                idii[$] = prst 
                addtostack(idii,namedx,prev) 
                idii[$] = prdx 
            end if 
            lo = length(o) 
            if newprst<=lo then 
                if prdx=-1 then 
                    if newprst=lo then 
                        name = sprintf("%s[%d]",{name,lo}) 
                    else 
                        this = "{"&this&"}" 
                        name = sprintf("%s[%d..%d]",{name,newprst,lo}) 
                    end if 
                    addtostack(idii&newprst,name,this) 
                else 
                    if newprst=lo then 
                        name = sprintf("%s[%d][%d]",{name,prdx,lo}) 
                    else 
                        this = "{"&this&"}" 
                        name = sprintf("%s[%d][%d..%d]",{name,prdx,newprst,lo}) 
                    end if 
                    addtostack(idii&newprst,name,this) 
                end if 
            end if 
            return {prdx+1,""} 
        end if 
        this = "{"&this&"}" 
    end if 
    lp = length(prev) 
    if lp=0 then 
        if not string(o) 
        or length(this)+length(name)+4<MAXLINELEN then 
            return {prst,this} 
        end if 
    elsif lp+length(this)+length(name)+4<MAXLINELEN then 
        return {prst,prev&','&this} 
    else 
        if prdx=prst+1 then 
            namedx = sprintf("%s[%d]",{name,prst}) 
        else 
            namedx = sprintf("%s[%d..%d]",{name,prst,prdx-1}) 
            prev = "{"&prev&"}" 
        end if 
        idii[$] = prst 
        addtostack(idii,namedx,prev) 
    end if 
    if string(o) then 
        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]&'"' 
            idii[$] = newprst 
            namedx = sprintf("%s[%d..%d]",{name,newprst,lp}) 
            addtostack(idii,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 
        idii[$] = newprst 
        addtostack(idii,name,this) 
        return {prdx+1,""} 
    end if 
    return {prdx,this} 
end function 
 
procedure clever_dump(string name, object o) 
integer prst 
string s 
    printstack = {} 
    {prst,s} = cdi(name,"",1,-1,o,{}) 
    if length(s) then 
        addtostack({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 s = repeat(0,10) 
--  for i=1 to 9 do 
--      s[10] = s 
--  end for 
--  clever_dump("s",s) 
--  for i=1 to 9 do 
--      s[1] = s 
--  end for 
--  clever_dump("s",s) 
 
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) 

which generates the following output:

symtab[1..15] = {1,0,3,4,0,0,0,8,0,0,0,12,0,0,15} 
symtab[16][1] = "C:\Program Files (x86)\Phix\builtins\" 
symtab[16][2] = "C:\Program Files (x86)\Phix\" 
symtab[16][3] = "C:\Program Files (x86)\Phix\demo\misc\eubins-mingw32\" 
symtab[17][1..3] = {{3,"someotherfile.exw"},{3,"somefile.e"},{1,"prtnid2.e"}} 
symtab[17][4..5] = {{1,"psprint.e"},{1,"pprntf.e"}} 
symtab[18..20] = {26,2,{-1073741819,0,32463637,32017528,253'',32049420,0,0}} 
symtab[21][1..11] = {-1,8,1,2304,0,253'',"P",0,0,0,32452560} 
symtab[21][12][1..13] = {0,-77,28,35'#',38'&',-1,41')',46'.',-1,49'1',52'4',55'7',-1} 
symtab[21][12][14..24] = {58':',-1,124'|',155'',163'',210'',256,259,280,291,307} 
symtab[21][12][25..40] = {345,352,396,434,-1,436,478,483,-2,501,550,-1,561,-3,577,625} 
symtab[21][12][41..55] = {662,700,712,727,738,-1,744,782,790,808,852,890,905,950,-2} 
symtab[21][12][56..65] = {957,962,970,972,983,-2,991,1033,1038,1048} 
symtab[21][13..14] = {1,0} 
symtab[22] = 0 
simple = 1 
text = "text" 
shortsq = {-1,0,1} 
t[1..4] = {0,0,0,0} 
t[5][1..60] = "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt" 
t[5][61..120] = "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt" 
t[5][121..180] = "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt" 
t[5][181..200] = "tttttttttttttttttttt" 
t[6..10] = {0,0,0,0,0} 
longtext[1..56] = "tttttttttttttttttttttttttttttttttttttttttttttttttttttttt" 
longtext[57..112] = "tttttttttttttttttttttttttttttttttttttttttttttttttttttttt" 
longtext[113..168] = "tttttttttttttttttttttttttttttttttttttttttttttttttttttttt" 
longtext[169..200] = "tttttttttttttttttttttttttttttttt" 

Anyway, thanks for playing!

Pete

Edit: oops, missed out constant MAXLINELEN, corrected a bug on line 79

new topic     » goto parent     » topic index » view message » categorize

6. Re: show subscripts in dump - help and ideas requested - solved

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) 
new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu