snit2.tcl
来自「Linux下的MSN聊天程序源码」· TCL 代码 · 共 2,009 行 · 第 1/5 页
TCL
2,009 行
#-----------------------------------------------------------------------# TITLE:# snit.tcl## AUTHOR:# Will Duquette## DESCRIPTION:# Snit's Not Incr Tcl, a simple object system in Pure Tcl.## Copyright (C) 2003-2005 by William H. Duquette# This code is licensed as described in license.txt.##-----------------------------------------------------------------------package provide snit 2.0#-----------------------------------------------------------------------# Namespacenamespace eval ::snit:: { namespace export \ compile type widget widgetadaptor typemethod method macro}#-----------------------------------------------------------------------# Some Snit variablesnamespace eval ::snit:: { variable reservedArgs {type selfns win self} # Widget classes which can be hulls (must have -class) variable hulltypes { toplevel tk::toplevel frame tk::frame ttk::frame labelframe tk::labelframe ttk::labelframe }}#-----------------------------------------------------------------------# Snit Type Implementation templatenamespace eval ::snit:: { # Template type definition: All internal and user-visible Snit # implementation code. # # The following placeholders will automatically be replaced with # the client's code, in two passes: # # First pass: # %COMPILEDDEFS% The compiled type definition. # # Second pass: # %TYPE% The fully qualified type name. # %IVARDECS% Instance variable declarations # %TVARDECS% Type variable declarations # %TCONSTBODY% Type constructor body # %INSTANCEVARS% The compiled instance variable initialization code. # %TYPEVARS% The compiled type variable initialization code. # This is the overall type template. variable typeTemplate # This is the normal type proc variable nominalTypeProc # This is the "-hastypemethods no" type proc variable simpleTypeProc}set ::snit::typeTemplate { #------------------------------------------------------------------- # The type's namespace definition and the user's type variables namespace eval %TYPE% {%TYPEVARS% } #---------------------------------------------------------------- # Commands for use in methods, typemethods, etc. # # These are implemented as aliases into the Snit runtime library. interp alias {} %TYPE%::installhull {} ::snit::RT.installhull %TYPE% interp alias {} %TYPE%::install {} ::snit::RT.install %TYPE% interp alias {} %TYPE%::typevariable {} ::variable interp alias {} %TYPE%::variable {} ::snit::RT.variable interp alias {} %TYPE%::mytypevar {} ::snit::RT.mytypevar %TYPE% interp alias {} %TYPE%::typevarname {} ::snit::RT.mytypevar %TYPE% interp alias {} %TYPE%::myvar {} ::snit::RT.myvar interp alias {} %TYPE%::varname {} ::snit::RT.myvar interp alias {} %TYPE%::codename {} ::snit::RT.codename %TYPE% interp alias {} %TYPE%::myproc {} ::snit::RT.myproc %TYPE% interp alias {} %TYPE%::mymethod {} ::snit::RT.mymethod interp alias {} %TYPE%::mytypemethod {} ::snit::RT.mytypemethod %TYPE% interp alias {} %TYPE%::from {} ::snit::RT.from %TYPE% #------------------------------------------------------------------- # Snit's internal variables namespace eval %TYPE% { # Array: General Snit Info # # ns: The type's namespace # hasinstances: T or F, from pragma -hasinstances. # simpledispatch: T or F, from pragma -hasinstances. # canreplace: T or F, from pragma -canreplace. # counter: Count of instances created so far. # widgetclass: Set by widgetclass statement. # hulltype: Hull type (frame or toplevel) for widgets only. # exceptmethods: Methods explicitly not delegated to * # excepttypemethods: Methods explicitly not delegated to * # tvardecs: Type variable declarations--for dynamic methods # ivardecs: Instance variable declarations--for dyn. methods typevariable Snit_info set Snit_info(ns) %TYPE%:: set Snit_info(hasinstances) 1 set Snit_info(simpledispatch) 0 set Snit_info(canreplace) 0 set Snit_info(counter) 0 set Snit_info(widgetclass) {} set Snit_info(hulltype) frame set Snit_info(exceptmethods) {} set Snit_info(excepttypemethods) {} set Snit_info(tvardecs) {%TVARDECS%} set Snit_info(ivardecs) {%IVARDECS%} # Array: Public methods of this type. # The index is the method name, or "*". # The value is [list $pattern $componentName], where # $componentName is "" for normal methods. typevariable Snit_typemethodInfo array unset Snit_typemethodInfo # Array: Public methods of instances of this type. # The index is the method name, or "*". # The value is [list $pattern $componentName], where # $componentName is "" for normal methods. typevariable Snit_methodInfo array unset Snit_methodInfo # Array: option information. See dictionary.txt. typevariable Snit_optionInfo array unset Snit_optionInfo set Snit_optionInfo(local) {} set Snit_optionInfo(delegated) {} set Snit_optionInfo(starcomp) {} set Snit_optionInfo(except) {} } #---------------------------------------------------------------- # Compiled Procs # # These commands are created or replaced during compilation: # Snit_instanceVars selfns # # Initializes the instance variables, if any. Called during # instance creation. proc %TYPE%::Snit_instanceVars {selfns} { %INSTANCEVARS% } # Type Constructor proc %TYPE%::Snit_typeconstructor {type} { %TVARDECS% %TCONSTBODY% } #---------------------------------------------------------------- # Default Procs # # These commands might be replaced during compilation: # Snit_destructor type selfns win self # # Default destructor for the type. By default, it does # nothing. It's replaced by any user destructor. # For types, it's called by method destroy; for widgettypes, # it's called by a destroy event handler. proc %TYPE%::Snit_destructor {type selfns win self} { } #---------------------------------------------------------- # Compiled Definitions %COMPILEDDEFS% #---------------------------------------------------------- # Finally, call the Type Constructor %TYPE%::Snit_typeconstructor %TYPE%}#-----------------------------------------------------------------------# Type procs## These procs expect the fully-qualified type name to be # substituted in for %TYPE%.# This is the nominal type proc. It supports typemethods and# delegated typemethods.set ::snit::nominalTypeProc { # WHD: Code for creating the type ensemble namespace eval %TYPE% { namespace ensemble create \ -unknown [list ::snit::RT.UnknownTypemethod %TYPE% ""] \ -prefixes 0 }}# This is the simplified type proc for when there are no typemethods# except create. In this case, it doesn't take a method argument;# the method is always "create".set ::snit::simpleTypeProc { # Type dispatcher function. Note: This function lives # in the parent of the %TYPE% namespace! All accesses to # %TYPE% variables and methods must be qualified! proc %TYPE% {args} { ::variable %TYPE%::Snit_info # FIRST, if the are no args, the single arg is %AUTO% if {[llength $args] == 0} { if {$Snit_info(isWidget)} { error "wrong \# args: should be \"%TYPE% name args\"" } lappend args %AUTO% } # NEXT, we're going to call the create method. # Pass along the return code unchanged. if {$Snit_info(isWidget)} { set command [list ::snit::RT.widget.typemethod.create %TYPE%] } else { set command [list ::snit::RT.type.typemethod.create %TYPE%] } set retval [catch {uplevel 1 $command $args} result] if {$retval} { if {$retval == 1} { global errorInfo global errorCode return -code error -errorinfo $errorInfo \ -errorcode $errorCode $result } else { return -code $retval $result } } return $result }}#=======================================================================# Snit Type Definition## These are the procs used to define Snit types, widgets, and # widgetadaptors.#-----------------------------------------------------------------------# Snit Compilation Variables## The following variables are used while Snit is compiling a type,# and are disposed afterwards.namespace eval ::snit:: { # The compiler variable contains the name of the slave interpreter # used to compile type definitions. variable compiler "" # The compile array accumulates information about the type or # widgettype being compiled. It is cleared before and after each # compilation. It has these indices: # # type: The name of the type being compiled, for use # in compilation procs. # defs: Compiled definitions, both standard and client. # which: type, widget, widgetadaptor # instancevars: Instance variable definitions and initializations. # ivprocdec: Instance variable proc declarations. # tvprocdec: Type variable proc declarations. # typeconstructor: Type constructor body. # widgetclass: The widgetclass, for snit::widgets, only # hasoptions: False, initially; set to true when first # option is defined. # localoptions: Names of local options. # delegatedoptions: Names of delegated options. # localmethods: Names of locally defined methods. # delegatesmethods: no if no delegated methods, yes otherwise. # hashierarchic : no if no hierarchic methods, yes otherwise. # components: Names of defined components. # typecomponents: Names of defined typecomponents. # typevars: Typevariable definitions and initializations. # varnames: Names of instance variables # typevarnames Names of type variables # hasconstructor False, initially; true when constructor is # defined. # resource-$opt The option's resource name # class-$opt The option's class # -default-$opt The option's default value # -validatemethod-$opt The option's validate method # -configuremethod-$opt The option's configure method # -cgetmethod-$opt The option's cget method. # -hastypeinfo The -hastypeinfo pragma # -hastypedestroy The -hastypedestroy pragma # -hastypemethods The -hastypemethods pragma # -hasinfo The -hasinfo pragma # -hasinstances The -hasinstances pragma # -simpledispatch The -simpledispatch pragma WHD: OBSOLETE # -canreplace The -canreplace pragma variable compile # This variable accumulates method dispatch information; it has # the same structure as the %TYPE%::Snit_methodInfo array, and is # used to initialize it. variable methodInfo # This variable accumulates typemethod dispatch information; it has # the same structure as the %TYPE%::Snit_typemethodInfo array, and is # used to initialize it. variable typemethodInfo # The following variable lists the reserved type definition statement # names, e.g., the names you can't use as macros. It's built at # compiler definition time using "info commands". variable reservedwords {}}#-----------------------------------------------------------------------# type compilation commands## The type and widgettype commands use a slave interpreter to compile# the type definition. These are the procs# that are aliased into it.# Initialize the compilerproc ::snit::Comp.Init {} { variable compiler variable reservedwords if {$compiler eq ""} { # Create the compiler's interpreter set compiler [interp create] # Initialize the interpreter $compiler eval { # Load package information # TBD: see if this can be moved outside. catch {package require ::snit::__does_not_exist__} # Protect some Tcl commands our type definitions # will shadow. rename proc _proc rename variable _variable } # Define compilation aliases. $compiler alias pragma ::snit::Comp.statement.pragma $compiler alias widgetclass ::snit::Comp.statement.widgetclass $compiler alias hulltype ::snit::Comp.statement.hulltype $compiler alias constructor ::snit::Comp.statement.constructor $compiler alias destructor ::snit::Comp.statement.destructor $compiler alias option ::snit::Comp.statement.option $compiler alias oncget ::snit::Comp.statement.oncget $compiler alias onconfigure ::snit::Comp.statement.onconfigure $compiler alias method ::snit::Comp.statement.method $compiler alias typemethod ::snit::Comp.statement.typemethod $compiler alias typeconstructor ::snit::Comp.statement.typeconstructor $compiler alias proc ::snit::Comp.statement.proc $compiler alias typevariable ::snit::Comp.statement.typevariable $compiler alias variable ::snit::Comp.statement.variable $compiler alias typecomponent ::snit::Comp.statement.typecomponent $compiler alias component ::snit::Comp.statement.component $compiler alias delegate ::snit::Comp.statement.delegate $compiler alias expose ::snit::Comp.statement.expose # Get the list of reserved words set reservedwords [$compiler eval {info commands}] }}# Compile a type definition, and return the results as a list of two# items: the fully-qualified type name, and a script that will define# the type when executed.## which type, widget, or widgetadaptor# type the type name# body the type definitionproc ::snit::Comp.Compile {which type body} { variable typeTemplate variable nominalTypeProc variable simpleTypeProc variable compile variable compiler variable methodInfo variable typemethodInfo
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?