⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optargs.scm

📁 MSYS在windows下模拟了一个类unix的终端
💻 SCM
📖 第 1 页 / 共 2 页
字号:
;;;; optargs.scm -- support for optional arguments;;;;;;;; 	Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc.;;;;;;;; This program is free software; you can redistribute it and/or modify;;;; it under the terms of the GNU General Public License as published by;;;; the Free Software Foundation; either version 2, or (at your option);;;; any later version.;;;;;;;; This program is distributed in the hope that it will be useful,;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;;;; GNU General Public License for more details.;;;;;;;; You should have received a copy of the GNU General Public License;;;; along with this software; see the file COPYING.  If not, write to;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,;;;; Boston, MA 02111-1307 USA;;;;;;;; As a special exception, the Free Software Foundation gives permission;;;; for additional uses of the text contained in its release of GUILE.;;;;;;;; The exception is that, if you link the GUILE library with other files;;;; to produce an executable, this does not by itself cause the;;;; resulting executable to be covered by the GNU General Public License.;;;; Your use of that executable is in no way restricted on account of;;;; linking the GUILE library code into it.;;;;;;;; This exception does not however invalidate any other reasons why;;;; the executable file might be covered by the GNU General Public License.;;;;;;;; This exception applies only to the code released by the;;;; Free Software Foundation under the name GUILE.  If you copy;;;; code from other Free Software Foundation releases into a copy of;;;; GUILE, as the General Public License permits, the exception does;;;; not apply to the code that you add in this way.  To avoid misleading;;;; anyone as to the status of such modified files, you must delete;;;; this exception notice from them.;;;;;;;; If you write modifications of your own for GUILE, it is your choice;;;; whether to permit this exception to apply to your modifications.;;;; If you do not wish that, delete this exception notice.;;;;;;;; Contributed by Maciej Stachowiak <mstachow@alum.mit.edu>;;; Commentary:;;; {Optional Arguments};;;;;; The C interface for creating Guile procedures has a very handy;;; "optional argument" feature. This module attempts to provide;;; similar functionality for procedures defined in Scheme with;;; a convenient and attractive syntax.;;;;;; exported macros are:;;;   let-optional;;;   let-optional*;;;   let-keywords;;;   let-keywords*;;;   lambda*;;;   define*;;;   define*-public;;;   defmacro*;;;   defmacro*-public;;;;;;;;; Summary of the lambda* extended parameter list syntax (brackets;;; are used to indicate grouping only):;;;;;; ext-param-list ::= [identifier]* [#:optional [ext-var-decl]+]?;;;   [#:key [ext-var-decl]+ [#:allow-other-keys]?]?;;;   [[#:rest identifier]|[. identifier]]?;;;;;; ext-var-decl ::= identifier | ( identifier expression );;;;;; The characters `*', `+' and `?' are not to be taken literally; they;;; mean respectively, zero or more occurences, one or more occurences,;;; and one or zero occurences.;;;;;; Code:(define-module (ice-9 optargs)  :export-syntax (let-optional		  let-optional*		  let-keywords		  let-keywords*		  define* lambda*		  define*-public		  defmacro*		  defmacro*-public));; let-optional rest-arg (binding ...) . body;; let-optional* rest-arg (binding ...) . body;;   macros used to bind optional arguments;;;; These two macros give you an optional argument interface that is;; very "Schemey" and introduces no fancy syntax. They are compatible;; with the scsh macros of the same name, but are slightly;; extended. Each of binding may be of one of the forms <var> or;; (<var> <default-value>). rest-arg should be the rest-argument of;; the procedures these are used from. The items in rest-arg are;; sequentially bound to the variable namess are given. When rest-arg;; runs out, the remaining vars are bound either to the default values;; or to `#f' if no default value was specified. rest-arg remains;; bound to whatever may have been left of rest-arg.;;(defmacro let-optional (REST-ARG BINDINGS . BODY)  (let-optional-template REST-ARG BINDINGS BODY 'let))(defmacro let-optional* (REST-ARG BINDINGS . BODY)  (let-optional-template REST-ARG BINDINGS BODY 'let*));; let-keywords rest-arg allow-other-keys? (binding ...) . body;; let-keywords* rest-arg allow-other-keys? (binding ...) . body;;   macros used to bind keyword arguments;;;; These macros pick out keyword arguments from rest-arg, but do not;; modify it. This is consistent at least with Common Lisp, which;; duplicates keyword args in the rest arg. More explanation of what;; keyword arguments in a lambda list look like can be found below in;; the documentation for lambda*.  Bindings can have the same form as;; for let-optional. If allow-other-keys? is false, an error will be;; thrown if anything that looks like a keyword argument but does not;; match a known keyword parameter will result in an error.;;(defmacro let-keywords (REST-ARG ALLOW-OTHER-KEYS? BINDINGS . BODY)  (let-keywords-template REST-ARG ALLOW-OTHER-KEYS? BINDINGS BODY 'let))(defmacro let-keywords* (REST-ARG ALLOW-OTHER-KEYS? BINDINGS . BODY)  (let-keywords-template REST-ARG ALLOW-OTHER-KEYS? BINDINGS BODY 'let*));; some utility procedures for implementing the various let-forms.(define (let-o-k-template REST-ARG BINDINGS BODY let-type proc)  (let ((bindings (map (lambda (x)			 (if (list? x)			     x			     (list x #f)))		       BINDINGS)))    `(,let-type ,(map proc bindings) ,@BODY)))(define (let-optional-template REST-ARG BINDINGS BODY let-type)    (if (null? BINDINGS)	`(begin ,@BODY)	(let-o-k-template REST-ARG BINDINGS BODY let-type			  (lambda (optional)			    `(,(car optional)			      (cond			       ((not (null? ,REST-ARG))				(let ((result (car ,REST-ARG)))				  ,(list 'set! REST-ARG					 `(cdr ,REST-ARG))				  result))			       (else				,(cadr optional))))))))(define (let-keywords-template REST-ARG ALLOW-OTHER-KEYS? BINDINGS BODY let-type)    (if (null? BINDINGS)	`(begin ,@BODY)	(let* ((kb-list-gensym (gensym "kb:G"))	       (bindfilter (lambda (key)			     `(,(car key)			       (cond				((assq ',(car key) ,kb-list-gensym)				 => cdr)				(else				 ,(cadr key)))))))	  `(let* ((ra->kbl ,rest-arg->keyword-binding-list)		  (,kb-list-gensym (ra->kbl ,REST-ARG ',(map							 (lambda (x) (symbol->keyword (if (pair? x) (car x) x)))							 BINDINGS)					    ,ALLOW-OTHER-KEYS?)))	     ,(let-o-k-template REST-ARG BINDINGS BODY let-type bindfilter)))))(define (rest-arg->keyword-binding-list rest-arg keywords allow-other-keys?)  (if (null? rest-arg)      '()      (let loop ((first (car rest-arg))		 (rest (cdr rest-arg))		 (accum '()))	(let ((next (lambda (a)		      (if (null? (cdr rest))			  a			  (loop (cadr rest) (cddr rest) a)))))	  (if (keyword? first)	      (cond	       ((memq first keywords)		(if (null? rest)		    (error "Keyword argument has no value.")		    (next (cons (cons (keyword->symbol first)				      (car rest)) accum))))	       ((not allow-other-keys?)		(error "Unknown keyword in arguments."))	       (else (if (null? rest)			 accum			 (next accum))))	      (if (null? rest)		  accum		  (loop (car rest) (cdr rest) accum)))))));; This is a reader extension to support the (deprecated) use of;; "#&optional" instead of "#:optional"(read-hash-extend #\& (lambda (c port)			(issue-deprecation-warning			 "`#&' is deprecated, use `#:' instead.")			(case (read port)			  ((optional) #:optional)			  ((key) #:key)			  ((rest) #:rest)			  ((allow-other-keys) #:allow-other-keys)			  (else (error "Bad #& value.")))));; lambda* args . body;;   lambda extended for optional and keyword arguments;;;; lambda* creates a procedure that takes optional arguments. These;; are specified by putting them inside brackets at the end of the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -