第8講成長
oddp関数を追加するコードは次のようにしてください。
defsubr("oddp",f_oddp);
当初ここを defsubr("oddp",(int)f_oddp); としていました。これですとMacのGCCで動作しないことが判明しました。
関数ポインタの型指定を正確にし、キャストをしなくてもいいように改訂しました。
C言語ソースコードは改訂済みです。これによりWindows、Ubuntu、MacのGCCで動作することが確認できました。
書籍の本体の中で示されているコードは以前のままになっており(int)のキャストがついたままとなっていますので、ご注意ください。
出会い
誤 「僕がC言語にハマってることシズカさんがをクラスメートから聞きつけたみたいだ。」
正 「僕がC言語にハマってることをシズカさんがクラスメートから聞きつけたみたいだ。」
第4講 S式の読み取り(read)
誤 ほとんと数アトムと同じです。
正 ほとんど数アトムと同じです。
第3講 急がば回れ
誤 type 種類を示すもので次のようになっています。
正 type トークンの種類です。
第1講 Lispを動かしてみる
誤 「Fortranのに次に古い言語で」
正 「Fortranの次に古い言語で」
第2講セルの正体
誤 「C言語ですとポインタというものがあります。、」
正 「C言語ですとポインタというものがあります。」
第2講セルの正体
構造体の説明の*subrの箇所
誤 「ある部分は関数ポインタです。」
正 「この部分は関数ポインタです。」
第4講 S式の読み取り(read)
誤 「readとreadlistを読みなつつ」
正 「readとreadlistを読みつつ」
第7講 ゴミ集め
セリフ部分
誤 「僕: どいう場合なのか、想像がつきません。」
正 「僕: どういう場合なのか、想像がつきません。」
マークの説明中
途中で(g y)とい関数の計算
途中で(g y)という関数の計算
補講(eval)
ifのコードの説明の直後
誤 ほかにも(setq a 1)なんてももそうですね。
正 ほかにも(setq a 1)なんてものもそうですね。
第6講 いよいよ頭脳に着手(eval)
アトムのときのコードに無駄がありました。
if(atomp(addr)){
if(numberp(addr))
return(addr);
if(symbolp(addr)){
res = findsym(addr);
if(res == 0)
error(CANT_FIND_ERR, "eval", addr);
else
switch(GET_TAG(res)){
case NUM: return(res);
case SYM: return(res);
case LIS: return(res);
case SUBR: return(res);
case FSUBR: return(res);
case FUNC: return(res);
}
}
}
わざわざswitch文で分ける必要はありませんでした。
以下のコードで十分です。
if(atomp(addr)){
if(numberp(addr))
return(addr);
if(symbolp(addr)){
res = findsym(addr);
if(res == 0)
error(CANT_FIND_ERR, "eval", addr);
else
return(res);
}
}
第5講 おうむ返し(print)
main関数をvoid型にしていてコンパイルできているのですが、int型にする方が望ましいです。
returnで数値を返すようにすれば-Wallで警告が出ません。
int main(void){
printf("MonoLis Ver0.01\n");
initcell();
initsubr();
int ret = setjmp(buf);
repl:
if(ret == 0)
while(1){
printf("> "); fflush(stdout); fflush(stdin);
print(eval(read ()));
printf("\n"); fflush(stdout);
}
else
if(ret == 1){
ret = 0;
goto repl;
}
else
return 0;
}
第2講 セルの正体
initcell関数で配列領域をオーバーランしていました。
誤
void initcell(void){
int addr;
for(addr=0; addr <= HEAPSIZE; addr++){
heap[addr].flag = FRE;
heap[addr].cdr = addr+1;
}
正
void initcell(void){
int addr;
for(addr=0; addr < HEAPSIZE; addr++){
heap[addr].flag = FRE;
heap[addr].cdr = addr+1;
}
全ソースコード
2016年1月30日、
アップロードされている全ソースコードを修正しました。
-Wallでウォーニングをかけていなかったため、タイプミスがありました。
原型をとどめる程度に修正をしています。