posting from Mark Harrison, a beautifully simple code generator: (RS)BTW, it's easy to set up a framework for classes and abstract data types (just look at how many class systems there are for Tcl). Here' some skeleton code. If they are still going on about "design patterns" then I want credit for the "recursively eval body" pattern. :-) proc class {namespace name body} {
set methods [list]
puts "namespace eval $namespace \{"
# Easier to build the code and substitute in the name afterwards
set dispatcher { proc %N {{name ""} args} {
variable _methodmap
if {[info exist _methodmap($name)]} {
return [uplevel 1 $_methodmap($name) $args]
} elseif {[string length $name]} {
variable _methods
return -code error "bad option \"$name\": must be $_methods"
} else {
return -code error \
"wrong # args: should be \"%N option ?arg arg ...?\""
}
}}
regsub -all %N $dispatcher [list $name] dispatcher
puts $dispatcher
puts {}
eval $body
puts {}
set ml [linsert [join $methods ", "] end-1 "or"]
puts " [list variable _methods $ml]"
puts { variable _methodmap}
set methodmap [list]
foreach method $methods {
lappend methodmap $method [list ${namespace}::_$method]
}
puts " array set _methodmap [list $methodmap]"
puts "\}"
}
proc variable {name} {
puts " variable $name ;# array indexed by name"
}
proc method {name arg body} {
upvar 1 methods methods
puts " proc _$name {$arg} \{"
puts " $body"
puts " \}"
lappend methods $name
}
# here's a test
class struct stack {
variable stacks
method clear {} {}
method peek {{count 1}} {}
method pop {{count 1}} {}
method push {arg1 args} {}
method rotate {count steps} {}
method size {} {}
}Mark Harrison [email protected] AsiaInfo Computer Networks http://www.markharrison.netBeijing / Santa Clara http://usai.asiainfo.com:8080
DKF: Added a dispatcher including code to automagically generate the dispatcher's error messages. The dispatcher is nowhere near robust enough about errors yet (rewriting the error trace is interesting to get right...)

