趣味で作った小規模な Lisp インタプリタ
Ruby の method_missing
と const_missing
を利用すると変数名自体でプログラミングが可能。
とりあえず簡単な関数定義まで実装した。
$ gem install missinglisp
$ irb
irb(main):001> require 'missinglisp'
=> true
irb(main):002> Lquote_hello_world_J
=> [:hello, :world]
irb(main):003> Ladd_1_2_3J
=> 6
irb(main):004> Ldefine_fibonacci_Llambda_Ln_J_Lif_Lleq_n_2J_1_Ladd_Lfibonacci_Lsub_n_2JJ_Lfibonacci_Lsub_n_1JJJJJJ
=> []
irb(main):005> Lfibonacci_10J
=> 55
次の変数名を評価すると足し算と引き算からなる計算を標準入力から読み取り、結果を出力する。
Ldefine_or_Llambda_La_b_J_Lif_a_t_Lif_b_t_nil_JJJJLdefine_and_Llambda_La_b_J_Lif_a_Lif_b_t_nil_Jnil_JJJLdefine_isDigit_Llambda_Lc_J_Land_Lleq_LcodeChar_48J_c_J_Lleq_c_LcodeChar_57JJJJJLdefine_isPlus_Llambda_Lc_J_Leq_LcodeChar_43Jc_JJJLdefine_isMinus_Llambda_Lc_J_Leq_LcodeChar_45Jc_JJJLdefine_toNum_Llambda_Lc_J_Lsub_LcharCode_c_J_48JJJLdefine_loop_Llambda_Linput_len_i_cur_cursign_sum_JLif_Lleq_len_i_J_Ladd_Lmult_cursign_cur_J_sum_J_Lif_LisPlus_Laref_input_i_JJ_Lloop_input_len_Ladd_i_1J_0_1_Ladd_Lmult_cursign_cur_J_sum_JJ_Lif_LisMinus_Laref_input_i_JJ_Lloop_input_len_Ladd_i_1J_0_Lsub_0_1J_Ladd_Lmult_cursign_cur_J_sum_JJ_Lif_LisDigit_Laref_input_i_JJ_Lloop_input_len_Ladd_i_1J_Ladd_Lmult_10_cur_J_LtoNum_Laref_input_i_JJJ_cursign_sum_J_Lloop_input_len_Ladd_i_1J_cur_cursign_sum_JJJJJJJLdefine_main_Llambda_LJLprogn_LwriteLine_QInput_expressionQJLprinc_LcodeChar_62JJLprinc_Q_QJLdefine_input_LreadLine_JJLdefine_len_Llength_input_JJLif_Leq_len_0JLwriteLine_QexitQJ_Lprogn_Ldefine_sum_Lloop_input_len_0_0_1_0JJLwriteLine_sum_JLmain_JJJJJJLmain_J
$ ruby -rmissinglisp -e Ldefine_or_Llambda_La...(略)...
Input expression
> 12 + 3 - 4
11
Input expression
> -5 + 18
13
Input expression
>
exit