1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| (define name -1) (define get-name (lambda () (set! name (+ name 1)) (string->symbol (string-append "val" (number->string name))))) (define deep (lambda (tree) (if (not (pair? tree)) 0 (+ 1 (deep-forest (cdr tree)))))) (define accumulate (lambda (pro lst) (if (= (length lst) 1) (pro (car lst)) (pro (car lst) (accumulate pro (cdr lst)))))) (define deep-forest (lambda (trees) (accumulate max (map deep trees))))
(define change (lambda (tree) (if (= 1 (deep tree)) (let ((name (get-name))) (list tree name name)) (let ((fro (change-forest (cdr tree)))) (let ((t (car fro)) (name (cadr fro)) (rands (caddr fro))) (list t name (cons (car tree) rands))))))) (define change-forest (lambda (trees) (let ((pos (find-position (map deep trees)))) (let ((left-trees (get-left-trees trees pos)) (tree (get-tree trees pos)) (right-trees (get-right-trees trees pos))) (let ((ch (change tree))) (let ((old-tree (car ch)) (name (cadr ch)) (new-tree (caddr ch))) (list old-tree name (append left-trees (list new-tree) right-trees))))))))
(define get-tree (lambda (trees pos) (if (= (car pos) 0) (car trees) (get-tree (cdr trees) (cdr pos))))) (define get-left-trees (lambda (trees pos) (if (= (car pos) 0) (list) (cons (car trees) (get-left-trees (cdr trees) (cdr pos)))))) (define get-right-trees (lambda (trees pos) (if (= (car pos) 0) (cdr trees) (get-right-trees (cdr trees) (cdr pos))))) (define helper (lambda (lst max) (if (null? lst) (lst) (if (= max (car lst)) (cons max (map (lambda (n) (- n 1)) (cdr lst))) (cons (car lst) (helper (cdr lst) max)))))) (define find-position (lambda (lst) (let ((ma (accumulate max lst))) (map (lambda (n) (- n ma)) (helper lst ma))))) (define CPS-helper (lambda (exp en-exp) (let ((ope (car exp)) (rands (cdr exp))) (let ((cps-ope (translate->CPS-name ope))) (append (cons cps-ope rands) (list en-exp))))))
(define translate->CPS-name (lambda (sy) (string->symbol (string-append "cps&" (symbol->string sy))))) (define CPS (lambda (exp) (if (not (pair? exp)) exp (if (equal? (car exp) 'lambda) (list 'lambda (cadr exp) (CPS (caddr exp))) (let ((ch (change exp))) (let ((ch-tree (car ch)) (name (cadr ch)) (new-tree (caddr ch))) (CPS-helper ch-tree (list 'lambda (list name)
|