Click here to Skip to main content
14,928,120 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I implemented a Scheme interpreter.Everything is working fine but i couldn't manage to print error message.I declared a procedure named cs305 which will start the show when called. It don't takes any arguments and it shouldn't. In every iteration of my REPL, i should print out the prompt then accept an input from the user, then evaluate the value of the input expression, and finally print the value evaluated by using a value prompt. ERROR message can be anything. However it should appears on the same line as the value prompt cs305:.My problem is only on displaying the error message.
Output should be,
<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


It is a long output sorry for the lenght but i wanted to explain every detail.I can handle the outputs which are not giving errors.But i have a problem with displaying error.

What I have tried:

<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 '())))

This is what i tried but still i cannot displaying errors.
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900