|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 24687 (0x606f)
Types: TextFile
Names: »parse.scm.70«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/scm/parse.scm.70«
;;; -*-Scheme-*-
;;;
;;; Copyright (c) 1984 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.
;;;
;;;; Scheme Parser
(declare (usual-integrations))
(define *get-character)
(define (*eof-action)
'())
(define *tyi)
(define *tyipeek)
(define *dismiss-character)
(define *read)
(define *get-character-buffer* #!FALSE)
(define *parser-radix* #o12)
\f
;;;; Character Class Tables
;;; This group of variables is in global for speed.
(define *whitespace-bit*
(access *whitespace-bit* character-package))
(define *alphabetic-bit*
(access *alphabetic-bit* character-package))
(define *digit-bit*
(access *digit-bit* character-package))
(define *atom-terminator-bit*
((access make-character-predicate-table character-package)
(lambda (char)
(disjunction
(vector-1b-ref *whitespace-bit* char)
(character-equal? char #/')
(character-equal? char #/()
(character-equal? char #/))
(character-equal? char #/;)
(character-equal? char #/#)
(character-equal? char #/")
(character-equal? char #/|)
(character-equal? char (access end-of-file character-package))))))
(define *atom-constituent-bit*
((access make-character-predicate-table character-package)
(lambda (char)
(conjunction
(< char (access *number-of-characters-in-ascii* character-package))
(not (vector-1b-ref *atom-terminator-bit* char))))))
(define *parser-named-characters*
`((NULL . #o0)
(BELL . #o7)
(TAB . ,(access tab character-package))
(LF . ,(access line-feed character-package))
(FF . ,(access form-feed character-package))
(CR . ,(access carriage-return character-package))
(SP . ,(access space character-package))
(DOT . #o56)))
(define *parser-named-objects*
`((NULL . ,(list))
(FALSE . ,(eq? 'TRUE 'FALSE))
(TRUE . ,(eq? 'TRUE 'TRUE))
(OPTIONAL . ,(access lambda-optional-tag lambda-package))))
\f
(define *parser-table*)
(define *parse-object-table*)
(define *collect-list-table*)
(define *parse-object-special-table*)
(define *collect-list-special-table*)
(define scheme-parser
(make-package scheme-parser
((end-of-file-character
(access end-of-file character-package))
(close-comment-character
(access end-of-line character-package))
(whitespace-characters
(access whitespace character-package))
(numerical-value
(access numerical-value character-package))
(for-each-character!
(access for-each-character character-package))
(make-character-dispatch-vector
(access make-character-dispatch-vector character-package)))
(define =char? eq?)
(define mem-char memq)
(define intern-character-list
(make-primitive-procedure 'INTERN-CHARACTER-LIST))
(declare (compilable-primitive-functions (=char? eq?)
(mem-char memq)
intern-character-list))
;;; This will capture the syntax definitions inside.
(let-syntax ()
\f
;;;; Character Operations
;;; Hairy stuff. Differs from the traditional TYI/TYIPEEK combination.
;;; TYIPEEK is THIS-CHARACTER. TYI is THIS-CHARACTER followed by
;;; DISMISS-THIS-CHARACTER, but usually we use them the other way around.
;;; So NEXT-CHARACTER means DISMISS-THIS-CHARACTER followed by THIS-CHARACTER.
;;; These procedures are open coded this way for speed.
;;; Unfortunately we don't yet have real procedure integration.
(define-macro (this-character-pass-eof)
`(disjunction *get-character-buffer*
(sequence (set! *get-character-buffer* (*get-character))
*get-character-buffer*)))
(define (this-character-pass-eof)
(this-character-pass-eof))
(define-macro (this-character)
`(if (=char? (this-character-pass-eof) end-of-file-character)
(error "End of file within READ")
*get-character-buffer*))
(define (this-character)
(this-character))
(define-macro (next-character-pass-eof)
`(if (set! *get-character-buffer* (*get-character))
*get-character-buffer*
(error "Dismissed unseen character" 'CALL-A-WIZARD)))
(define (next-character-pass-eof)
(next-character-pass-eof))
(define-macro (next-character)
`(if (=char? (next-character-pass-eof) end-of-file-character)
(error "End of file within READ")
*get-character-buffer*))
(define (next-character)
(next-character))
(define-macro (dismiss-this-character)
`(if (not (set! *get-character-buffer* #!FALSE))
(error "Dismissed unseen character" 'CALL-A-WIZARD)))
(define (dismiss-this-character)
(dismiss-this-character))
(set! *tyipeek
(named-lambda (*tyipeek)
(if (=char? (this-character-pass-eof) end-of-file-character)
(*eof-action)
*get-character-buffer*)))
(set! *tyi
(named-lambda (*tyi)
(if (=char? (this-character-pass-eof) end-of-file-character)
(sequence (set! *get-character-buffer* #!FALSE)
(*eof-action))
(set! *get-character-buffer* #!FALSE))))
(set! *dismiss-character
(named-lambda (*dismiss-character)
(if (not (set! *get-character-buffer* #!FALSE))
(*get-character))))
\f
(define-macro (atom-terminator? char)
`(vector-1b-ref *atom-terminator-bit* ,char))
(define (atom-terminator? char)
(atom-terminator? char))
(define-macro (atom-constituent? char)
`(vector-1b-ref *atom-constituent-bit* ,char))
(define (atom-constituent? char)
(atom-constituent? char))
(define-macro (whitespace? char)
`(vector-1b-ref *whitespace-bit* ,char))
(define (whitespace? char)
(whitespace? char))
(define-macro (alphabetic? char)
`(vector-1b-ref *alphabetic-bit* ,char))
(define (alphabetic? char)
(alphabetic? char))
(define-macro (digit? char)
`(vector-1b-ref *digit-bit* ,char))
(define (digit? char)
(digit? char))
\f
;;;; Table dispatches
(define-macro (parse-object)
`((vector-ref *parse-object-table* (this-character-pass-eof))))
(define (parse-object)
(parse-object))
(set! *read parse-object)
(define-macro (dismiss-and-parse-object)
`((vector-ref *parse-object-table* (next-character-pass-eof))))
(define (dismiss-and-parse-object)
(dismiss-and-parse-object))
(define-macro (collect-list)
`((vector-ref *collect-list-table* (this-character))))
(define (collect-list)
(collect-list))
(define-macro (dismiss-and-collect-list)
`((vector-ref *collect-list-table* (next-character))))
(define (dismiss-and-collect-list)
(dismiss-and-collect-list))
\f
;;;; Atoms
;;; There are two major dispatch tables, one for parsing at top level,
;;; the other for parsing the elements of a list. Most of the entries
;;; for each table are have similar actions.
;;; Default is atomic object. Parsing an atomic object does not
;;; consume its terminator. Thus different terminators [such as open
;;; paren, close paren, and whitespace], can have different effects on
;;; parser.
(define ((collect-list-wrapper object-parser))
(let ((value (object-parser))) ;forces order.
(cons value (collect-list))))
(define (parse-atom)
(build-atom (accumulate-atom (this-character-pass-eof))))
(define parse-atom-in-list
(collect-list-wrapper parse-atom))
;;; Names beginning with alphabetic characters are handled specially
;;; to speed up the parsing of symbols.
(define (parse-symbol)
(intern-character-list (accumulate-atom (this-character-pass-eof))))
(define parse-symbol-in-list
(collect-list-wrapper parse-symbol))
(define (build-atom char-list)
(disjunction (parse-number char-list)
(intern-character-list char-list)))
(define (accumulate-atom char)
(cons (character-upcase char)
(if (atom-terminator? (next-character-pass-eof))
'()
(accumulate-atom *get-character-buffer*)))) ;Speed up hack.
\f
;;;; Lists
(define (parse-list)
(dismiss-and-collect-list))
(define parse-list-in-list
(collect-list-wrapper parse-list))
(define (parse-vector)
(list->vector (parse-list)))
(define parse-vector-in-list
(collect-list-wrapper parse-vector))
;;; Ignore close parens typed at top level.
(define (parse-close-list)
(dismiss-and-parse-object))
(define (parse-close-list-in-list)
(dismiss-this-character)
'())
(define (dotted-list-tail)
;; atom with initial dot?
(if (atom-constituent? (next-character))
(let ((first (build-atom (cons #/. (accumulate-atom (this-character))))))
(cons first (collect-list)))
;; (A . B) -- get B and ignore whitespace following it.
(let ((tail (parse-object)))
(let ignore-whitespace ((char (this-character)))
(cond ((=char? char #/))
(dismiss-this-character))
((whitespace? char)
(ignore-whitespace (next-character)))
(else
(error "Illegal character in ignored stream" char))))
tail)))
\f
;;;; Whitespace and Comments
(define (parse-whitespace)
(dismiss-and-parse-object))
(define (parse-whitespace-in-list)
(dismiss-and-collect-list))
(define (parse-end-of-file)
(*eof-action))
(define (parse-end-of-file-in-list)
(error "End of file within READ"))
(define (parse-comment)
(let flush-comment ((char (next-character-pass-eof)))
(cond ((=char? char close-comment-character)
(dismiss-and-parse-object))
((=char? char end-of-file-character)
(parse-object))
(else
(flush-comment (next-character-pass-eof))))))
(define (parse-comment-in-list)
(let flush-comment ((char (next-character)))
(cond ((=char? char close-comment-character)
(dismiss-and-collect-list))
(else
(flush-comment (next-character))))))
(define (parse-special-comment)
(let special-comment-loop ((char (next-character)))
(if (=char? char #/|)
(let ((next-char (next-character)))
(if (=char? next-char #/#)
(dismiss-and-parse-object)
(special-comment-loop next-char)))
(special-comment-loop (next-character)))))
(define (parse-special-comment-in-list)
(let special-comment-loop ((char (next-character)))
(if (=char? char #/|)
(let ((next-char (next-character)))
(if (=char? next-char #/#)
(dismiss-and-collect-list)
(special-comment-loop next-char)))
(special-comment-loop (next-character)))))
\f
;;;; Quoteification
(define (parse-quote)
(cons 'QUOTE
(cons (dismiss-and-parse-object)
'())))
(define parse-quote-in-list
(collect-list-wrapper parse-quote))
(define (parse-quasiquote)
(cons 'QUASIQUOTE
(cons (dismiss-and-parse-object)
'())))
(define parse-quasiquote-in-list
(collect-list-wrapper parse-quasiquote))
(define (parse-quasiunquote)
(if (=char? (next-character) #/@)
(cons 'QUASIQUOTE-SPREADER
(cons (dismiss-and-parse-object)
'()))
(cons 'QUASIQUOTE-UNQUOTER
(cons (parse-object)
'()))))
(define parse-quasiunquote-in-list
(collect-list-wrapper parse-quasiunquote))
(define (parse-string)
(list->string
(let accumulate-string ((char (next-character)))
(if (=char? char #/")
(let ((next-char (next-character-pass-eof)))
(if (=char? next-char #/")
(cons next-char
(accumulate-string (next-character)))
'()))
(cons char (accumulate-string (next-character)))))))
(define parse-string-in-list
(collect-list-wrapper parse-string))
(define (parse-special-atom)
(intern-character-list
(cons #/|
(let accumulate-special-atom ((char (next-character)))
(cons char
(if (=char? char #/|)
(let ((next-char (next-character-pass-eof)))
(if (=char? next-char #/|)
(accumulate-special-atom (next-character))
'()))
(accumulate-special-atom (next-character))))))))
(define parse-special-atom-in-list
(collect-list-wrapper parse-special-atom))
\f
;;;; Abstract Object Syntax
(define (parse-character-value)
(let ((char (next-character)))
(dismiss-this-character)
char))
(define parse-character-value-in-list
(collect-list-wrapper parse-character-value))
(define (parse-named-character)
(let ((character-name (dismiss-and-parse-object)))
(cdr (disjunction (assq character-name *parser-named-characters*)
(error "No character by this name" 'READ
character-name)))))
(define parse-named-character-in-list
(collect-list-wrapper parse-named-character))
(define (parse-named-object)
(let ((object-name (dismiss-and-parse-object)))
(cdr (disjunction (assq object-name *parser-named-objects*)
(error "No object by this name" 'READ object-name)))))
(define parse-named-object-in-list
(collect-list-wrapper parse-named-object))
\f
;;;; Radix Management
(define ((establish-temporary-radix new-radix))
(fluid-let ((*parser-radix* new-radix))
(disjunction
(build-special-integer (accumulate-atom (next-character-pass-eof)))
(error "Bad syntax for special integer" 'READ))))
(define parse-base-2-integer
(establish-temporary-radix 2))
(define parse-base-2-integer-in-list
(collect-list-wrapper parse-base-2-integer))
(define parse-base-8-integer
(establish-temporary-radix 8))
(define parse-base-8-integer-in-list
(collect-list-wrapper parse-base-8-integer))
(define parse-base-10-integer
(establish-temporary-radix 10))
(define parse-base-10-integer-in-list
(collect-list-wrapper parse-base-10-integer))
(define parse-base-16-integer
(establish-temporary-radix 16))
(define parse-base-16-integer-in-list
(collect-list-wrapper parse-base-16-integer))
(define (parse-radix-change)
(establish-permanent-radix)
(parse-object))
(define (parse-radix-change-in-list)
(establish-permanent-radix)
(collect-list))
(define (establish-permanent-radix)
(let ((new-radix (dismiss-and-parse-object)))
(if (conjunction (integer? new-radix) (> new-radix 1))
(set! *parser-radix* new-radix)
(error "Bad radix" 'READ new-radix))))
\f
;;;; Numbers
;;; [+/-][n*][.][n*][E/e[+/-][n*]]
(define (parse-number char-list)
(cond ((=char? (car char-list) #/-)
(build-signed-number (cdr char-list) -1))
((=char? (car char-list) #/+)
(build-signed-number (cdr char-list) +1))
(else
(build-signed-number char-list +1))))
(define (build-signed-number char-list sign)
(conjunction char-list
(cond ((digit? (car char-list))
(let ((v (build-unsigned-number char-list 0)))
(conjunction v (* v sign))))
((conjunction (=char? (car char-list) #/.)
(not (null? (cdr char-list)))
(digit? (cadr char-list)))
(let ((v (build-float (cdr char-list) 0)))
(conjunction v (* v sign))))
(else #!FALSE)))) ;makes +/- symbols
(define (build-unsigned-number char-list value)
(cond ((null? char-list)
value)
((=char? (car char-list) #/.) ; 123. is a "float"
(build-float (cdr char-list) value))
((digit? (car char-list))
(build-unsigned-number (cdr char-list)
(+ (* *parser-radix* value)
(numerical-value (car char-list)))))
((mem-char (car char-list) '(#/E #/e))
(build-scientific (cdr char-list) value 0 0))
(else #!FALSE)))
(define (build-float char-list integer-part)
(define (float-loop char-list fraction place-value)
;; fraction is the numerator and radix^place-value is the denominator.
(cond ((null? char-list)
(+ integer-part
(/ fraction (integer-expt *parser-radix* place-value))))
((digit? (car char-list))
(float-loop (cdr char-list)
(+ (* *parser-radix* fraction)
(numerical-value (car char-list)))
(1+ place-value)))
((mem-char (car char-list) '(#/E #/e))
(build-scientific (cdr char-list)
integer-part
fraction
place-value))
(else #!FALSE)))
(float-loop char-list 0 0))
(define (build-scientific char-list integer-part fraction place-value)
(conjunction
(not (null? char-list))
(let ((v (parse-number char-list)))
(conjunction
(not (null? v))
(+ (* integer-part (expt *parser-radix* v))
(* fraction (expt *parser-radix* (- v place-value))))))))
\f
;;;; Special Integers
;;; are constructed when using temporary radices -- this is how we
;;; get the hexadecimal radix to work, for instance.
(define &- (make-primitive-procedure '&-))
(define A-10 (- #/A 10))
(define (build-special-integer char-list)
(cond ((digit? (car char-list))
(build-unsigned-special-integer
(cdr char-list)
(&- (car char-list) #/0)))
((alphabetic? (car char-list))
(build-unsigned-special-integer
(cdr char-list)
(&- (character-upcase (car char-list)) A-10)))
((=char? (car char-list) #/-)
(conjunction
(not (null? (cdr char-list)))
(let ((v (build-unsigned-special-integer (cdr char-list) 0)))
(conjunction v (* -1 )))))
((=char? (car char-list) #/+)
(conjunction
(not (null? (cdr char-list)))
(build-unsigned-special-integer (cdr char-list) 0)))
(else #!FALSE)))
(define (build-unsigned-special-integer char-list value)
(cond ((null? char-list)
value)
((digit? (car char-list))
(build-unsigned-special-integer
(cdr char-list)
(+ (* *parser-radix* value) (&- (car char-list) #/0))))
((alphabetic? (car char-list))
(build-unsigned-special-integer
(cdr char-list)
(+ (* *parser-radix* value)
(&- (character-upcase (car char-list)) A-10))))
(else #!FALSE)))
\f
;;;; Dispatch Table Construction
(define (parse-undefined-special)
(error "No such special reader macro" 'READ (this-character)))
(define (parse-special-macro)
((vector-ref *parse-object-special-table* (next-character))))
(define (parse-special-macro-in-list)
((vector-ref *collect-list-special-table* (next-character))))
(set! *parse-object-table*
(make-character-dispatch-vector parse-atom))
(set! *collect-list-table*
(make-character-dispatch-vector parse-atom-in-list))
(set! *parse-object-special-table*
(make-character-dispatch-vector parse-undefined-special))
(set! *collect-list-special-table*
(make-character-dispatch-vector parse-undefined-special))
(set! *parser-table*
(cons (cons *parse-object-table* *collect-list-table*)
(cons *parse-object-special-table* *collect-list-special-table*)))
(vector-set! *parse-object-table* #/# parse-special-macro)
(vector-set! *collect-list-table* #/# parse-special-macro-in-list)
(for-each-character!
(lambda (char)
(if (alphabetic? char)
(sequence
(vector-set! *parse-object-table* char parse-symbol)
(vector-set! *collect-list-table* char parse-symbol-in-list)))))
(vector-set! *parse-object-table* #/( parse-list)
(vector-set! *collect-list-table* #/( parse-list-in-list)
(vector-set! *parse-object-special-table* #/( parse-vector)
(vector-set! *collect-list-special-table* #/( parse-vector-in-list)
(vector-set! *parse-object-table* #/) parse-close-list)
(vector-set! *collect-list-table* #/) parse-close-list-in-list)
(vector-set! *collect-list-table* #/. dotted-list-tail)
(mapc (lambda (char)
(vector-set! *parse-object-table* char parse-whitespace)
(vector-set! *collect-list-table* char parse-whitespace-in-list))
whitespace-characters)
(vector-set! *parse-object-table* end-of-file-character parse-end-of-file)
(vector-set! *collect-list-table* end-of-file-character
parse-end-of-file-in-list)
\f
(vector-set! *parse-object-table* #/; parse-comment)
(vector-set! *collect-list-table* #/; parse-comment-in-list)
(vector-set! *parse-object-special-table* #/| parse-special-comment)
(vector-set! *collect-list-special-table* #/| parse-special-comment-in-list)
(vector-set! *parse-object-table* #/' parse-quote)
(vector-set! *collect-list-table* #/' parse-quote-in-list)
(vector-set! *parse-object-table* #/` parse-quasiquote)
(vector-set! *collect-list-table* #/` parse-quasiquote-in-list)
(vector-set! *parse-object-table* #/, parse-quasiunquote)
(vector-set! *collect-list-table* #/, parse-quasiunquote-in-list)
(vector-set! *parse-object-table* #/" parse-string)
(vector-set! *collect-list-table* #/" parse-string-in-list)
(vector-set! *parse-object-table* #/| parse-special-atom)
(vector-set! *collect-list-table* #/| parse-special-atom-in-list)
(vector-set! *parse-object-special-table* #// parse-character-value)
(vector-set! *collect-list-special-table* #// parse-character-value-in-list)
(vector-set! *parse-object-special-table* #/\ parse-named-character)
(vector-set! *collect-list-special-table* #/\ parse-named-character-in-list)
(vector-set! *parse-object-special-table* #/! parse-named-object)
(vector-set! *collect-list-special-table* #/! parse-named-object-in-list)
(mapc (lambda (char)
(vector-set! *parse-object-special-table* char parse-base-2-integer)
(vector-set! *collect-list-special-table* char
parse-base-2-integer-in-list))
'(#/B #/b))
(mapc (lambda (char)
(vector-set! *parse-object-special-table* char parse-base-8-integer)
(vector-set! *collect-list-special-table* char
parse-base-8-integer-in-list))
'(#/O #/o))
(mapc (lambda (char)
(vector-set! *parse-object-special-table* char parse-base-10-integer)
(vector-set! *collect-list-special-table* char
parse-base-10-integer-in-list))
'(#/D #/d))
(mapc (lambda (char)
(vector-set! *parse-object-special-table* char parse-base-16-integer)
(vector-set! *collect-list-special-table* char
parse-base-16-integer-in-list))
'(#/X #/x))
;(mapc (lambda (char)
; (vector-set! *parse-object-special-table* char parse-radix-change)
; (vector-set! *collect-list-special-table* char
; parse-radix-change-in-list))
; '(#/R #/r))
;;; end LET-SYNTAX.
)
;;; end SCHEME-PARSER package.
))
\f
;;;; Parser Tables
(define (current-parser-table)
*parser-table*)
(define (set-current-parser-table! new-table)
(set! *parse-object-table* (caar new-table))
(set! *collect-list-table* (cdar new-table))
(set! *parse-object-special-table* (cadr new-table))
(set! *collect-list-special-table* (cddr new-table))
(set! *parser-table* new-table))
(define (with-parser-table new-parser-table thunk)
(define old-parser-table)
(dynamic-wind (lambda ()
(set! old-parser-table
(set-current-parser-table! new-parser-table)))
thunk
(lambda ()
(set! new-parser-table
(set-current-parser-table! old-parser-table)))))
(define (copy-parser-table table)
(cons (cons (vector-copy (caar table))
(vector-copy (cdar table)))
(cons (vector-copy (cadr table))
(vector-copy (cddr table)))))
(define parser-table-entry)
(define set-parser-table-entry!)
(let ()
(define (decode-parser-character table character receiver)
(cond ((character? character)
(receiver (car table) character))
((string? character)
(cond ((= (string-size character) 1)
(receiver (car table) (string-ref character 0)))
((conjunction (= (string-size character) 2)
(character-equal? (string-ref character 0) #/#))
(receiver (cdr table) (string-ref character 1)))
(else
(error "Bad character" 'DECODE-PARSER-CHARACTER character))))
(else
(error "Bad character" 'DECODE-PARSER-CHARACTER character))))
(define (ptable-ref table index)
(cons (vector-ref (car table) index)
(vector-ref (cdr table) index)))
(define (ptable-set! table index value)
(vector-set! (car table) index (car value))
(vector-set! (cdr table) index (cdr value)))
(set! parser-table-entry
(named-lambda (parser-table-entry table character)
(decode-parser-character table character ptable-ref)))
(set! set-parser-table-entry!
(named-lambda (set-parser-table-entry! table character entry)
(decode-parser-character table character
(lambda (sub-table index)
(ptable-set! sub-table index entry)))))
)