首页 文章

为口译员评估While循环

提问于
浏览
1

所以我熟悉其他语言的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))
 )

这是一些其他可能相关的代码(解释器部分):

(define (evaluate prog env)
  (match prog
    [(struct sp-val (v))              (cons v env)] 
    [(struct sp-while (c body))       (eval-while c body env)]
    [_                                (error "Unrecognized expression")]))

任何帮助都非常感谢!

编辑:

这是一个更完整的代码版本 .

测试用例:

(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)))

更主要的评估:

[(struct sp-binop (op exp1 exp2)) (eval-binop op exp1 exp2 env)]
    [(struct sp-assign (var exp))     (eval-assign var exp env)]
    [(struct sp-var (varname))        (cons (hash-ref env varname) env)]

如果我还要包括他们的定义,请告诉我 .

额外增加eval-assign:

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

1 回答

  • 3

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

    (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) 是尾调用 . 这意味着没有评估上下文的累积 .

    UPDATE

    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) 以检查环境是否已更新 .

相关问题