lisp on yarv製作日誌14
rubyのハッシュを簡単に使えるようにしてみました。
(make_hash h (("a" 10) ("b" 20) ("c" 30))) (get_hash h "a") #=> 10
ちなみにマクロで書きました。
(macro (make_hash a hash_list) `(begin (rasm ,a.to_s) (rasm " = {") ,@(map (lambda (val) `(begin (macro_val_print ,(car val)) (rasm " => ") (macro_val_print ,(cadr val)) (rasm ", "))) hash_list) (rasm "}"))) (macro (gethash a key) `(begin (macro_val_print ,a) (rasm "[") (macro_val_print ,key) (rasm "]"))
macro_val_printはコンパイルしたときに、改行を行わないようにする命令です。
例えば、(gethash h "a")でmacro_val_printを使わなかった場合、
h
["a"]
のように、コンパイルされてしまいます。
このマクロ使えばruby以外の言語の生成もできそうな気がしたので試してみました。
(macro (def_c k name args *body) `(begin (macro_val_print ,k) (rasm " ") (macro_val_print ,name) (rasm "(") (macro_val_print ,(caar args)) (rasm " ") (macro_val_print ,(cadar args)) ,@(map (lambda (a) `(begin (rasm ",") (macro_val_print ,(car a)) (rasm " ") (macro_val_print ,(cadr a))))(cdr args)) (rasm ")\n") (rasm "{\n") ,@(a2l body) (rasm "}"))) (def_c int add ((int a) (int b)) (return (+ a b))) ;コンパイル結果 int add(int a, int b) { return(a+b) }
これは、なかなか楽しいですね。もう少し汎用的に使えるようなのを作るのも、
面白そうです。