You are here


admin의 아바타
첨부 파일파일 크기
File cmacro.tcl7.43 KB

홈페이지 :

A C-like macro substitution mechanism for Tcl source code.
The purpose is that macro expansions will be inlined in a Tcl proc, for better performance than if another proc were called. (This is also a common reason why macros are used instead of functions in C.)


# C-like Macro system for Tcl.
# cmacro::reset ?beginChar? ?midChar? ?endChar?
# Delete any existing macro definitions,
# and set the special substitution delimiters.
# Defaults are ""
# cmacro::define name formal_parameter_list body
# Define a macro named "name" to expand to "body",
# substituting occurrances of the formal parameters
# with values provided when the macro is used.
# Tcl "string map" is used to make the substitutions.
# cmacro::substitute string
# Preform macro substitutions on string
# and return the new string.
# cmacro::mproc name params body
# Define a procedure just like "proc" does,
# but first preform macro substitutions on the body.
# For examples, see the tests at the end of this file.
# To test, run with ::argv set to "--test-cmacro"

Here we define three macros, "hd", "tl", and "tlN". The first two take one parameter, but tlN takes two.

        cmacro::define hd X {[lindex X 0]}
        cmacro::define tl X {[lrange X 1 end]}
        cmacro::define tlN {N X} {[lrange X N end]}

(* "hd" returns the head of a list, its first element. "tl" returns the tail, the rest of the list. "tlN" returns the tail starting with the Nth element, rather than starting with the second. *)

Now we use them in two proc definitions, but we use "cmacro::mproc" rather than "proc" so macro substitutions will occur.

        cmacro::mproc second list { return hd > }
        cmacro::mproc tailN {n list} { return tlN }

(* "second" returns the head of the tail of the list, which is its second item. "tailN" is a simple wrapper around "tlN", demonstrating how a "," is used to separate the arguments to the macro "tlN". *)

Although the C preprocessor uses parentheses "(" ")" to mark macro arguments, we prefer angle brackets "" so that parentheses may be used for array references. (You may change the special characters with the cmacro::reset command if you don't like angle brackets.)

The "" ends the macro arguments. Inner macros substitute before outer ones. There may be no extra "" characters inside the macro arguments.

Macro arguments are "string trim"med, so spaces may be used after "", and around "," to improve readability, without changing the substitution. This matters when the formal parameters of the macro are used in strings in the macro definition.

Whereas C allows macros with no arguments and no parens, we require the angle brackets to be used.

Here is "second_proc", which is the same as "second" except that it is written using procs instead of macros:

proc hd_proc X {lindex $X 0}
proc tl_proc X {lrange $X 1 end}
proc second_proc list {hd_proc [tl_proc $list]}

And here is a preformance test:

set list {one two three four five}

puts fast=[time {second $list} 2000]
puts slow=[time {second_proc $list} 2000]

And the results:

$ tclsh8.4 perform.tcl
fast=7 microseconds per iteration
slow=37 microseconds per iteration