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.