Scheme 为解释器计算While循环

Scheme 为解释器计算While循环,scheme,racket,Scheme,Racket,所以我熟悉其他语言中的while循环,但在Racket中很难使用它。我所能做到的最好的事情就是让循环运行一次(更像是if语句),或者运行一个无限循环 以下是运行一次的代码: ;; Evaluates a loop. ;; When the condition is false, return 0. ;; There is nothing special about zero -- we just need to return something. (define (eval-while c bo

所以我熟悉其他语言中的while循环,但在Racket中很难使用它。我所能做到的最好的事情就是让循环运行一次(更像是if语句),或者运行一个无限循环

以下是运行一次的代码:

;; Evaluates a loop.
;; When the condition is false, return 0.
;; There is nothing special about zero -- we just need to return something.
(define (eval-while c body env)
  (if (false?(car(evaluate c env)))
    (cons 0 env)
    (evaluate body env))
)
下面是我对无限循环的另一次尝试:

 (define (eval-while c body env)
   (if (evaluate c env)
     (eval-while c body (cdr(evaluate body env)))
     (cons 0 env))
 )
下面是一些其他可能相关的代码(解释器部分):

任何帮助都非常感谢

编辑:

下面是代码的更完整版本

测试用例:

(evaluate (sp-seq (sp-assign "x" (sp-val 0))
      (sp-seq (sp-assign "y" (sp-val 10))
      (sp-while (sp-binop < (sp-var "x") (sp-var "y"))
                (sp-assign "x" (sp-binop + (sp-var "x") (sp-val 1))))
      ))
      empty-env) ;'(0 . #hash(("y" . 10) ("x" . 10)))
请让我知道我是否也应该包括他们的定义

额外添加评估分配:

(define (eval-assign var exp env)
  (cons (car(evaluate exp env))(hash-set env var (car(evaluate exp env)))) 
)

是所有计算器函数返回一对值和环境的约定吗?如果是这样,那么这可能会起作用:

(define (eval-while c body env)
   (if (evaluate c env)                           ; if c is true
       (begin                                     ; then
         (evaluate body env)                      ;   1) evaluate body
         (eval-while c body env))                 ;   2) loop 
                                                  ; else
       (cons 0 env)))                             ;   return 0  (and environment)
请注意,调用
(eval while c body env)
是尾部调用。这意味着不需要构建评估上下文

更新

eval assign
的源代码中,我可以看到环境被表示为一个不可变的哈希表。因此,循环需要使用新的环境

试试这个:

(define (eval-while c body env)
   (if (evaluate c env)                           ; if    c is true
       (match (evaluate body env)                 ; then  evaluate body
         [(cons value new-env)                    ;       grab the new environment
          (eval-while c body new-env)])           ;       loop using new env   
       (cons 0 env)))                             ; return 0  (and environment)

另外:在
eval while
中插入
(displayln env)
,以检查环境是否已更新

谢谢你的回复。不幸的是,在我的例子中,这仍然是一个无限循环。我不想在文章中充斥大量的代码,所以我试图发布最基本的代码,但我会添加更多的代码。具体来说,填写无限循环的测试用例。感谢您提供更新的答案!它仍在无限期地运行,但环境正在得到更新。似乎条件的计算结果永远不会为false。x超过y(10)并继续前进。但也许这是一个足够好的开始,让我试着自己解决剩下的问题。除非你能马上想到为什么会这样。@aurora91哦!如果evaluate在条件为false时返回
(cons#f an env)
,那么您需要将
(If(evaluate c env)…)
更改为
(If(car(evaluate c env))…)
您太棒了!非常感谢您详细的回答!这些评论对我们来说是一个巨大的帮助。我一定会进一步研究这一点,以确保我将来能够自己完成。环境
env
是否发生了变化,或者您是否为每个计算器函数创建了一个新的env?包括
eval assign
的源代码。我将其添加到了中。我相信这个环境是不可变的,因为它在顶部被定义为一个不可变的散列。
(define (eval-while c body env)
   (if (evaluate c env)                           ; if c is true
       (begin                                     ; then
         (evaluate body env)                      ;   1) evaluate body
         (eval-while c body env))                 ;   2) loop 
                                                  ; else
       (cons 0 env)))                             ;   return 0  (and environment)
(define (eval-while c body env)
   (if (evaluate c env)                           ; if    c is true
       (match (evaluate body env)                 ; then  evaluate body
         [(cons value new-env)                    ;       grab the new environment
          (eval-while c body new-env)])           ;       loop using new env   
       (cons 0 env)))                             ; return 0  (and environment)