スキームでインタープリターを実装しようとしています。今のところ、その一部を実装しましたが、「if」ステートメントに問題があります。文法は次のとおりです。
<s6> -> <expr>
| <define>
<define> -> ( define IDENT <expr> )
<expr> -> NUMBER
| IDENT
| <if>
<if> -> ( if <expr> <expr> <expr> )
これまでに書いたコードは次のとおりです。
(define get-operator (lambda (op-symbol)
(cond
((equal? op-symbol '+) +)
((equal? op-symbol '-) -)
((equal? op-symbol '*) *)
((equal? op-symbol '/) /)
(else (error "s6-interpret: operator not implemented -->" op-symbol)))))
(define if-stmt? (lambda (e)
(and (list? e) (equal? (car e) 'if) (= (length e) 4))))
(define define-stmt? (lambda (e)
(and (list? e) (equal? (car e) 'define) (symbol? (cadr e)) (= (length e) 3))))
(define get-value (lambda (var env)
(cond
((null? env) (error "s6-interpret: unbound variable -->" var))
((equal? (caar env) var) (cdar env))
(else (get-value var (cdr env))))))
(define extend-env (lambda (var val old-env)
(cons (cons var val) old-env)))
(define repl (lambda (env)
(let* (
(dummy1 (display "cs305> "))
(expr (read))
(new-env (if (define-stmt? expr)
(extend-env (cadr expr) (s6-interpret (caddr expr) env) env)env))
(val (if (define-stmt? expr)
(cadr expr)
(s6-interpret expr env)))
(dummy2 (display "cs305: "))
(dummy3 (display val))
(dummy4 (newline))
(dummy4 (newline)))
(repl new-env))))
(define s6-interpret (lambda (e env)
(cond
((number? e) e)
((symbol? e) (get-value e env))
((not (list? e)) (error "s6-interpret: cannot evaluate -->" e))
(if-stmt? e) (if (eq? (cadr e) 0) (map s6-interpret (cadddr e)) (map s6-interpret(caddr e))))
(else
(let ((operands (map s6-interpret (cdr e) (make-list (length (cdr e)) env)))
(operator (get-operator (car e))))
(apply operator operands))))))
(define cs305-interpreter (lambda () (repl '())))
define ステートメントはうまく機能します。私のコードには、いくつかの基本的な数学演算子の実装も含まれていますが、それらは無視できます。私の問題は、実装した「if」ステートメントが期待どおりに機能しないことです。「(if 1(+ 2 5)9)」と書くと(+ 2 5)と出力されますが、実際には2 + 5である7と出力したいのです。私の再帰に問題があると思います。誰でもこれで私を助けることができますか?
ありがとうございました