You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

292 lines
8.4 KiB
Scheme

;;; compat.ss
;;; Copyright 1984-2017 Cisco Systems, Inc.
;;;
;;; Licensed under the Apache License, Version 2.0 (the "License");
;;; you may not use this file except in compliance with the License.
;;; You may obtain a copy of the License at
;;;
;;; http://www.apache.org/licenses/LICENSE-2.0
;;;
;;; Unless required by applicable law or agreed to in writing, software
;;; distributed under the License is distributed on an "AS IS" BASIS,
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;;; See the License for the specific language governing permissions and
;;; limitations under the License.
;;; miscellaneous definitions to make this version compatible
;;; (where possible) with previous versions...and to a small extent with
;;; other versions of scheme and other dialects of lisp as well
;;; use only those items that you need to avoid introducing accidental
;;; dependencies on other items.
(define-syntax define!
(syntax-rules ()
((_ x v) (begin (set! x v) 'x))))
(define-syntax defrec!
(syntax-rules ()
((_ x v) (define! x (rec x v)))))
(define-syntax begin0
(syntax-rules ()
((_ x y ...) (let ((t x)) y ... t))))
(define-syntax recur
(syntax-rules ()
((_ f ((i v) ...) e1 e2 ...)
(let f ((i v) ...) e1 e2 ...))))
(define-syntax trace-recur
(syntax-rules ()
((_ f ((x v) ...) e1 e2 ...)
(trace-let f ((x v) ...) e1 e2 ...))))
(define swap-box!
(lambda (b v)
(if (box? b)
(let ((x (unbox b))) (set-box! b v) x)
(error 'swap-box! "~s is not a box" b))))
(define cull
(lambda (pred? ls)
(unless (procedure? pred?)
(error 'cull "~s is not a procedure" pred?))
(let f ([l ls])
(cond
[(pair? l)
(if (pred? (car l))
(cons (car l) (f (cdr l)))
(f (cdr l)))]
[(null? l) '()]
[else (error 'cull "~s is not a proper list" ls)]))))
(define cull! cull)
(define mem
(lambda (pred? ls)
(unless (procedure? pred?)
(error 'mem "~s is not a procedure" pred?))
(let f ([l ls])
(cond
[(pair? l) (if (pred? (car l)) l (f (cdr l)))]
[(null? l) #f]
[else (error 'mem "~s is not a proper list" ls)]))))
(define rem
(lambda (pred? ls)
(unless (procedure? pred?)
(error 'rem "~s is not a procedure" pred?))
(let f ([l ls])
(cond
[(pair? l)
(if (pred? (car l))
(f (cdr l))
(cons (car l) (f (cdr l))))]
[(null? l) '()]
[else (error 'rem "~s is not a proper list" ls)]))))
(define rem!
(lambda (pred? ls)
(unless (procedure? pred?)
(error 'rem! "~s is not a procedure" pred?))
(let f ([l ls])
(cond
[(pair? l)
(if (pred? (car l))
(f (cdr l))
(begin
(set-cdr! l (f (cdr l)))
l))]
[(null? l) '()]
[else (error 'rem! "~s is not a proper list" ls)]))))
(define ass
(lambda (pred? alist)
(unless (procedure? pred?)
(error 'ass "~s is not a procedure" pred?))
(let loop ([l alist])
(cond
[(and (pair? l) (pair? (car l)))
(if (pred? (caar l))
(car l)
(loop (cdr l)))]
[(null? l) #f]
[else (error 'ass "improperly formed alist ~s" alist)]))))
(define prompt-read
(lambda (fmt . args)
(apply printf fmt args)
(read)))
(define tree-copy
(rec tree-copy
(lambda (x)
(if (pair? x)
(cons (tree-copy (car x)) (tree-copy (cdr x)))
x))))
(define ferror error)
(define *most-negative-short-integer* (most-negative-fixnum))
(define *most-positive-short-integer* (most-positive-fixnum))
(define *most-negative-fixnum* (most-negative-fixnum))
(define *most-positive-fixnum* (most-positive-fixnum))
(define *eof* (read-char (open-input-string "")))
(define short-integer? fixnum?)
(define big-integer? bignum?)
(define ratio? ratnum?)
(define float? flonum?)
(define bound? top-level-bound?)
(define global-value top-level-value)
(define set-global-value! set-top-level-value!)
(define define-global-value define-top-level-value)
(define symbol-value top-level-value)
(define set-symbol-value! set-top-level-value!)
(define put putprop)
(define get getprop)
(define copy-list list-copy)
(define copy-tree tree-copy)
(define copy-string string-copy)
(define copy-vector vector-copy)
(define intern string->symbol)
(define symbol-name symbol->string)
(define string->uninterned-symbol gensym)
(define make-temp-symbol string->uninterned-symbol)
(define uninterned-symbol? gensym?)
(define temp-symbol? uninterned-symbol?)
(define compile-eval compile)
(define closure? procedure?)
(define =? =)
(define <? <)
(define >? >)
(define <=? <=)
(define >=? >=)
(define float exact->inexact)
(define rational inexact->exact)
(define char-equal? char=?)
(define char-less? char<?)
(define string-equal? string=?)
(define string-less? string<?)
; following defn conflicts with new r6rs mod
#;(define mod modulo)
(define flush-output flush-output-port)
(define clear-output clear-output-port)
(define clear-input clear-input-port)
(define mapcar map)
(define mapc for-each)
(define true #t)
(define false #f)
(define t #t)
(define nil '())
(define macro-expand expand)
;;; old macro and structure definition
;;; thanks to Michael Lenaghan (MichaelL@frogware.com) for suggesting
;;; various improvements.
(define-syntax define-macro!
(lambda (x)
(syntax-case x ()
[(k (name arg1 ... . args)
form1
form2
...)
#'(k name (arg1 ... . args)
form1
form2
...)]
[(k (name arg1 arg2 ...)
form1
form2
...)
#'(k name (arg1 arg2 ...)
form1
form2
...)]
[(k name args . forms)
(identifier? #'name)
(letrec ((add-car
(lambda (access)
(case (car access)
((cdr) `(cadr ,@(cdr access)))
((cadr) `(caadr ,@(cdr access)))
((cddr) `(caddr ,@(cdr access)))
((cdddr) `(cadddr ,@(cdr access)))
(else `(car ,access)))))
(add-cdr
(lambda (access)
(case (car access)
((cdr) `(cddr ,@(cdr access)))
((cadr) `(cdadr ,@(cdr access)))
((cddr) `(cdddr ,@(cdr access)))
((cdddr) `(cddddr ,@(cdr access)))
(else `(cdr ,access)))))
(parse
(lambda (l access)
(cond
((null? l) '())
((symbol? l) `((,l ,access)))
((pair? l)
(append!
(parse (car l) (add-car access))
(parse (cdr l) (add-cdr access))))
(else
(syntax-error #'args
(format "invalid ~s parameter syntax" (datum k))))))))
(with-syntax ((proc (datum->syntax-object #'k
(let ((g (gensym)))
`(lambda (,g)
(let ,(parse (datum args) `(cdr ,g))
,@(datum forms)))))))
#'(define-syntax name
(lambda (x)
(syntax-case x ()
((k1 . r)
(datum->syntax-object #'k1
(proc (syntax-object->datum x)))))))))])))
(alias define-macro define-macro!)
(alias defmacro define-macro!)
(define-macro! define-struct! (name . slots)
`(begin
(define ,name
(lambda ,slots
(vector ',name ,@slots)))
(define ,(string->symbol (format "~a?" name))
(lambda (x)
(and (vector? x)
(= (vector-length x) (1+ ,(length slots)))
(eq? ',name (vector-ref x 0)))))
,@(\#make-accessors name slots)
',name))
(define \#make-accessors
(lambda (name slots)
(recur f ((n 1) (slots slots))
(if (not (null? slots))
(let*
((afn (string->symbol (format "~a-~a" name (car slots))))
(sfn (string->symbol (format "~a!" afn))))
`((define-macro! ,afn (x) `(vector-ref ,x ,,n))
(define-macro! ,sfn (x v) `(vector-set! ,x ,,n ,v))
,@(f (1+ n) (cdr slots))))
'()))))