Created
October 22, 2012 13:12
-
-
Save b0oh/3931450 to your computer and use it in GitHub Desktop.
meta circular eval
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (define (mceval 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-sequnce (begin-actions exp) env)) | |
| ((cond? exp) (mceval (cond->if exp) env)) | |
| ((application? exp) | |
| (mcapply (mceval (operator exp) env) | |
| (list-of-values (operands exp) env))) | |
| (else | |
| (error "Unknown expression type -- EVAL" exp)))) | |
| (define (mcapply proc args) | |
| (cond ((primitive-procedure? proc) | |
| (apply-primitive-procedure proc args)) | |
| ((compound-procedure? proc) | |
| (eval-sequnce | |
| (procedure-body proc) | |
| (extend-environment | |
| (procedure-parameters proc) | |
| args | |
| (procedure-environment proc)))) | |
| (else | |
| (error "Unknown procedure type -- APPLY" proc)))) | |
| (define (tagged-list? exp tag) | |
| (if (pair? exp) | |
| (eq? (car exp) tag) | |
| false)) | |
| (define (list-of-values exps env) | |
| (if (no-operands? exps) | |
| '() | |
| (cons (mceval (first-operand exps) env) | |
| (list-of-values (rest-operands exps) env)))) | |
| (define (eval-sequence exps env) | |
| (cond ((last-exp? exps) (mceval (first-exp exps) env)) | |
| (else (mceval (first-exp exps) env) | |
| (eval-sequence (rest-exps exps) env)))) | |
| (define (last-exp? seq) (null? (cdr seq))) | |
| (define (first-exp seq) (car seq)) | |
| (define (rest-exps seq) (cdr seq)) | |
| ;; numbers and strings | |
| (define (self-evaluating? exp) | |
| (cond ((number? exp) true) | |
| ((string? exp) true) | |
| (else false))) | |
| ;; variable | |
| (define (variable? exp) (symbol? exp)) | |
| ;; quote | |
| (define (quoted? exp) (tagged-list? exp 'quote)) | |
| (define (text-of-quotation exp) (cadr exp)) | |
| ;; asignment | |
| (define (assignment? exp) | |
| (tagged-list? exp 'set!)) | |
| (define (eval-assignment exp env) | |
| (set-variable-value! (assignment-variable exp) | |
| (mceval (assignment-value exp) env) | |
| env) | |
| 'ok) | |
| (define (assignment-variable exp) (cadr exp)) | |
| (define (assignment-value exp) (caddr exp)) | |
| ;; definition | |
| (define (definition? exp) (tagged-list? exp 'define)) | |
| (define (eval-definition exp env) | |
| (define-variable! (definition-variable exp) | |
| (mceval (definition-value exp) env) | |
| env) | |
| 'ok) | |
| (define (definition-variable exp) | |
| (if (symbol? (cadr exp)) | |
| (cadr exp) | |
| (caadr exp))) | |
| (define (definition-value exp) | |
| (if (symbol? (cadr exp)) | |
| (caddr exp) | |
| (make-lambda (cdadr exp) | |
| (cddr exp)))) | |
| ;; if | |
| (define (if? exp) (tagged-list? exp 'if)) | |
| (define (if-predicate exp) (cadr exp)) | |
| (define (if-consequent exp) (caddr exp)) | |
| (define (if-alternative exp) | |
| (if (not (null? (cdddr exp))) | |
| (cadddr exp) | |
| 'false)) | |
| (define (make-if pred conseq alter) | |
| (list 'if pred conseq alter)) | |
| (define (eval-if exp env) | |
| (if (true? (mceval (if-predicate exp) env)) | |
| (mceval (if-consequent exp) env) | |
| (mceval (if-alternative exp) env))) | |
| (define (true? x) (not (eq? x false))) | |
| (define (false? x) (eq? x false)) | |
| ;; lambda | |
| (define (lambda? exp) (tagged-list? exp 'lambda)) | |
| (define (lambda-parameters exp) (cadr exp)) | |
| (define (lambda-body exp) (cddr exp)) | |
| (define (make-lambda parameters body) | |
| (cons 'lambda (cons parameters body))) | |
| ;; begin | |
| (define (begin? exp) (tagged-list? exp 'begin)) | |
| (define (begin-actions exp) (cdr exp)) | |
| (define (sequence->exp seq) | |
| (cond ((null? seq) seq) | |
| ((last-exp? seq) (first-exp seq)) | |
| (else (make-begin seq)))) | |
| (define (make-begin seq) (cons 'begin seq)) | |
| ;;cond | |
| (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-extended-clause? clause) | |
| (eq? '=> (car (cond-actions clause)))) | |
| (define (cond-predicate clause) | |
| (car clause)) | |
| (define (cond-actions clause) | |
| (cdr clause)) | |
| (define (cond-extended-action clause) | |
| (cadr (cond-actions 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 "ELSE clause not last -- COND->IF" clauses)) | |
| (if (cond-extended-clause? first) | |
| (make-if (cond-predicate first) | |
| (list (cond-extended-action first) | |
| (cond-predicate first)) | |
| (expand-clauses rest)) | |
| (make-if (cond-predicate first) | |
| (sequence->exp (cond-actions first)) | |
| (expand-clauses rest))))))) | |
| ;; application | |
| (define (application? exp) (pair? exp)) | |
| (define (operator exp) (car exp)) | |
| (define (operands exp) (cdr exp)) | |
| (define (no-operands? ops) (null? ops)) | |
| (define (first-operand ops) (car ops)) | |
| (define (rest-operands ops) (cdr ops)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment