オーソドックスなものはすでにコメント済み(comment-275)ですが、あらためて趣向を変えて、この手のお題では恒例の“ズル”である、字句解析器(スキャナ)の表の書き換えで挑戦してみました。Squeak4.1 を使用。
| oldTable pairs iota newTable | oldTable := Scanner classPool at: #TypeTable. iota := 1 to: oldTable size. pairs := iota with: oldTable collect: #->. newTable := pairs as: Dictionary. newTable at: $左 charCode put: #leftParenthesis. newTable at: $右 charCode put: #rightParenthesis. newTable at: $始 charCode put: #leftBracket. newTable at: $終 charCode put: #rightBracket. Scanner classPool at: #TypeTable put: newTable
作業はテーブルを書き換えているだけ。さらにこの細工の時点でも、括弧を(さほど無茶をせずに―)使っていないというところもミソですね。変幻自在さでは定評のあるさしもの LISP もこのユルさはまではマネできまい…とも。w
追記: 細工の時点で括弧を使わないのは難しいにしても、ここで Smalltalk でやっていることにあとほんの少し手続きを増やせば(set-syntax-from-char に加えて、関数の定義 と set-macro-character など)、Common Lisp でも同様のことは可能(―なはず^^;)です。念のため。
結果、次のコードが実行できるようになります。
| limit next | limit := 20. next := 1. 左 1 to: limit 右 do: 始 :each | Transcript cr; show: each printString, '! = ', 左 next := next * each 右 終
念のため、通常の、括弧を使用したものであればこう。
| limit next | limit := 20. next := 1. (1 to: limit) do: [:each | Transcript cr; show: each printString, '! = ', (next := next * each)]
元の状態に戻すには、Scanner initialize を do it します。起動中のイメージを保存せずに再起動してもOKです(ただ、起動後に施した他の変更も破棄されてしまうので注意)。