最新 RSS

tips@free BLOG

レトロなマイコン、電子工作、PCやフリーソフト関係のTipsと私的備忘録

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でコンパイル)

コメント
お名前 コメント