Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/Sugar+macros+collection?V=21
QUERY_STRINGV=21
CONTENT_TYPE
DOCUMENT_URI/revision/Sugar+macros+collection
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.69.6.89
REMOTE_PORT27264
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.16.203.107
HTTP_CF_RAY886823ed38887317-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_REFERERhttps://wiki.tcl.tk/revision/Sugar+macros+collection?V=21
HTTP_CF_CONNECTING_IP3.16.203.107
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {Sugar macros collection} A\ page\ to\ collect\ useful\ \[Sugar\]\ macros.\n\n----\n'''inlist'''\ command\ macro\n\nExpands\n\n======\n\ \[inlist\ \$list\ \$element\]\n======\n\nin\n\n======\n\ \[expr\ \{\[lsearch\ -exact\ \$list\ \$element\]\ !=\ -1\}\]\n======\n\nThis\ one\ was\ suggested\ by\ \[Richard\ Suchenwirth\]\ (but\ the\ implementation\ is\ mine\ (\[SS\]),\ so\ even\ possible\ bugs):\n\n======\n\ sugar::macro\ inlist\ argv\ \{\n\ \ \ \ \ if\ \{\[llength\ \$argv\]\ !=\ 3\}\ \{error\ \"Bad\ number\ of\ arguments\"\}\n\ \ \ \ \ list\ expr\ \\\n\ \ \ \ \ \ \ \ \ \"\\\{\\\[lsearch\ -exact\ \[lindex\ \$argv\ 1\]\ \[lindex\ \$argv\ 2\]\\\]\ !=\ -1\\\}\"\n\ \}\n======\n\n\[AMG\]:\ See\ also\ \[in\],\ which\ can\ be\ used\ as\ a\ command\ as\ well\ as\ a\ math\ operator\ in\ Tcl\ 8.5.\n\n----\n'''tailrec_proc'''\ transformer\n\nA\ wrapper\ to\ \[proc\]\ able\ to\ optimize\ tail\ recursive\ calls.\nFor\ example\ the\ following:\n\n======\n\ tailrec_proc\ ack\ \{m\ n\}\ \{\n\ \ \ \ if\ \{\$m\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ return\ \[expr\ \{\$n\ +\ 1\}\]\n\ \ \ \ \}\ elseif\ \{\$n\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ ack\ \[expr\ \{\$m\ -\ 1\}\]\ 1\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ ack\ \[expr\ \{\$m\ -\ 1\}\]\ \[ack\ \$m\ \[expr\ \{\$n\ -\ 1\}\]\]\n\ \ \ \ \}\n\ \}\n======\n\nwill\ be\ equivalent\ to:\n\n======\n\ proc\ ack\ \{m\ n\}\ \{\n\ \ \ \ while\ 1\ \{\n\ \ \ \ \ \ \ \ if\ \{\$m\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[expr\ \{\$n\ +\ 1\}\]\n\ \ \ \ \ \ \ \ \}\ elseif\ \{\$n\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \[list\ m\ n\]\ \[list\ \[expr\ \{\$m\ -\ 1\}\]\ 1\]\ break\n\ \ \ \ \ \ \ \ \ \ \ \ continue\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \[list\ m\ n\]\ \[list\ \[expr\ \{\$m\ -\ 1\}\]\ \[ack\ \$m\ \[expr\ \{\$n\ -\ 1\}\]\]\]\ break\n\ \ \ \ \ \ \ \ \ \ \ \ continue\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ break\n\ \ \ \ \}\n\ \}\n======\n\nThis\ is\ the\ example\ in\ the\ page\ \[Sugar\ transformers\],\ but\ with\ some\ bugfix.\ This\ new\ version\ care\ a\ bit\ more\ about\nindentation\ and\ does\ not\ use\ temp\ variables,\ but\ \[foreach\]\ to\ perform\ multi-assignment\ (thanks\ to\ Richard\ Suchenwirth\ for\nthe\ idea).\n\n======\n\ proc\ tailrec_proc\ \{name\ arglist\ body\}\ \{\n\ \ \ \ \ #\ Convert\ the\ script\ into\ a\ Tcl\ list\n\ \ \ \ \ set\ l\ \[sugar::scriptToList\ \$body\]\n\ \ \ \ \ #\ Convert\ tail\ calls\n\ \ \ \ \ set\ l\ \[tailrec_convert_calls\ \$name\ \$arglist\ \$l\]\n\ \ \ \ \ #\ Add\ the\ final\ break\n\ \ \ \ \ lappend\ l\ \[list\ \{TOK\ break\}\ \{EOL\ \"\\n\"\}\]\n\ \ \ \ \ #\ Convert\ it\ back\ to\ script\n\ \ \ \ \ set\ body\ \[sugar::listToScript\ \$l\]\n\ \ \ \ \ #\ Add\ the\ surrounding\ while\ 1\n\ \ \ \ \ set\ body\ \"while\ 1\ \{\$body\}\"\n\ \ \ \ \ #\ Call\ \[proc\]\n\ \ \ \ \ uplevel\ proc\ \[list\ \$name\ \$arglist\ \$body\]\n\ \}\n\ \n\ #\ Convert\ tail\ calls.\ Helper\ for\ tailrec_proc.\n\ #\ Recursively\ call\ itself\ on\ \[if\]\ script\ arguments.\n\ proc\ tailrec_convert_calls\ \{name\ arglist\ code\}\ \{\n\ \ \ \ \ #\ Search\ the\ last\ non-null\ command.\n\ \ \ \ \ set\ lastidx\ -1\n\ \ \ \ \ for\ \{set\ j\ 0\}\ \{\$j\ <\ \[llength\ \$code\]\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ \ set\ cmd\ \[lindex\ \$code\ \$j\]\n\ \ \ \ \ \ \ \ \ if\ \{\[sugar::indexbytype\ \$cmd\ TOK\ 0\]\ !=\ -1\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ set\ lastidx\ \$j\n\ \ \ \ \ \ \ \ \ \ \ \ \ set\ cmdidx\ \[sugar::indexbytype\ \$cmd\ TOK\ 0\]\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \}\n\ \ \ \ \ if\ \{\$lastidx\ ==\ -1\}\ \{\n\ \ \ \ \ \ \ \ \ return\ \$code\n\ \ \ \ \ \}\n\ \ \ \ \ set\ cmd\ \[lindex\ \$code\ \$lastidx\]\n\ \ \ \ \ set\ cmdname\ \[lindex\ \$cmd\ \$cmdidx\ 1\]\n\ \ \ \ \ if\ \{\[lindex\ \$cmd\ 0\ 0\]\ eq\ \{SPACE\}\}\ \{\n\ \ \ \ \ \ \ \ \ set\ space\ \[lindex\ \$cmd\ 0\ 1\]\n\ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ set\ space\ \"\ \"\n\ \ \ \ \ \}\n\ \ \ \ \ if\ \{\$cmdname\ eq\ \$name\}\ \{\n\ \ \ \ \ \ \ \ \ #puts\ \"TAILCALL\ ->\ \$cmdname\"\n\ \ \ \ \ \ \ \ \ set\ recargs\ \[lrange\ \[sugar::tokens\ \$cmd\]\ 1\ end\]\n\ \ \ \ \ \ \ \ \ set\ t\ \[list\ \[list\ SPACE\ \$space\]\ \[list\ TOK\ foreach\]\ \[list\ SPACE\ \"\ \"\]\]\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \"\\\[list\ \"\]\n\ \ \ \ \ \ \ \ \ foreach\ a\ \$arglist\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \$a\]\ \[list\ SPACE\ \"\ \"\]\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \"\\\]\ \"\]\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \"\\\[list\ \"\]\n\ \ \ \ \ \ \ \ \ foreach\ a\ \$recargs\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \$a\]\ \[list\ SPACE\ \"\ \"\]\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \"\\\]\ \"\]\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ break\]\ \[list\ EOL\ \"\\n\"\]\n\ \ \ \ \ \ \ \ \ set\ code\ \[linsert\ \$code\ \$lastidx\ \$t\]\n\ \ \ \ \ \ \ \ \ incr\ lastidx\n\ \ \ \ \ \ \ \ \ lset\ code\ \$lastidx\ \[list\ \[list\ SPACE\ \$space\]\ \[list\ TOK\ continue\]\ \[list\ EOL\ \"\\n\"\]\]\n\ \ \ \ \ \}\ elseif\ \{\$cmdname\ eq\ \{if\}\}\ \{\n\ \ \ \ \ \ \ \ \ #puts\ \"IF\ CALL\"\n\ \ \ \ \ \ \ \ \ for\ \{set\ j\ 0\}\ \{\$j\ <\ \[llength\ \$cmd\]\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[lindex\ \$cmd\ \$j\ 0\]\ ne\ \{TOK\}\}\ continue\ \n\ \ \ \ \ \ \ \ \ \ \ \ \ switch\ --\ \[lindex\ \$cmd\ \$j\ 1\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ -\ elseif\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ incr\ j\ 2\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ incr\ j\ 1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ default\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ script\ \[lindex\ \$code\ \$lastidx\ \$j\ 1\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #puts\ \"\$j\ ->\ \$script\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ scriptcode\ \[sugar::scriptToList\ \[lindex\ \$script\ 0\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ converted\ \[tailrec_convert_calls\ \$name\ \$arglist\ \$scriptcode\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lset\ code\ \$lastidx\ \$j\ 1\ \[list\ \[sugar::listToScript\ \$converted\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \}\n\ \ \ \ \ return\ \$code\n\ \}\n======\n\n\[AMG\]:\ See\ \[tailcall\].\n\n----\n'''Math\ commands\ as\ macro'''\n\nExpands\n\n======\n\ \[+\ \$a\ \$b\ \$c\]\n======\n\nto\n\n======\n\ \[expr\ \{\$a+\$b+\$c\}\]\n======\n\nPerforms\ some\ pre-calculation\ of\ the\ value\ at\ compile\ time\ when\ possible.\nFor\ example\n\n======\n\ \[+\ \[*\ \[+\ 1\ 2\]\ 4\]\ 1\]\n======\n\nis\ expanded\ to\n\n======\n\ \[expr\ 13\]\n======\n\nand\ so\ on.\n\nNOTE:\ this\ macro\ requires\ sugar\ 0.1\ to\ be\ used,\ it's\ availabe\ for\ download\ from\ the\ \[Sugar\]\ page.\n\n======\n\ package\ require\ sugar\n\ \n\ sugar::macro\ \{+\ -\ /\ *\}\ \{op\ args\}\ \{\n\ \ \ \ \ for\ \{set\ j\ 0\}\ \{\$j\ <\ \[llength\ \$args\]\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ #\ Is\ the\ operand\ in\ the\ form\ \[expr\ \{<valid-double>\}\]?\n\ \ \ \ \ \ \ \ #\ This\ can\ be\ translated\ to\ just\ <valid-double>\n\ \ \ \ \ \ \ \ if\ \{\[regexp\ \{^\\\[expr\ (.*)\\\]\$\}\ \[lindex\ \$args\ \$j\]\ =>\ double\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ is\ double\ -strict\ \$double\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lset\ args\ \$j\ \$double\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ if\ \{!\[string\ is\ double\ -strict\ \[lindex\ \$args\ \$j\]\]\}\ break\n\ \ \ \ \ \}\n\ \ \ \ \ if\ \{\$j\ ==\ \[llength\ \$args\]\}\ \{\n\ \ \ \ \ \ \ \ #\ The\ expression\ can\ be\ computed\ at\ compile-time?\n\ \ \ \ \ \ \ \ list\ expr\ \"\[eval\ expr\ \[join\ \$args\ \$op\]\]\"\n\ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ list\ expr\ \"\{\[join\ \$args\ \$op\]\}\"\n\ \ \ \ \ \}\n\ \}\n\ \n\ sugar::proc\ test\ \{\}\ \{\n\ \ \ \ \ puts\ \[*\ \[+\ 5\ 2\]\ 4\]\n\ \ \ \ \ puts\ \[+\ 1\]\n\ \}\n\ \n\ puts\ \[info\ body\ test\]\n\ test\n======\n\n\[AMG\]:\ See\ \[tcl::mathfunc\]\ and\ \[tcl::mathop\].\n\n----\n\[A/AK\]\ is\ \[using\ sugar\ for\ forward-compatible\ \{*\}\]\n\n----\n\[A/AK\]\ work\ above\ had\ inspired\ to\ \[FM\]\ a\ math\ expand\ syntax\ extension\ :\n\n======\n#\ word\ prefixed\ by\ \{=\}\ is\ treated\ as\ an\ expression\ :\ ie\ \{=\}expression\ is\ transformed\ in\ \[expr\ \{expression\}\]\n\n======\nsugar::syntaxmacro\ mathexpand\ args\ \{\n\ \ \ #\ The\ first\ thing\ we\ check:\ is\ there\ anything\ to\ expand?\n\ \ \ if\ \{\[lsearch\ \$args\ \{\{=\}?*\}\]==-1\}\ \{\n\ \ \ \ \ \ \ #\ and\ if\ there\ is\ none...\n\ \ \ \ \ \ \ return\ \$args\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ set\ evalCmd\ \[\]\n\ \ \ \ \ \ \ foreach\ token\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ #\ If\ the\ arg\ is\ expanded\n\ \ \ \ \ \ \ \ \ \ if\ \{\[string\ match\ \{\{=\}?*\}\ \$token\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ whattoexpand\ \[string\ range\ \$token\ 3\ end\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ evalCmd\ \"\\\[expr\ \{\$whattoexpand\}\\\]\"\n\ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ we\ append\ a\ one-element\ \[list\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ to\ the\ eval's\ argument\ list\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ evalCmd\ \"\$token\"\n\ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \}\n\ \ \ \ \ \ return\ \$evalCmd\n\ \ \ \}\n\}\n#\ test\npackage\ require\ Tk\n\nsugar::proc\ testmathexpand\ \{\}\ \{\n\ \ \ set\ A\ \[list\ \ \{=\}(\[winfo\ screenwidth\ .\]-\[winfo\ width\ .\])/2\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \{=\}(\[winfo\ screenheight\ .\]-\[winfo\ height\ .\])/2\]\n\ \ \ return\ +\[join\ \$A\ +\]\n\}\n\nproc\ testexpr\ \{\}\ \{\n\ \ \ set\ A\ \[list\ \ \[expr\ \{(\[winfo\ screenwidth\ .\]-\[winfo\ width\ .\])/2\}\]\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \[expr\ \{(\[winfo\ screenheight\ .\]-\[winfo\ height\ .\])/2\}\]\]\n\ \ \ return\ +\[join\ \$A\ +\]\n\}\nwm\ geom\ .\ \[testmathexpand\]\nwm\ geom\ .\ \[testexpr\]\ntime\ \{testmathexpand\}\ 10000\ \;#\ ->\ 4.7\ microseconds\ per\ iteration\ntime\ \{testexpr\}\ 10000\;\ #\ ->\ 4.7\ microseconds\ per\ iteration\n======\n\n\[AMG\]:\ The\ empty\ script\ substitution\ \[\[\]\]\ produces\ empty\ string,\ but\ it's\ not\ a\ very\ common\ idiom.\ \ In\ fact,\ this\ is\ the\ first\ time\ I\ have\ seen\ it\ used\ in\ practice.\ \ Profiling\ via\ \[time\]\ shows\ it\ to\ be\ as\ fast\ as\ the\ alternatives.\ \ In\ actual\ code,\ I've\ only\ ever\ seen\ \"\",\ \{\},\ and\ sometimes\ \[\[list\]\]\ on\ the\ theory\ that\ it\ slightly\ reduces\ \[shimmering\].\ \ (By\ the\ way,\ using\ \[\[list\]\]\ to\ construct\ an\ empty\ list\ doesn't\ improve\ performance.)\n\n<<categories>>\ Application\ |\ Dev.\ Tools\ |\ String\ Processing regexp2} CALL {my render {Sugar macros collection} A\ page\ to\ collect\ useful\ \[Sugar\]\ macros.\n\n----\n'''inlist'''\ command\ macro\n\nExpands\n\n======\n\ \[inlist\ \$list\ \$element\]\n======\n\nin\n\n======\n\ \[expr\ \{\[lsearch\ -exact\ \$list\ \$element\]\ !=\ -1\}\]\n======\n\nThis\ one\ was\ suggested\ by\ \[Richard\ Suchenwirth\]\ (but\ the\ implementation\ is\ mine\ (\[SS\]),\ so\ even\ possible\ bugs):\n\n======\n\ sugar::macro\ inlist\ argv\ \{\n\ \ \ \ \ if\ \{\[llength\ \$argv\]\ !=\ 3\}\ \{error\ \"Bad\ number\ of\ arguments\"\}\n\ \ \ \ \ list\ expr\ \\\n\ \ \ \ \ \ \ \ \ \"\\\{\\\[lsearch\ -exact\ \[lindex\ \$argv\ 1\]\ \[lindex\ \$argv\ 2\]\\\]\ !=\ -1\\\}\"\n\ \}\n======\n\n\[AMG\]:\ See\ also\ \[in\],\ which\ can\ be\ used\ as\ a\ command\ as\ well\ as\ a\ math\ operator\ in\ Tcl\ 8.5.\n\n----\n'''tailrec_proc'''\ transformer\n\nA\ wrapper\ to\ \[proc\]\ able\ to\ optimize\ tail\ recursive\ calls.\nFor\ example\ the\ following:\n\n======\n\ tailrec_proc\ ack\ \{m\ n\}\ \{\n\ \ \ \ if\ \{\$m\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ return\ \[expr\ \{\$n\ +\ 1\}\]\n\ \ \ \ \}\ elseif\ \{\$n\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ ack\ \[expr\ \{\$m\ -\ 1\}\]\ 1\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ ack\ \[expr\ \{\$m\ -\ 1\}\]\ \[ack\ \$m\ \[expr\ \{\$n\ -\ 1\}\]\]\n\ \ \ \ \}\n\ \}\n======\n\nwill\ be\ equivalent\ to:\n\n======\n\ proc\ ack\ \{m\ n\}\ \{\n\ \ \ \ while\ 1\ \{\n\ \ \ \ \ \ \ \ if\ \{\$m\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ \[expr\ \{\$n\ +\ 1\}\]\n\ \ \ \ \ \ \ \ \}\ elseif\ \{\$n\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \[list\ m\ n\]\ \[list\ \[expr\ \{\$m\ -\ 1\}\]\ 1\]\ break\n\ \ \ \ \ \ \ \ \ \ \ \ continue\n\ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ foreach\ \[list\ m\ n\]\ \[list\ \[expr\ \{\$m\ -\ 1\}\]\ \[ack\ \$m\ \[expr\ \{\$n\ -\ 1\}\]\]\]\ break\n\ \ \ \ \ \ \ \ \ \ \ \ continue\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ break\n\ \ \ \ \}\n\ \}\n======\n\nThis\ is\ the\ example\ in\ the\ page\ \[Sugar\ transformers\],\ but\ with\ some\ bugfix.\ This\ new\ version\ care\ a\ bit\ more\ about\nindentation\ and\ does\ not\ use\ temp\ variables,\ but\ \[foreach\]\ to\ perform\ multi-assignment\ (thanks\ to\ Richard\ Suchenwirth\ for\nthe\ idea).\n\n======\n\ proc\ tailrec_proc\ \{name\ arglist\ body\}\ \{\n\ \ \ \ \ #\ Convert\ the\ script\ into\ a\ Tcl\ list\n\ \ \ \ \ set\ l\ \[sugar::scriptToList\ \$body\]\n\ \ \ \ \ #\ Convert\ tail\ calls\n\ \ \ \ \ set\ l\ \[tailrec_convert_calls\ \$name\ \$arglist\ \$l\]\n\ \ \ \ \ #\ Add\ the\ final\ break\n\ \ \ \ \ lappend\ l\ \[list\ \{TOK\ break\}\ \{EOL\ \"\\n\"\}\]\n\ \ \ \ \ #\ Convert\ it\ back\ to\ script\n\ \ \ \ \ set\ body\ \[sugar::listToScript\ \$l\]\n\ \ \ \ \ #\ Add\ the\ surrounding\ while\ 1\n\ \ \ \ \ set\ body\ \"while\ 1\ \{\$body\}\"\n\ \ \ \ \ #\ Call\ \[proc\]\n\ \ \ \ \ uplevel\ proc\ \[list\ \$name\ \$arglist\ \$body\]\n\ \}\n\ \n\ #\ Convert\ tail\ calls.\ Helper\ for\ tailrec_proc.\n\ #\ Recursively\ call\ itself\ on\ \[if\]\ script\ arguments.\n\ proc\ tailrec_convert_calls\ \{name\ arglist\ code\}\ \{\n\ \ \ \ \ #\ Search\ the\ last\ non-null\ command.\n\ \ \ \ \ set\ lastidx\ -1\n\ \ \ \ \ for\ \{set\ j\ 0\}\ \{\$j\ <\ \[llength\ \$code\]\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ \ set\ cmd\ \[lindex\ \$code\ \$j\]\n\ \ \ \ \ \ \ \ \ if\ \{\[sugar::indexbytype\ \$cmd\ TOK\ 0\]\ !=\ -1\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ set\ lastidx\ \$j\n\ \ \ \ \ \ \ \ \ \ \ \ \ set\ cmdidx\ \[sugar::indexbytype\ \$cmd\ TOK\ 0\]\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \}\n\ \ \ \ \ if\ \{\$lastidx\ ==\ -1\}\ \{\n\ \ \ \ \ \ \ \ \ return\ \$code\n\ \ \ \ \ \}\n\ \ \ \ \ set\ cmd\ \[lindex\ \$code\ \$lastidx\]\n\ \ \ \ \ set\ cmdname\ \[lindex\ \$cmd\ \$cmdidx\ 1\]\n\ \ \ \ \ if\ \{\[lindex\ \$cmd\ 0\ 0\]\ eq\ \{SPACE\}\}\ \{\n\ \ \ \ \ \ \ \ \ set\ space\ \[lindex\ \$cmd\ 0\ 1\]\n\ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ set\ space\ \"\ \"\n\ \ \ \ \ \}\n\ \ \ \ \ if\ \{\$cmdname\ eq\ \$name\}\ \{\n\ \ \ \ \ \ \ \ \ #puts\ \"TAILCALL\ ->\ \$cmdname\"\n\ \ \ \ \ \ \ \ \ set\ recargs\ \[lrange\ \[sugar::tokens\ \$cmd\]\ 1\ end\]\n\ \ \ \ \ \ \ \ \ set\ t\ \[list\ \[list\ SPACE\ \$space\]\ \[list\ TOK\ foreach\]\ \[list\ SPACE\ \"\ \"\]\]\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \"\\\[list\ \"\]\n\ \ \ \ \ \ \ \ \ foreach\ a\ \$arglist\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \$a\]\ \[list\ SPACE\ \"\ \"\]\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \"\\\]\ \"\]\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \"\\\[list\ \"\]\n\ \ \ \ \ \ \ \ \ foreach\ a\ \$recargs\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \$a\]\ \[list\ SPACE\ \"\ \"\]\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ \"\\\]\ \"\]\n\ \ \ \ \ \ \ \ \ lappend\ t\ \[list\ TOK\ break\]\ \[list\ EOL\ \"\\n\"\]\n\ \ \ \ \ \ \ \ \ set\ code\ \[linsert\ \$code\ \$lastidx\ \$t\]\n\ \ \ \ \ \ \ \ \ incr\ lastidx\n\ \ \ \ \ \ \ \ \ lset\ code\ \$lastidx\ \[list\ \[list\ SPACE\ \$space\]\ \[list\ TOK\ continue\]\ \[list\ EOL\ \"\\n\"\]\]\n\ \ \ \ \ \}\ elseif\ \{\$cmdname\ eq\ \{if\}\}\ \{\n\ \ \ \ \ \ \ \ \ #puts\ \"IF\ CALL\"\n\ \ \ \ \ \ \ \ \ for\ \{set\ j\ 0\}\ \{\$j\ <\ \[llength\ \$cmd\]\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[lindex\ \$cmd\ \$j\ 0\]\ ne\ \{TOK\}\}\ continue\ \n\ \ \ \ \ \ \ \ \ \ \ \ \ switch\ --\ \[lindex\ \$cmd\ \$j\ 1\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ -\ elseif\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ incr\ j\ 2\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ incr\ j\ 1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ default\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ script\ \[lindex\ \$code\ \$lastidx\ \$j\ 1\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #puts\ \"\$j\ ->\ \$script\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ scriptcode\ \[sugar::scriptToList\ \[lindex\ \$script\ 0\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ converted\ \[tailrec_convert_calls\ \$name\ \$arglist\ \$scriptcode\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lset\ code\ \$lastidx\ \$j\ 1\ \[list\ \[sugar::listToScript\ \$converted\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \}\n\ \ \ \ \ return\ \$code\n\ \}\n======\n\n\[AMG\]:\ See\ \[tailcall\].\n\n----\n'''Math\ commands\ as\ macro'''\n\nExpands\n\n======\n\ \[+\ \$a\ \$b\ \$c\]\n======\n\nto\n\n======\n\ \[expr\ \{\$a+\$b+\$c\}\]\n======\n\nPerforms\ some\ pre-calculation\ of\ the\ value\ at\ compile\ time\ when\ possible.\nFor\ example\n\n======\n\ \[+\ \[*\ \[+\ 1\ 2\]\ 4\]\ 1\]\n======\n\nis\ expanded\ to\n\n======\n\ \[expr\ 13\]\n======\n\nand\ so\ on.\n\nNOTE:\ this\ macro\ requires\ sugar\ 0.1\ to\ be\ used,\ it's\ availabe\ for\ download\ from\ the\ \[Sugar\]\ page.\n\n======\n\ package\ require\ sugar\n\ \n\ sugar::macro\ \{+\ -\ /\ *\}\ \{op\ args\}\ \{\n\ \ \ \ \ for\ \{set\ j\ 0\}\ \{\$j\ <\ \[llength\ \$args\]\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ #\ Is\ the\ operand\ in\ the\ form\ \[expr\ \{<valid-double>\}\]?\n\ \ \ \ \ \ \ \ #\ This\ can\ be\ translated\ to\ just\ <valid-double>\n\ \ \ \ \ \ \ \ if\ \{\[regexp\ \{^\\\[expr\ (.*)\\\]\$\}\ \[lindex\ \$args\ \$j\]\ =>\ double\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ is\ double\ -strict\ \$double\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lset\ args\ \$j\ \$double\n\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ if\ \{!\[string\ is\ double\ -strict\ \[lindex\ \$args\ \$j\]\]\}\ break\n\ \ \ \ \ \}\n\ \ \ \ \ if\ \{\$j\ ==\ \[llength\ \$args\]\}\ \{\n\ \ \ \ \ \ \ \ #\ The\ expression\ can\ be\ computed\ at\ compile-time?\n\ \ \ \ \ \ \ \ list\ expr\ \"\[eval\ expr\ \[join\ \$args\ \$op\]\]\"\n\ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ list\ expr\ \"\{\[join\ \$args\ \$op\]\}\"\n\ \ \ \ \ \}\n\ \}\n\ \n\ sugar::proc\ test\ \{\}\ \{\n\ \ \ \ \ puts\ \[*\ \[+\ 5\ 2\]\ 4\]\n\ \ \ \ \ puts\ \[+\ 1\]\n\ \}\n\ \n\ puts\ \[info\ body\ test\]\n\ test\n======\n\n\[AMG\]:\ See\ \[tcl::mathfunc\]\ and\ \[tcl::mathop\].\n\n----\n\[A/AK\]\ is\ \[using\ sugar\ for\ forward-compatible\ \{*\}\]\n\n----\n\[A/AK\]\ work\ above\ had\ inspired\ to\ \[FM\]\ a\ math\ expand\ syntax\ extension\ :\n\n======\n#\ word\ prefixed\ by\ \{=\}\ is\ treated\ as\ an\ expression\ :\ ie\ \{=\}expression\ is\ transformed\ in\ \[expr\ \{expression\}\]\n\n======\nsugar::syntaxmacro\ mathexpand\ args\ \{\n\ \ \ #\ The\ first\ thing\ we\ check:\ is\ there\ anything\ to\ expand?\n\ \ \ if\ \{\[lsearch\ \$args\ \{\{=\}?*\}\]==-1\}\ \{\n\ \ \ \ \ \ \ #\ and\ if\ there\ is\ none...\n\ \ \ \ \ \ \ return\ \$args\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ set\ evalCmd\ \[\]\n\ \ \ \ \ \ \ foreach\ token\ \$args\ \{\n\ \ \ \ \ \ \ \ \ \ #\ If\ the\ arg\ is\ expanded\n\ \ \ \ \ \ \ \ \ \ if\ \{\[string\ match\ \{\{=\}?*\}\ \$token\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ whattoexpand\ \[string\ range\ \$token\ 3\ end\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ evalCmd\ \"\\\[expr\ \{\$whattoexpand\}\\\]\"\n\ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ we\ append\ a\ one-element\ \[list\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ to\ the\ eval's\ argument\ list\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ evalCmd\ \"\$token\"\n\ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \}\n\ \ \ \ \ \ return\ \$evalCmd\n\ \ \ \}\n\}\n#\ test\npackage\ require\ Tk\n\nsugar::proc\ testmathexpand\ \{\}\ \{\n\ \ \ set\ A\ \[list\ \ \{=\}(\[winfo\ screenwidth\ .\]-\[winfo\ width\ .\])/2\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \{=\}(\[winfo\ screenheight\ .\]-\[winfo\ height\ .\])/2\]\n\ \ \ return\ +\[join\ \$A\ +\]\n\}\n\nproc\ testexpr\ \{\}\ \{\n\ \ \ set\ A\ \[list\ \ \[expr\ \{(\[winfo\ screenwidth\ .\]-\[winfo\ width\ .\])/2\}\]\ \\\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \[expr\ \{(\[winfo\ screenheight\ .\]-\[winfo\ height\ .\])/2\}\]\]\n\ \ \ return\ +\[join\ \$A\ +\]\n\}\nwm\ geom\ .\ \[testmathexpand\]\nwm\ geom\ .\ \[testexpr\]\ntime\ \{testmathexpand\}\ 10000\ \;#\ ->\ 4.7\ microseconds\ per\ iteration\ntime\ \{testexpr\}\ 10000\;\ #\ ->\ 4.7\ microseconds\ per\ iteration\n======\n\n\[AMG\]:\ The\ empty\ script\ substitution\ \[\[\]\]\ produces\ empty\ string,\ but\ it's\ not\ a\ very\ common\ idiom.\ \ In\ fact,\ this\ is\ the\ first\ time\ I\ have\ seen\ it\ used\ in\ practice.\ \ Profiling\ via\ \[time\]\ shows\ it\ to\ be\ as\ fast\ as\ the\ alternatives.\ \ In\ actual\ code,\ I've\ only\ ever\ seen\ \"\",\ \{\},\ and\ sometimes\ \[\[list\]\]\ on\ the\ theory\ that\ it\ slightly\ reduces\ \[shimmering\].\ \ (By\ the\ way,\ using\ \[\[list\]\]\ to\ construct\ an\ empty\ list\ doesn't\ improve\ performance.)\n\n<<categories>>\ Application\ |\ Dev.\ Tools\ |\ String\ Processing} CALL {my revision {Sugar macros collection}} CALL {::oo::Obj6824 process revision/Sugar+macros+collection} CALL {::oo::Obj6822 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4