diff options
Diffstat (limited to 'Examples/guile/multivalue')
| -rw-r--r-- | Examples/guile/multivalue/Makefile | 18 | ||||
| -rw-r--r-- | Examples/guile/multivalue/example.c | 18 | ||||
| -rw-r--r-- | Examples/guile/multivalue/example.i | 32 | ||||
| -rw-r--r-- | Examples/guile/multivalue/runme.scm | 66 |
4 files changed, 134 insertions, 0 deletions
diff --git a/Examples/guile/multivalue/Makefile b/Examples/guile/multivalue/Makefile new file mode 100644 index 0000000..dc9c66d --- /dev/null +++ b/Examples/guile/multivalue/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' guile + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='my-guile' INTERFACE='$(INTERFACE)' guile_static + +clean:: + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' guile_clean + +check: all diff --git a/Examples/guile/multivalue/example.c b/Examples/guile/multivalue/example.c new file mode 100644 index 0000000..c9ebad1 --- /dev/null +++ b/Examples/guile/multivalue/example.c @@ -0,0 +1,18 @@ +void divide_l(int a, int b, int *quotient_p, int *remainder_p) +{ + *quotient_p = a/b; + *remainder_p = a%b; +} + +void divide_v(int a, int b, int *quotient_p, int *remainder_p) +{ + *quotient_p = a/b; + *remainder_p = a%b; +} + +void divide_mv(int a, int b, int *quotient_p, int *remainder_p) +{ + *quotient_p = a/b; + *remainder_p = a%b; +} + diff --git a/Examples/guile/multivalue/example.i b/Examples/guile/multivalue/example.i new file mode 100644 index 0000000..1353894 --- /dev/null +++ b/Examples/guile/multivalue/example.i @@ -0,0 +1,32 @@ +/* -*- c -*- */ + +%module example; + +%{ +void divide_l(int a, int b, int *quotient_p, int *remainder_p); +void divide_v(int a, int b, int *quotient_p, int *remainder_p); +void divide_mv(int a, int b, int *quotient_p, int *remainder_p); +%} + +/* Multiple values as lists. By default, if more than one value is to +be returned, a list of the values is created and returned; to switch +back to this behavior, use: */ +%values_as_list; + +void divide_l(int a, int b, int *OUTPUT, int *OUTPUT); + +/* Multiple values as vectors. By issueing: */ +%values_as_vector; +/* vectors instead of lists will be used. */ + +void divide_v(int a, int b, int *OUTPUT, int *OUTPUT); + +/* Multiple values for multiple-value continuations. + (This is the most elegant way.) By issueing: */ +%multiple_values; +/* multiple values are passed to the multiple-value + continuation, as created by `call-with-values' or the + convenience macro `receive'. (See the Scheme file.) */ + +void divide_mv(int a, int b, int *OUTPUT, int *OUTPUT); + diff --git a/Examples/guile/multivalue/runme.scm b/Examples/guile/multivalue/runme.scm new file mode 100644 index 0000000..73eb5af --- /dev/null +++ b/Examples/guile/multivalue/runme.scm @@ -0,0 +1,66 @@ +;;;; Show the three different ways to deal with multiple return values + +(use-modules (example)) + +;;; Multiple values as lists. By default, if more than one value is to +;;; be returned, a list of the values is created and returned. The +;;; procedure divide-l does so: + +(let* ((quotient/remainder (divide-l 37 5)) + ;; divide-l returns a list of the two values, so get them: + (quotient (car quotient/remainder)) + (remainder (cadr quotient/remainder))) + (display "37 divided by 5 is ") + (display quotient) + (display ", remainder ") + (display remainder) + (newline)) + +;;; Multiple values as vectors. You can get vectors instead of lists +;;; if you want: + +(let* ((quotient-remainder-vector (divide-v 40 7)) + ;; divide-v returns a vector of two values, so get them: + (quotient (vector-ref quotient-remainder-vector 0)) + (remainder (vector-ref quotient-remainder-vector 1))) + (display "40 divided by 7 is ") + (display quotient) + (display ", remainder ") + (display remainder) + (newline)) + +;;; Multiple values for multiple-value continuations. (The most +;;; elegant way.) You can get multiple values passed to the +;;; multiple-value continuation, as created by `call-with-values'. + +(call-with-values (lambda () + ;; the "producer" procedure + (divide-mv 91 13)) + (lambda (quotient remainder) + ;; the "consumer" procedure + (display "91 divided by 13 is ") + (display quotient) + (display ", remainder ") + (display remainder) + (newline))) + +;;; SRFI-8 has a very convenient macro for this construction: + +(use-modules (srfi srfi-8)) + +;;; If your Guile is too old, you can define the receive macro yourself: +;;; +;;; (define-macro (receive vars vals . body) +;;; `(call-with-values (lambda () ,vals) +;;; (lambda ,vars ,@body))) + +(receive (quotient remainder) + (divide-mv 111 19) ; the "producer" form + ;; In the body, `quotient' and `remainder' are bound to the two + ;; values. + (display "111 divided by 19 is ") + (display quotient) + (display ", remainder ") + (display remainder) + (newline)) + |
