diff --git a/ch4/ex4-2.scm b/ch4/ex4-2.scm index b5e5ae0..c2f614d 100644 --- a/ch4/ex4-2.scm +++ b/ch4/ex4-2.scm @@ -2,4 +2,34 @@ ;; Example 4.2 -;; trying to apply (define) func. But define is the special case. \ No newline at end of file +;; a. trying to apply (define) func. But define is the special case. + +;; b. + +(define (eval exp env) + (cond ((self-evaluating? exp) exp) + ((variable? exp) (lookup-variable-value exp env)) + ((quoted? exp) (text-of-quotation exp)) + ((application? exp) + (apply (eval (operator exp) env) ;; apply procedure (proc, args) + (list-of-values (operands exp) env))) + ((assignment? exp) (eval-assignment exp env)) + ((definition? exp) (eval-definition exp env)) + ((if? exp) (eval-if exp env)) + ((lambda? exp) + (make-procedure (lambda-parameters exp) + (lambda-body exp) + env)) + ((begin? exp) + (eval-sequence (begin-actions exp) env)) + ((cond? exp) (eval (cond->if exp) env)) + (else + (error "Unknown expression type -- EVAL" exp)))) + +;; procedure invocation +(define (application? exp) (tagged-list? exp 'call)) +(define (operator exp) (cadr exp)) +(define (operands exp) (cddr exp)) +(define (no-operands? ops) (null? ops)) +(define (first-operand ops) (car ops)) +(define (rest-operands ops) (cdr ops)) \ No newline at end of file diff --git a/ch4/ex4-3.scm b/ch4/ex4-3.scm new file mode 100644 index 0000000..6f1f7b4 --- /dev/null +++ b/ch4/ex4-3.scm @@ -0,0 +1 @@ +#lang racket diff --git a/ch4/ex4-4.scm b/ch4/ex4-4.scm new file mode 100644 index 0000000..960d860 --- /dev/null +++ b/ch4/ex4-4.scm @@ -0,0 +1,47 @@ +#lang racket + +;; Example 4.4 + +;; not sure need testing + +(define (eval exp env) + (cond ((self-evaluating? exp) exp) + ((variable? exp) (lookup-variable-value exp env)) + ((quoted? exp) (text-of-quotation exp)) + ((assignment? exp) (eval-assignment exp env)) + ((definition? exp) (eval-definition exp env)) + ((if? exp) (eval-if exp env)) + + ((and? exp) (eval-and (and-operands exp) env)) + ((or? exp) (eval-or (or-operands exp) env)) + + ((lambda? exp) + (make-procedure (lambda-parameters exp) + (lambda-body exp) + env)) + ((begin? exp) + (eval-sequence (begin-actions exp) env)) + ((cond? exp) (eval (cond->if exp) env)) + ((application? exp) + (apply (eval (operator exp) env) ;; apply procedure (proc, args) + (list-of-values (operands exp) env))) + (else + (error "Unknown expression type -- EVAL" exp)))) + +;; and + +(define (and? exp) (tagged-list? exp 'and)) +(define (and-operands exp) (cdr exp)) +(define (eval-and exp env) + (cond ((null? exp) 'true) + ((false? (eval (car exp))) 'false) + (else (eval-and (cdr exp) env)))) + +;; or + +(define (or? exp) (tagged-list? exp 'or)) +(define (or-operands exp) (cdr exp)) +(define (eval-or exp env) + (cond ((true? (eval (car exp))) 'true) + ((null? exp) 'false) + (else (eval-or (cdr exp) env)))) \ No newline at end of file diff --git a/ch4/ex4-5.scm b/ch4/ex4-5.scm new file mode 100644 index 0000000..c387b95 --- /dev/null +++ b/ch4/ex4-5.scm @@ -0,0 +1,55 @@ +#lang racket + +;; Example 4.5 + +;; TODO + +(define (eval exp env) + (cond ((self-evaluating? exp) exp) + ((variable? exp) (lookup-variable-value exp env)) + ((quoted? exp) (text-of-quotation exp)) + ((assignment? exp) (eval-assignment exp env)) + ((definition? exp) (eval-definition exp env)) + ((if? exp) (eval-if exp env)) + ((lambda? exp) + (make-procedure (lambda-parameters exp) + (lambda-body exp) + env)) + ((begin? exp) + (eval-sequence (begin-actions exp) env)) + ((cond? exp) (eval (cond->if exp) env)) + ((application? exp) + (apply (eval (operator exp) env) ;; apply procedure (proc, args) + (list-of-values (operands exp) env))) + (else + (error "Unknown expression type -- EVAL" exp)))) + +(define (cond? exp) (tagged-list? exp 'cond)) +(define (cond-clauses exp) (cdr exp)) +(define (cond-else-clause? clause) + (eq? (cond-predicate clause) 'else)) +(define (cond-predicate clause) (car clause)) +(define (cond-actions clause) (cdr clause)) +(define (cond->if exp) + (expand-clauses (cond-clauses exp))) + +(define (expand-clauses clauses) + (if (null? clauses) + 'false + (let ((first (car clauses)) + (rest (cdr clauses))) + (if (cond-else-clause? first) + (if (null? rest) + (sequence->exp (cond-actions first)) + (error "Clause else not the last" clauses)) + (make-if (cond-predicate first) + (sequence->exp (cond-actions first)) + (expand-clauses rest)))))) + +(define (last-exp? seq) (null? (cdr seq))) +(define (first-exp seq) (car seq)) +(define (make-begin seq) (cons 'begin seq)) +(define (sequence->exp seq) + (cond ((null? seq) seq) + ((last-exp? seq) (first-exp seq)) + (else (make-begin seq)))) \ No newline at end of file