Я сделал интерпретатор схемы, и у меня есть проблема при отображении ошибок?
Я реализовал интерпретатор схемы.Все работает нормально, но я не смог напечатать сообщение об ошибке.Я объявил процедуру с именем cs305, которая запустит шоу при вызове. Он не принимает никаких аргументов и не должен. В каждой итерации моего REPL я должен распечатать приглашение, затем принять входные данные от пользователя, затем оценить значение входного выражения и, наконец, распечатать значение, вычисленное с помощью приглашения значения. Сообщение об ошибке может быть любым. Однако он должен появиться в той же строке, что и приглашение value cs305:.My проблема заключается только в отображении сообщения об ошибке.
Выход должен быть,
<pre>1 ]=> (cs305) cs305> 3 cs305: 3 cs305> (define x 5) cs305: x cs305> x cs305: 5 cs305> (define y 7) cs305: y cs305> y cs305: 7 cs305> (+ x y) cs305: 12 cs305> (+ x y (- x y 1) (* 2 x y ) (/ y 7)) cs305: 80 cs305> (if x (+ x 1) (* x 2)) cs305: 6 cs305> (if (- 5 x) (+ x 1) (* x 2)) cs305: 10 cs305> (cond (0 (+ x 1)) ((* y 0 ) (/ y 0)) ((- y (+ x 5)) (* x y)) (else -1) ) cs305: 35 5 Scheme Interaction (cont’d) cs305> (cond (0 (+ x 1)) ((* y 0 ) (/ y 0)) ((- y (+ x 2)) (* x y)) (else -1) ) cs305: -1 cs305> (define z (let ((x 1) (y x)) (+ x y))) cs305: z cs305> z cs305: 6 cs305> (define z (let* ((x z) (y x)) (if (- (/ y 2) 3) (+ x z) (- z (/ x 3))))) cs305: z cs305> z cs305: 4 cs305> (let ((x 1)) (+ x y z)) cs305: 12 cs305> (let () (+ x y z)) cs305: 16 cs305> (define 1 y) cs305: ERROR cs305> (def x 1) cs305: ERROR cs305> t cs305: ERROR cs305> (if 1 2) cs305: ERROR cs305> (if 1) cs305: ERROR cs305> (if) cs305: ERROR 6 Scheme Interaction (cont’d) cs305> (cond) cs305: ERROR cs305> (cond 1) cs305: ERROR cs305> (cond 1 2) cs305: ERROR cs305> (cond 1 2 3) cs305: ERROR cs305> (cond (1 2) (1 3) (2 4)) cs305: ERROR cs305> (cond (1 2) (else 3) (else 4)) cs305: ERROR cs305> (cond (else 3) (3 4)) cs305: ERROR cs305> (let (x 3) (y 4) (+ x y)) cs305: ERROR cs305> (let ((x)) (+ x y)) cs305: ERROR cs305> (let (()) (+ x y)) cs305: ERROR
Это длинный вывод, извините за длину, но я хотел бы объяснить каждую деталь.Я могу обрабатывать выходы, которые не дают ошибок.Но у меня есть проблема с отображением ошибки.
Что я уже пробовал:
<pre><pre>(define get-operator (lambda (op-symbol env) (cond ((equal? op-symbol '+) +) ((equal? op-symbol '-) -) ((equal? op-symbol '*) *) ((equal? op-symbol '/) /) (else (get-value op-symbol env)) ))) (define if-stmt? (lambda (e) (and (list? e) (equal? (car e) 'if) (= (length e) 4)))) (define letstar-stmt? (lambda (e) (and (list? e) (equal? (car e) 'let*) (= (length e) 3)))) (define let-stmt? (lambda (e) (and (list? e) (equal? (car e) 'let) (= (length e) 3)))) (define define-stmt? (lambda (e) (and (list? e) (equal? (car e) 'define) (symbol? (cadr e)) (= (length e) 3)))) (define formal-list? (lambda (e) (and (list? e) (symbol? (car e)) (or (null? (cdr e)) (formal-list? (cdr e)))))) (define lambda-short-stmt? (lambda (e) (and (list? e) (equal? (car e) 'lambda) (formal-list? (cadr e)) (not (define-stmt? (caddr e)))))) (define is-normal? (lambda (o) (cond ((eq? o '+) #t) ((eq? o '-) #t) ((eq? o '/) #t) ((eq? o '*) #t) (else #f) ))) (define get-value (lambda (var env) (cond ((null? env) (display "cs305: error")) ((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) (s8-hw5 (caddr expr) env) env) env)) (val (if (define-stmt? expr) (cadr expr) (s8-hw5 expr env))) (dummy2 (display "cs305: ")) (dummy3 (display val)) (dummy4 (newline)) (dummy4 (newline))) (repl new-env)))) (define s8-hw5 (lambda (e env) (cond ((number? e) e) ((symbol? e) (get-value e env)) ((not (list? e)) (error "s8-hw5: cannot evaluate -->" )) ((if-stmt? e) (if (eq? (s8-hw5 (cadr e) env) 0) ( s8-hw5 (cadddr e) env) ( s8-hw5 (caddr e) env))) ((let-stmt? e) (let ((names (map car (cadr e))) (inits (map cadr (cadr e)))) (let ((vals (map (lambda (init) (s8-hw5 init env)) inits))) (let ((new-env (append (map cons names vals) env))) (s8-hw5 (caddr e) new-env))))) ((letstar-stmt? e) (if (= (length (cadr e)) 1) ;if the second element is of length 1, (second element is the one right after the let*) take different action. (let ((l (list 'let (cadr e) (caddr e)))) (let ((names (map car (cadr l))) (inits (map cadr (cadr l)))) ;make the list, consisting of let, 2nd element and 3rd element. ;and let it be the normal let statement. notice that rest is the same with original let statement. (let ((vals (map (lambda (init) (s8-hw5 init env)) inits))) (let ((new-env (append (map cons names vals) env))) (s8-hw5 (caddr l) new-env))))) (let ((first (list 'let (list (caadr e)))) (rest (list 'let* (cdadr e) (caddr e)))) ;now since length is not 1, it is a list; then treat differently. (let ((l (append first (list rest)))) (let ((names (map car (cadr l))) (inits (map cadr (cadr l)))) (let ((vals (map (lambda (init) (s8-hw5 init env)) inits))) (let ((new-env (append (map cons names vals) env))) (s8-hw5 (caddr l) new-env)))))))) ((lambda-short-stmt? e) e) (else (cond ((lambda-short-stmt? (car e)) (if (= (length (cadar e)) (length (cdr e))) (let* ((par (map s8-hw5 (cdr e) (make-list (length (cdr e)) env))) (nenv (append (map cons (cadar e) par) env))) (s8-hw5 (caddar e) nenv)) (error "s8-hw5: Total number of formal parameters and actual parameters do not match!"))) ;if normal math operators, different measures should be taken; for the exceptions etc. ((is-normal? (car e)) (let ((operands (map s8-hw5 (cdr e) (make-list (length (cdr e)) env))) (operator (get-operator (car e) env))) (cond ;for the exceptions, write the cases ((and (equal? operator '+) (= (length operands) 0)) 0) ;if no operands in addition, it is 0. ((and (equal? operator '*) (= (length operands) 0)) 1) ;if no operands in multiplication, it is 1. ((and (or (equal? operator '-) (equal? operator '/)) (= (length operands) (or 0 1))) (error "s8-hw5: It needs at least two operands for this operator -->" operator)) (else (apply operator operands)) ))) (else (let* ((result (s8-hw5 (list (get-value (car e) env) (cadr e)) env))) result)) ) )))) (define cs305 (lambda () (repl '())))
Это то, что я пробовал, но до сих пор я не могу отображать ошибки.