# stack.tcl
oo::class create stack
oo::define stack {
variable Data
variable Debug_
method push {args} {
lappend Data {*}$args
}
method peek {{n 0} {retall {}}} {
expr {$retall ne {}
? [lrange $Data end-$n end]
: [lindex $Data end-$n] }
}
method pkrange {nA nZ {reverse {}}} {
set r [lrange $Data end-$nZ end-$nA]
expr {$reverse ni {"" 0 no false off} ?
[lreverse $r] : $r}
}
method pop {{n 0}} {
set r [my peek $n all]
set Data [lreplace $Data end-$n end]
return $r
}
method size {} {
llength $Data
}
method prune {keep} {
set Data [lreplace $Data 0 [- [llength $Data] $keep 1]]
}
method set_debug { on_off } {
set Debug_ [expr {$on_off ni {"" off 0 false no}}]
puts "[self]: debug-print=[expr {$Debug_ ? {'on'} : {'off'}}]"
return {}
}
constructor {} {
set Data {}
set Debug_ {}
}
destructor {
if {$Debug_ ne {}} {
puts "[self] destroyed"
}
}
}
oo::class create prefix {
superclass stack
method len {} {
my variable Data
return [string length [join $Data ""]]
}
method prn {} {
my variable Data
my variable Debug_
set output [join $Data ""]
# if {$Debug_} { puts $output}
}
method clear {} {
my variable Data
set Data {}
}
}
oo::class create table
oo::define table {
variable Rows
variable Rowcol
variable Ncol
variable Nrow
variable Cols
variable Title
constructor {} {
set Rows [dict create]
set Nrow 0
set Ncol 0
set Width 0
set Cols 0
set Title ""
}
method title {title} {
my variable Title
set Title $title
}
method Addcol {row col item} {
set itmlen [string length $item]
dict set Rows $Nrow $Ncol [list _itm $item _len $itmlen _max 0]
if {$Nrow > 0} {my ColMax $Ncol $itmlen}
incr Ncol
}
method ColMax {col {max -1}} {
set currmax [dict get $Rows 0 $col _max]
expr {$max >= 0
? [dict set Rows 0 $col _max [max $max $currmax]]
: $currmax}
}
method addTD {td} {
my Addcol $Nrow $Ncol $td
}
method endRow {} {
incr Nrow
set Cols $Ncol
set Ncol 0
}
method PrintCell {row col} {
set td [dict get $Rows $row $col _itm]
set tdlen [dict get $Rows $row $col _len]
set max [dict get $Rows 0 $col _max]
return " $td[string repeat { } [- $max $tdlen]] |"
}
method printRow {row} {
set out |
foreach col [iota $Cols] {
append out [my PrintCell $row $col]
}
return $out
}
method printRows {prfx {lnchar -}} {
lappend out $prfx[my printRow 0 ]
lappend out $prfx[my printHdrLine $lnchar]
foreach row [iota $Nrow 1] {
lappend out $prfx[my printRow $row]
}
join $out \n
}
method printHdrLine {{char -}} {
set out |
foreach col [iota $Cols] {
append out [string repeat $char [+ 2 [dict get $Rows 0 $col _max]]] |
}
return $out
}
}
proc iota {n {min 0} {ls {}}} {
if {$n == $min} {
return $ls
}
tailcall iota [incr n -1] $min [linsert $ls 0 $n]
}