プログラマーができることは、メタでできる
メタプログラミングに関する考察をメモする
単語の羅列
・
・
・
知識
知恵
メタプログラミングは 知恵をアクセス可能な状態にすることを目標にしなければならない。
C In S-Expression
テキスト形式
http://ll.jus.or.jp/2009/slide/beforeafter/lltv-beforeafter-shiro/slides/lltv.html
プレゼンのリポート形式
http://www.atmarkit.co.jp/news/200909/07/lltv02.html
これは、数年前、研究段階だと発表された記事で、その後どうなっているかは不明。
でも、インテンショナルプログラミングをするためのヒントが書かれていると思う箇所があったのです。
それはなにかというと、インテンショナルプログラミングのwikiの説明
のなかに、
「1 から 10 までの数を表示する」と意図を記述すると、下記のコードと同等のコードが得られると書いてある
for (int i = 1; i <= 10; i++) { System.out.println("the number is " + i); }
この記事と、本物のマクロ”でCのコード行数を半分に!で紹介されている問題点3の記事が似ているのだ。
抜粋すると
int i; : for (i = 0; i < (int)clen; i++) putchar((unsigned char)s[i]);
for (int i = [0..clen]) { putchar(...) } とか書けたらなあ
である。これは、C言語の無駄な記述をとらえたものである。
ちなみに、シモニー氏の記述は
<<print the numbers 1 to 10>>
である。
forすらない、シンプルな記述だ。
チャールズシモニーは、意図をコードに展開するというアプローチでこの考えに達したのだろうとおもうが、この記事を書いている人は、もともとあるコードをみて、それを人間の理解しやすい形式にコンパクトにまとめるというアプローチで到達したものと考えられる。
そして、これはLisp系のマクロ(本物のマクロと称している)を使えば可能であるとしている。
なかなかいいアプローチだとおもう、1対1に対応する、S式の表現をほぼそのままの表現を保てば、lispのマクロを使って展開することができる。
問題はS式表現風に元のコードを解析し、逆にS式を対象とするC言語とかに変換する必要がある。
ネットでも同様のことをしようとしたと思われる人が、ANTLRを使ってこころみてみようとしていたのを見つけた。
http://antlr.1301665.n2.nabble.com/Parsing-Lisp-into-C-td3724626.html
Input:
(defun foo (x y) (progn (+ x 1) (+ y 1)))
Grammar:
program: (sexpr)* -> ^(PROGRAM sexpr*); sexpr: QT?(list|atom) ; list: '(' ')' | '(' members ')' -> ^(LIST members); members: (sexpr)+; atom: OPERATOR | ID | num | STRING ; num : (n=INT|n=FLOAT) -> ^(NUM $n);
AST Output:
PROGRAM LIST defun foo LIST x y LIST progn LIST + x 1 LIST + y 1
Desired Output:
PROGRAM FUNCTION foo ARGS x y BLOCK + x 1 + y 1