Change Guile license to LGPLv3+
[bpt/guile.git] / module / language / tree-il / primitives.scm
CommitLineData
ac4d09b1 1;;; open-coding primitive procedures
cb28c085 2
ac4d09b1 3;; Copyright (C) 2009 Free Software Foundation, Inc.
cb28c085 4
53befeb7
NJ
5;;;; This library is free software; you can redistribute it and/or
6;;;; modify it under the terms of the GNU Lesser General Public
7;;;; License as published by the Free Software Foundation; either
8;;;; version 3 of the License, or (at your option) any later version.
9;;;;
10;;;; This library is distributed in the hope that it will be useful,
11;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13;;;; Lesser General Public License for more details.
14;;;;
15;;;; You should have received a copy of the GNU Lesser General Public
16;;;; License along with this library; if not, write to the Free Software
17;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
cb28c085
AW
18
19;;; Code:
20
55ae815b 21(define-module (language tree-il primitives)
cb28c085
AW
22 #:use-module (system base syntax)
23 #:use-module (language tree-il)
24 #:use-module (srfi srfi-16)
55ae815b
AW
25 #:export (resolve-primitives! add-interesting-primitive!
26 expand-primitives!))
27
28(define *interesting-primitive-names*
29 '(apply @apply
30 call-with-values @call-with-values
31 call-with-current-continuation @call-with-current-continuation
32 call/cc
33 values
34 eq? eqv? equal?
35 = < > <= >= zero?
36 + * - / 1- 1+ quotient remainder modulo
37 not
38 pair? null? list? acons cons cons*
39
40 list vector
41
42 car cdr
43 set-car! set-cdr!
44
45 caar cadr cdar cddr
46
47 caaar caadr cadar caddr cdaar cdadr cddar cdddr
48
49 caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr
50 cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr))
51
52(define (add-interesting-primitive! name)
53 (hashq-set! *interesting-primitive-vars*
54 (module-variable (current-module) name) name))
55
56(define *interesting-primitive-vars* (make-hash-table))
57
58(for-each add-interesting-primitive! *interesting-primitive-names*)
59
60(define (resolve-primitives! x mod)
61 (post-order!
62 (lambda (x)
63 (record-case x
64 ((<toplevel-ref> src name)
c0ee3245
AW
65 (and=> (hashq-ref *interesting-primitive-vars*
66 (module-variable mod name))
67 (lambda (name) (make-primitive-ref src name))))
55ae815b
AW
68 ((<module-ref> src mod name public?)
69 ;; for the moment, we're disabling primitive resolution for
70 ;; public refs because resolve-interface can raise errors.
71 (let ((m (and (not public?) (resolve-module mod))))
c0ee3245
AW
72 (and m
73 (and=> (hashq-ref *interesting-primitive-vars*
74 (module-variable m name))
75 (lambda (name) (make-primitive-ref src name))))))
55ae815b
AW
76 (else #f)))
77 x))
78
79\f
cb28c085
AW
80
81(define *primitive-expand-table* (make-hash-table))
82
83(define (expand-primitives! x)
84 (pre-order!
85 (lambda (x)
86 (record-case x
87 ((<application> src proc args)
88 (and (primitive-ref? proc)
89 (let ((expand (hashq-ref *primitive-expand-table*
90 (primitive-ref-name proc))))
91 (and expand (apply expand src args)))))
92 (else #f)))
93 x))
94
95;;; I actually did spend about 10 minutes trying to redo this with
96;;; syntax-rules. Patches appreciated.
97;;;
98(define-macro (define-primitive-expander sym . clauses)
99 (define (inline-args args)
100 (let lp ((in args) (out '()))
101 (cond ((null? in) `(list ,@(reverse out)))
102 ((symbol? in) `(cons* ,@(reverse out) ,in))
103 ((pair? (car in))
104 (lp (cdr in)
105 (cons `(make-application src (make-primitive-ref src ',(caar in))
106 ,(inline-args (cdar in)))
107 out)))
108 ((symbol? (car in))
109 ;; assume it's locally bound
110 (lp (cdr in) (cons (car in) out)))
111 ((number? (car in))
112 (lp (cdr in) (cons `(make-const src ,(car in)) out)))
113 (else
114 (error "what what" (car in))))))
115 (define (consequent exp)
116 (cond
117 ((pair? exp)
118 `(make-application src (make-primitive-ref src ',(car exp))
119 ,(inline-args (cdr exp))))
120 ((symbol? exp)
121 ;; assume locally bound
122 exp)
123 ((number? exp)
124 `(make-const src ,exp))
125 (else (error "bad consequent yall" exp))))
126 `(hashq-set! *primitive-expand-table*
127 ',sym
128 (case-lambda
129 ,@(let lp ((in clauses) (out '()))
130 (if (null? in)
131 (reverse (cons '(else #f) out))
132 (lp (cddr in)
133 (cons `((src . ,(car in))
134 ,(consequent (cadr in))) out)))))))
135
136(define-primitive-expander +
137 () 0
138 (x) x
139 (x y z . rest) (+ x (+ y z . rest)))
140
141(define-primitive-expander *
142 () 1
143 (x) x
144 (x y z . rest) (* x (* y z . rest)))
145
146(define-primitive-expander -
147 (x) (- 0 x)
148 (x y z . rest) (- x (+ y z . rest)))
149
150(define-primitive-expander 1-
151 (x) (- x 1))
152
153(define-primitive-expander /
154 (x) (/ 1 x)
81fd3152 155 (x y z . rest) (/ x (* y z . rest)))
cb28c085
AW
156
157(define-primitive-expander caar (x) (car (car x)))
158(define-primitive-expander cadr (x) (car (cdr x)))
159(define-primitive-expander cdar (x) (cdr (car x)))
160(define-primitive-expander cddr (x) (cdr (cdr x)))
161(define-primitive-expander caaar (x) (car (car (car x))))
162(define-primitive-expander caadr (x) (car (car (cdr x))))
163(define-primitive-expander cadar (x) (car (cdr (car x))))
164(define-primitive-expander caddr (x) (car (cdr (cdr x))))
165(define-primitive-expander cdaar (x) (cdr (car (car x))))
166(define-primitive-expander cdadr (x) (cdr (car (cdr x))))
167(define-primitive-expander cddar (x) (cdr (cdr (car x))))
168(define-primitive-expander cdddr (x) (cdr (cdr (cdr x))))
169(define-primitive-expander caaaar (x) (car (car (car (car x)))))
170(define-primitive-expander caaadr (x) (car (car (car (cdr x)))))
171(define-primitive-expander caadar (x) (car (car (cdr (car x)))))
172(define-primitive-expander caaddr (x) (car (car (cdr (cdr x)))))
173(define-primitive-expander cadaar (x) (car (cdr (car (car x)))))
174(define-primitive-expander cadadr (x) (car (cdr (car (cdr x)))))
175(define-primitive-expander caddar (x) (car (cdr (cdr (car x)))))
176(define-primitive-expander cadddr (x) (car (cdr (cdr (cdr x)))))
177(define-primitive-expander cdaaar (x) (cdr (car (car (car x)))))
178(define-primitive-expander cdaadr (x) (cdr (car (car (cdr x)))))
179(define-primitive-expander cdadar (x) (cdr (car (cdr (car x)))))
180(define-primitive-expander cdaddr (x) (cdr (car (cdr (cdr x)))))
181(define-primitive-expander cddaar (x) (cdr (cdr (car (car x)))))
182(define-primitive-expander cddadr (x) (cdr (cdr (car (cdr x)))))
183(define-primitive-expander cdddar (x) (cdr (cdr (cdr (car x)))))
184(define-primitive-expander cddddr (x) (cdr (cdr (cdr (cdr x)))))
185
186(define-primitive-expander cons*
187 (x) x
188 (x y) (cons x y)
189 (x y . rest) (cons x (cons* y . rest)))
190
dce042f1
AW
191(define-primitive-expander acons (x y z)
192 (cons (cons x y) z))
193
194(define-primitive-expander apply (f . args)
195 (@apply f . args))
196
197(define-primitive-expander call-with-values (producer consumer)
198 (@call-with-values producer consumer))
199
200(define-primitive-expander call-with-current-continuation (proc)
201 (@call-with-current-continuation proc))
202
0f423f20
AW
203(define-primitive-expander call/cc (proc)
204 (@call-with-current-continuation proc))
205
dce042f1 206(define-primitive-expander values (x) x)