Posted to tcl by aspect at Wed Oct 08 09:49:08 GMT 2014view raw
- ** Macros in Tcl **
- The invocation [proc $name $arglist $body] creates a command procedure named $name, whose invocation (according to DDL#2) results in the following
- 1.1) a local scope will be created for the local vars
- 1.2) some local vars (the formal arguments) will be initialized with values coming from the actual arguments;
- 1.3) the body will be run as a script in that local scope, returning it's last result;
- 1.4) the local scope will be destroyed
- The invocation [defmacro $name $arglist $body] creates a command procedure named $name, whose expansion and invocation are according to the following:
- 2.1) a local scope will be created for the local vars
- 2.2) some local vars (the formal arguments) will be initialized with values coming from the actual arguments;
- 2.3) the body will be run as a script in that local scope, returning it's last result;
- 2.4) the local scope will be destroyed
- 2.5) the result of step #3 will be evaluated in the calling context as though it were passwd to [eval];
- A macro differs from a proc in that steps 1-4 may occur *at any time*. The interpreter is free to pre-evaluate macros, or to cache the results of a
- macro call to be re-used next time a compatible call-site is evaluated.
- This places limits on the sort of things that can be done in a macro body with defined results. Those limits can be summarised as:
- 3.1) evaluation of a macro body can have no observable side effects
- 3.2) evaluation of a macro body cannot depend on time-varying elements of the execution environment
- Breaching either of these may make demons fly out your nose.
- *** Proof-of concept implementation in pure Tcl ****
- ======
- namespace eval ::macros {}
- proc defmacro {name arglist body} {
- proc ::macros::$name $arglist $body
- uplevel 1 [
- list interp alias {} $name {} expand-macro $name
- ]
- }
- proc expand-macro {name args} {
- tailcall eval [::macros::$name {*}$args]
- }
- # not-very-motivating example usage:
- defmacro let {varName args} {
- return "set [list $varName] \[expr $args\]"
- }
- let x 23*42
- ======
- *** Proof-of-concept implementation inside the interpreter ***
- See http://sourceforge.net/p/tcl/patches/535/ - spjuth, 2008; via http://wiki.tcl.tk/11159