続・凄い人見つけた
回答 (Lispのひび)
早速回答をもらえました。
ありがとうございます。
> でも、Cで書くなら、再帰呼び出しに頼らず、自分でスタックを持った方がいいかもしれません。
これはどういう意味なのでしょうか。うーん、ちょっと分かりません。
私のcygwin上での動作ですが
$ cat test.c
#include <stdio.h>
#include <stdlib.h>
void muda_rec(int n)
{
if (n > 0) {
muda_rec(n - 1);
}
}
int main(int argc, char **argv)
{
if (argc != 2) {
printf("Usage: %s number\n", argv[0]);
return 1;
}
muda_rec(atoi(argv[1]));
printf("hello world\n");
return 0;
}
$ gcc test.c
$ ./a 100000
hello world
$ ./a 1000000
$
再帰呼び出しをやりすぎると動作がおかしくなるのがわかります。
(本来表示されるはずの”hello world”が表示されずにプログラムが終了してます)
mallocなどで大きな配列を確保し、それをスタックとして利用すれば再帰呼び出しを使わずに
ループとしてプログラムを書けるのでこの問題を回避できます。
(もっとも、上のプログラムの場合はスタックを使う必要もありませんが…)
もちろん、配列を使い切るという可能性もありますが、配列のサイズは自分で分かっているため、
使い切った場合はエラーメッセージを出したり、reallocで領域を追加で確保できます。
neg、+-*/関数の実装を終えた。引数列から数値のみ取り出す関数などに分離したら簡潔に書けた。
関数宣言の部分をそのまま引用します。どんな関数が実装されているか分かると思うので。add_func("quit", quit, type_subr); add_func("car", func_car, type_subr); add_func("cdr", func_cdr, type_subr); add_func("cons", func_cons, type_subr); add_func("eq", func_eq, type_subr); add_func("?atom", func_isatom, type_subr); add_func("==", func_iseq, type_subr); add_func("=", func_set, type_fsubr); add_func("define", func_define, type_fsubr); add_func("neg", func_neg, type_subr); add_func("+", func_add, type_subr); add_func("-", func_sub, type_subr); add_func("*", func_mul, type_subr); add_func("/", func_div, type_subr);(T216の関数)
type_subrとtype_fsubrのあたりに感動しました。結婚してください(笑)
それにしても関数の名前がなんだか独特ですね。
?atom という名前は少し変な気がします。?をつけるなら普通は atom? でしょう。
(ただ、そうするのであれば、 eq も eq? にすべきでしょう。)
関数導入は(define A (B) C)ならアトムAに関数ポインタとして(lambda (B) C)を代入します。タイプはexpr(引数評価型)です。
==関数は内部までしっかり等しいかをチェックします。eqのようにアドレスが同じだけで判断しません。
(T216関数追加)
上の説明を読む限り、defineは関数定義専用なんでしょうか。
それなら普通はdefunという名前を使います(上の引数の使い方もdefunと一致しますし)。
変数と関数の名前空間が同一であれば、Schemeのdefineと同様に、
関数と変数両方の定義に使えると面白いかと思います。
それから、==に関しては、
(== ‘(a b c) ‘(a b c)) => t
ということなんでしょうか。
それならequalという名前を使うのが一般的かと思います。
(eq 'a 'a) => t (eq 1 1) => 未定義 (eql 1 1) => t (eql '(a b c) '(a b c)) => 未定義 (equal '(a b c) '(a b c)) => t
といったように、名前が長くなるにつれてチェックが細かくなります。
とにかく、ひとまず完成したようで何よりです。
これからも頑張って下さい。応援してます。