0

我正在尝试在 Scheme 中为一种简单的编程语言编写解释器。现在,我正在编写一个程序来处理带有 break 语句的 while 循环。为了解决这个问题,我使用了 call/cc。

解析语言时,它看起来像这样:

var x = 0;
while (x < 10) {
  x = x - 1;
  break;
  x = x + 100;
}
return x;

变成

((var x 0) (while (< x 10) (begin (= x (- x 1)) (break) (= x (+ x 100)))) (return x))

我解释这些陈述的方法如下:

(define while_break
  (lambda (cond body state)
    (call/cc
     (lambda (break-cont)
       (letrec
           ((Mstate_loop (lambda (cond body state)
                         ; Need second loop
                         (if (eq? (M_Bool cond state) #t)
                             (call/cc
                              (lambda (second-break-cont)
                                (letrec
                                  ((Body_loop (lambda (body_line state)
                                                (cond
                                                  ((null? body_line) (second-break-cont state))
                                              ; Conditions to exit the loop
                                              ((eq? (first_line body_line) 'break) (second-break-cont state))
                                              ; If this is the last line, run it and break
                                              ((null? (rest_of_lines body_line)) (second-break-cont (M_State body_line state)))
                                              ; Otherwise, run the next line
                                              (else (Body_loop (rest_of_lines body_line) (M_State (first_line body_line) state)))))))
                            (Body_loop body state))))
                          (break-cont state)
                          ))))
        (Mstate_loop cond body state))
     ))))


(define first_line car)
(define rest_of_lines cdr)

其中 (M_State 语句 state) 返回当前状态更新以反映语句(例如状态 ((x) (2)) 表示 x = 2。 (M_State '(var x 5) '((x) (2))) 将返回((x)(5))。)

当我将它通过调试器时,行 ((null?body_line) (second-break-cont state)) 总是调用 second-break-cont,即使 body_line 不为空。我花了很多时间调试这个,但似乎找不到错误。任何帮助发现我的错误将不胜感激。

4

1 回答 1

1

我没有详细研究过你的代码,但我注意到了一件事。你有一个cond为你的主函数和外循环命名的参数。cond这将隐藏您尝试在内部循环中使用的内置宏。

事实上,仅此一项就可以解释为什么(second-break-cont state)总是调用 your 。cond表达式不再是宏调用,而是普通的函数调用,所以里面的所有表达式都被求值。

您应该将参数称为cond.

于 2016-03-05T02:26:31.493 回答