pcs/edwin/emacros.scm

183 lines
7.9 KiB
Scheme
Raw Permalink Normal View History

2023-05-20 05:57:04 -04:00
;;;
;;; Copyright (c) 1985 Massachusetts Institute of Technology
;;;
;;; This material was developed by the Scheme project at the
;;; Massachusetts Institute of Technology, Department of
;;; Electrical Engineering and Computer Science. Permission to
;;; copy this software, to redistribute it, and to use it for any
;;; purpose is granted, subject to the following restrictions and
;;; understandings.
;;;
;;; 1. Any copy made of this software must include this copyright
;;; notice in full.
;;;
;;; 2. Users of this software agree to make their best efforts (a)
;;; to return to the MIT Scheme project any improvements or
;;; extensions that they make, so that these may be included in
;;; future releases; and (b) to inform MIT of noteworthy uses of
;;; this software.
;;;
;;; 3. All materials developed as a consequence of the use of
;;; this software shall duly acknowledge such use, in accordance
;;; with the usual standards of acknowledging credit in academic
;;; research.
;;;
;;; 4. MIT has made no warrantee or representation that the
;;; operation of this software will be error-free, and MIT is
;;; under no obligation to provide any services, by way of
;;; maintenance, update, or otherwise.
;;;
;;; 5. In conjunction with products arising from the use of this
;;; material, there shall be no use of the name of the
;;; Massachusetts Institute of Technology nor of any adaptation
;;; thereof in any advertising, promotional, or sales literature
;;; without prior written consent from MIT in each case.
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Modified by Texas Instruments Inc 8/15/85
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
(begin
(define-integrable substring-find-next-char
substring-find-next-char-in-set)
(define-integrable substring-find-previous-char
substring-find-previous-char-in-set)
)
;;;; Replace Group
(define (string-replace string char1 char2)
(let ((string (string-copy string)))
(string-replace! string char1 char2)
string))
(define (substring-replace string start end char1 char2)
(let ((string (string-copy string)))
(substring-replace! string start end char1 char2)
string))
(define (string-replace! string char1 char2)
(substring-replace! string 0 (string-length string) char1 char2))
(define (substring-replace! string start end char1 char2)
(define (loop start)
(let ((index (substring-find-next-char string start end char1)))
(if index
(sequence (string-set! string index char2)
(loop (1+ index))))))
(loop start))
(define string-uppercase '())
(let ()
(define (string-set-case char-set-case)
(lambda (string1)
(let ((end (string-length string1)))
(define (loop string2 string1 index char-set-case end)
(if (= index end)
string2
(begin (string-set! string2
index
(char-set-case (string-ref string1 index)))
(loop string2 string1 (1+ index) char-set-case end))))
(loop (make-string end '()) string1 0 char-set-case end))))
(set! string-uppercase (string-set-case char-upcase)))
(define map2
(lambda (fn arg1 arg2)
(cond ((or (null? arg1) (null? arg2)) '())
(t (cons (fn (car arg1) (car arg2))
(map2 fn (cdr arg1) (cdr arg2)))))))
(macro define-named-structure
(lambda (e)
(let ((name (cadr e)) (slots (cddr e)))
(define ((make-symbols x) y) (make-symbol x y))
(define (make-symbol . args)
(string->symbol (apply string-append args)))
(let ((structure-string (string-uppercase name))
(slot-strings (mapcar symbol->string slots)))
(let ((prefix (string-append structure-string "-")))
(let ((structure-name (string->symbol structure-string))
(tag-name (make-symbol "%" prefix "TAG"))
(constructor-name
(make-symbol "%MAKE-" structure-string))
(predicate-name (make-symbol structure-string "?"))
(slot-names
(mapcar (make-symbols
(string-append prefix "INDEX:"))
slot-strings))
(selector-names
(mapcar (make-symbols prefix) slot-strings)))
(define (slot-loop tail slot-names n)
(if (null? slot-names)
tail
(slot-loop (cons (list 'DEFINE-INTEGRABLE
(car
slot-names)
n)
tail)
(cdr slot-names)
(|1+| n))))
(define (selector-loop tail selector-names n)
(if (null? selector-names)
tail
(selector-loop
(cons `(define-integrable
,(car selector-names)
(lambda (,structure-name)
(vector-ref ,structure-name
,n)))
tail)
(cdr selector-names)
(|1+| n))))
`(begin
(define ,tag-name ,name)
(define (,constructor-name)
(let ((,structure-name
(make-vector ,(1+ (length slots)) '())))
(vector-set! ,structure-name 0 ,tag-name)
,structure-name))
;;; (define (,predicate-name object)
;;; (and (vector? object)
;;; (not (zero? (vector-size object)))
;;; (eq? ,tag-name (vector-ref object 0))))
,@(slot-loop '() slot-names 1)
,@(selector-loop '() selector-names 1))))))))
(macro define-command
(lambda (e)
(let ((bvl (cadr e)) (description (caddr e)) (body (cdddr e)))
(let ((name (car bvl))
(arg-names
(mapcar (lambda (arg)
(if (pair? arg) (car arg) arg))
(cdr bvl)))
(arg-inits
(mapcar (lambda (arg)
(if (pair? arg) (cadr arg) #!FALSE))
(cdr bvl))))
(let ((procedure-name
(string->symbol
(string-append (canonicalize-name-string name)
"-COMMAND"))))
`(begin
(define (,procedure-name ,@arg-names)
,@(map2 (lambda (arg-name arg-init)
`(if (not ,arg-name)
(set! ,arg-name ,arg-init)))
arg-names arg-inits)
,@body)
(make-command ,name ,description ,procedure-name)))))))
(define canonicalize-name-string
(lambda (name)
(let ((name (string-uppercase name)))
(string-replace! name #\Space #\-)
name)))