I'm trying to write an interpreter for a simple programming language in Scheme. Right now, I'm writing a procedure to handle while-loops with break statements. To approach this problem, I'm using call/cc.
When the language is parsed, it looks like this:
var x = 0;
while (x < 10) {
x = x - 1;
break;
x = x + 100;
}
return x;
turns into
((var x 0) (while (< x 10) (begin (= x (- x 1)) (break) (= x (+ x 100)))) (return x))
My approach to interpreting these statements is as follows:
(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)
Where (M_State statement state) returns the current state updated to reflect statement (e.g. the state ((x) (2)) represents x = 2. (M_State '(var x 5) '((x) (2))) would return ((x) (5)).)
When I put this through the debugger, the line ((null? body_line) (second-break-cont state)) always calls upon second-break-cont, even though body_line is not null. I've spent a lot of time debugging this, but can't seem to find the error. Any help in spotting my mistake would be greatly appreciated.
答案 0 :(得分:1)
我没有详细研究过你的代码,但我注意到了一件事。您的主函数和外部循环都有一个名为cond
的参数。这将遮蔽您尝试在内循环中使用的内置cond
宏。
事实上,仅此一点就可以解释为什么总是会调用(second-break-cont state)
。 cond
表达式不再是宏调用,而是普通的函数调用,因此会对所有表达式进行求值。
您应该将参数调用为cond
以外的其他参数。