2014/01/19
■ [z80][xlisp]自作Z80 CP/Mマシン(39)
引き続き XLISPのメモ。
うまく動かない if関数を調べるために確認用の printfを追加して流れを追ったり、デバッガをかけて引数をチェックしたりとしてみましたが、どうやらソース自体が間違っていそうなので後のバージョンのソースを探して比べて見ました。
下に ver1.1と 1.2の該当部分のソースを示しますが、やはり処理が違っています、修正されたのでしょうねぇ、、
具体的には、 引数の取り出しが xlmatch(LIST, &arg.n_ptr) から xlarg(&args) へ、 引数の評価が xlevarg(thenexpr.n_ptr) から xleval(thenexpr.n_ptr) へ変わっています。
XLISP v1.1 xlsubr.c /* fif - builtin function if */ static struct node *fif(args) struct node *args; { struct node *oldstk,arg,testexpr,thenexpr,elseexpr,*val; int dothen; /* create a new stack frame */ oldstk = xlsave(&arg,&testexpr,&thenexpr,&elseexpr,NULL); /* initialize */ arg.n_ptr = args; /* evaluate the test expression */ testexpr.n_ptr = xlevarg(&arg.n_ptr); /* get the then clause */ thenexpr.n_ptr = xlmatch(LIST,&arg.n_ptr); <- 真の場合の引数を取り出し /* get the else clause */ if (arg.n_ptr != NULL) elseexpr.n_ptr = xlmatch(LIST,&arg.n_ptr); <- 偽の場合の引数を取り出し else elseexpr.n_ptr = NULL; /* make sure there aren't any more arguments */ xllastarg(arg.n_ptr); /* figure out which expression to evaluate */ dothen = testvalue(testexpr.n_ptr); /* default the result value to the value of the test expression */ val = testexpr.n_ptr; /* evaluate the appropriate clause */ if (dothen) while (thenexpr.n_ptr != NULL) val = xlevarg(&thenexpr.n_ptr); <- 真の評価 else while (elseexpr.n_ptr != NULL) val = xlevarg(&elseexpr.n_ptr); <- 偽の評価 /* restore the previous stack frame */ xlstack = oldstk; /* return the last value */ return (val); }
XLISP v1.2 xlcont.c /* xif - builtin function 'if' */ struct node *xif(args) struct node *args; { struct node *oldstk,testexpr,thenexpr,elseexpr,*val; /* create a new stack frame */ oldstk = xlsave(&testexpr,&thenexpr,&elseexpr,NULL); /* get the test expression, then clause and else clause */ testexpr.n_ptr = xlarg(&args); <- 真の場合の引数を取り出し thenexpr.n_ptr = xlarg(&args); <- 偽の場合の引数を取り出し elseexpr.n_ptr = (args ? xlarg(&args) : NULL); xllastarg(args); /* evaluate the appropriate clause */ <- 真・偽の評価 val = xleval(xleval(testexpr.n_ptr) ? thenexpr.n_ptr : elseexpr.n_ptr); /* restore the previous stack frame */ xlstack = oldstk; /* return the last value */ return (val); }
修正後は思ったとおりの結果になりました。
P>xlisp XLISP version 1.1 > (if t 1 2) 1 <- 1 が返ってくる > (if t (1)(2)) error: bad function <- エラーになる (1) (if t (1) (2))
(環境は CP/M Z80 HI-TECH C ver3.09でコンパイル)