方案的简单步进代码

simple stepper code for scheme

我正在使用带有列表缩写的初级语言。 我已经在以下工作了 3 天,但无济于事。

我需要编写一个名为 step 的函数来消耗 以 AExp 的形式设计表达式 (ex),并生成一个 AExp,表示 ex

的跟踪中的下一步

示例: 如果 (ex) ex1 是
(+ 5 (* (+ 1 2 3) 2 (* 4 1)) 7)

然后(步骤 ex1)产生: (+ 5 (* 6 2 (* 4 1)) 7).

到目前为止,这就是我所做的:

(define (step ex)
 (cond [(number? ex) (list  ex)]
       [else
     (cond
       [(symbol=? (ainode-op ex) '+)
          (cons(ainode-op ex)
                  (list-eval1 (ainode-args ex)))]
       [(symbol=? (ainode-op ex) '*)
          (cons(ainode-op ex)
                  (list-eval2 (ainode-args ex)))])]))

(define (list-eval1 exlist)
             (cond [(empty? exlist)(list 0)]
                   [else (append(step (first exlist))
                         (list-eval1 (rest exlist)))]))



      (define (list-eval2 exlist)
              (cond [(empty? exlist)(list 0)]
                    [else (append(step (first exlist))
                    (list-eval2 (rest exlist)))]))

但是我的功能没有按我想要的方式工作。 有帮助吗?

这是一个提示。首先你应该注意,当一个表达式只包含一个符号和一个或多个数字时,它可以被评估。所以你可以定义一个辅助函数 evaluable? 当它的参数是一个可以计算的表达式时 returns 为真。例如:

(define (evaluable? exp)
  (cond ((null? exp) #t)
        ((list? (car exp)) #f)
        (else (evaluable? (cdr exp)))))

然后您可以定义 step 来计算第一个(子)表达式的可计算值并重建表达式的其余部分。在伪代码中,是这样的:

(define (step exp)
  (cond ((number? exp) exp)
        ((evaluable exp) (evaluate exp))
        (else (... make a recursive descent in the current expression by rebuilding the external expression...))))

当然 evaluate 应该评估包含运算符和数字操作数的列表。

编辑

如何下楼? step 的最后一行可能是这样的:

(else (cons (car exp) (step-operands (cdr exp))))))

注意,我们使用cons来重建与car相同的结构,并通过函数step-operands处理操作数的结果,找到第一个可以重写的表达式的操作数。由于这是作业,我只会给你一个这样的函数的草图(注意我假设列表 operands 至少有一个元素,不检查表达式的正确性):

(define (step-operands operands)
  (cond ((number? (car operands)) (cons (car operands) (... (cdr operands))))
        (else (cons (... (car operands))(cdr operands)))))

您只需用适当的函数填充点(并思考发生了什么!)