/
xensg.sex
132 lines (100 loc) · 3.92 KB
/
xensg.sex
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; File: xensg.scm ;;
;; Project: the specializer Unmix ;;
;; Author: S.A.Romanenko, the Institute for Applied ;;
;; Mathematics, the USSR Acedemy of Sciences, ;;
;; Moscow. ;;
;; Created: 5 August 1990 ;;
;; Revised: December 1992 ;;
;; ;;
;; Contents: A compiler from Mixwell to Scheme. ;;
;; ;;
;; Synopsis: ;;
;; (uensg:main src dst prog) ;;
;; ;;
;; src - source program name ;;
;; dst - destination program name ;;
;; prog - a Mixwell program ;;
;; ;;
;; Description: ;;
;; Compiles the Mixwell program "prog" ;;
;; into Scheme program. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (uensg:main src dst prog)
;;
;; Translates a Mixwell program into a Scheme program.
;; There should'n be any need for a thorough syntax check
;; since the input programs are (usually) produced by other
;; programs, which in turn are expected to produce
;; well-formed code.
;;
(define (ensugar prog)
(map compile-fundef prog))
(define (compile-fundef fundef)
(with (( (fname parlist '= body) fundef ))
`(define (,fname ,@parlist) ,(compile-exp body))
))
(define (compile-exp exp)
(select
(exp)
(_ & (symbol? exp) => exp)
(('quote const) =>
(if (literal? const) const exp))
(('car exp1) =>
(*extend-syntax-add-car* (compile-exp exp1)))
(('cdr exp1) =>
(*extend-syntax-add-cdr* (compile-exp exp1)))
(('cons exp1 exp2) =>
(compile-cons (compile-exp exp1)
(compile-exp exp2)))
(('if exp1 exp2 exp3) =>
(compile-if
(compile-exp exp1)
(compile-exp exp2)
(compile-exp exp3)))
(('call fname . exp*) =>
`(,fname . ,(map compile-exp exp*)))
(('rcall fname . exp*) =>
`(rcall (,fname . ,(map compile-exp exp*))))
(('xcall fname . exp*) =>
`(,fname . ,(map compile-exp exp*)))
((fname . exp*) =>
`(,fname . ,(map compile-exp exp*)))
))
(define (compile-cons exp1 exp2)
(list 'quasiquote
(cons (make-unquote exp1) (make-unquote exp2))))
(define (make-unquote exp)
(match
(exp)
(_ & (literal? exp) => exp)
(('quote c) => c)
(('quasiquote c) => c)
(_ => (list 'unquote exp))
))
(define (compile-if exp0 exp1 exp2)
(match
(exp2)
(('if p a b) =>
`(cond (,exp0 ,exp1) (,p ,a) (else ,b)))
(('cond . clause*) =>
`(cond (,exp0 ,exp1) . ,clause*))
(_ =>
`(if ,exp0 ,exp1 ,exp2))
))
(define (literal? x)
(or (boolean? x)
(number? x)
(char? x)
(string? x)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (uensg:main src dst prog) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(newline)
(display "-- Ensugaring: ") (display src) (display " -> ") (display dst)
(newline)
(set! prog (ensugar prog))
(display "-- Done --") (newline)
prog)