为解释器评估 While 循环
Evaluating While Loop for Interpreter
所以我熟悉其他语言的 while 循环,但在 Racket 中无法使用它。我能够完成的最好的事情是让循环进入 运行 一次(更像是一个 if 语句)或者进入无限循环。
这是 运行ning 一次的代码:
;; 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)]
请让我知道是否还应该包含它们的定义。
额外的评估赋值:
(define (eval-assign var exp env)
(cons (car(evaluate exp env))(hash-set env var (car(evaluate exp env))))
)
约定俗成的所有求值函数return都是值与环境的一对吗?如果是这样,那么这可能有效:
(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
的来源,我可以看到环境表示为 immutable 哈希 table。因此循环需要使用新的环境。
试试这个:
(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)
,检查环境是否更新。
所以我熟悉其他语言的 while 循环,但在 Racket 中无法使用它。我能够完成的最好的事情是让循环进入 运行 一次(更像是一个 if 语句)或者进入无限循环。
这是 运行ning 一次的代码:
;; 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)]
请让我知道是否还应该包含它们的定义。
额外的评估赋值:
(define (eval-assign var exp env)
(cons (car(evaluate exp env))(hash-set env var (car(evaluate exp env))))
)
约定俗成的所有求值函数return都是值与环境的一对吗?如果是这样,那么这可能有效:
(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
的来源,我可以看到环境表示为 immutable 哈希 table。因此循环需要使用新的环境。
试试这个:
(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)
,检查环境是否更新。