csvrn80 Ответов: 0

Я сделал интерпретатор схемы, и у меня есть проблема при отображении ошибок?


Я реализовал интерпретатор схемы.Все работает нормально, но я не смог напечатать сообщение об ошибке.Я объявил процедуру с именем 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 '())))

Это то, что я пробовал, но до сих пор я не могу отображать ошибки.

0 Ответов