|
|
1.1 root 1: .\" Copyright (c) 1980 Regents of the University of California.
2: .\" All rights reserved. The Berkeley software License Agreement
3: .\" specifies the terms and conditions for redistribution.
4: .\"
5: .\" @(#)ch8.n 6.2 (Berkeley) 5/14/86
6: .\"
7: ." $Header: ch8.n,v 1.4 83/07/27 15:12:22 layer Exp $
8: .Lc Functions,\ Fclosures,\ and\ Macros 8
9: .sh 2 valid\ function\ objects \n(ch 1
10: .pp
11: There are many different objects which can occupy the function field of
12: a symbol object.
13: Table 8.1, on the following page,
14: shows all of the possibilities, how to recognize them,
15: and where to look for documentation.
16: .(z
17: .sp 1v
18: .TS
19: box center ;
20: c | c | c .
21: informal name object type documentation
22: =
23: interpreted list with \fIcar\fP 8.2
24: lambda function \fIeq\fP to lambda
25: _
26: interpreted list with \fIcar\fP 8.2
27: nlambda function \fIeq\fP to nlambda
28: _
29: interpreted list with \fIcar\fP 8.2
30: lexpr function \fIeq\fP to lexpr
31: _
32: interpreted list with \fIcar\fP 8.3
33: macro \fIeq\fP to macro
34: _
35: fclosure vector with \fIvprop\fP 8.4
36: \fIeq\fP to fclosure
37: _
38: compiled binary with discipline 8.2
39: lambda or lexpr \fIeq\fP to lambda
40: function
41: _
42: compiled binary with discipline 8.2
43: nlambda function \fIeq\fP to nlambda
44: _
45: compiled binary with discipline 8.3
46: macro \fIeq\fP to macro
47: _
48: foreign binary with discipline 8.5
49: subroutine of \*(lqsubroutine\*(rq\*[\(dg\*]
50: _
51: foreign binary with discipline 8.5
52: function of \*(lqfunction\*(rq\*[\(dg\*]
53: _
54: foreign binary with discipline 8.5
55: integer function of \*(lqinteger-function\*(rq\*[\(dg\*]
56: _
57: foreign binary with discipline 8.5
58: real function of \*(lqreal-function\*(rq\*[\(dg\*]
59: _
60: foreign binary with discipline 8.5
61: C function of \*(lqc-function\*(rq\*[\(dg\*]
62: _
63: foreign binary with discipline 8.5
64: double function of \*(lqdouble-c-function\*(rq\*[\(dg\*]
65: _
66: foreign binary with discipline 8.5
67: structure function of \*(lqvector-c-function\*(rq\*[\(dg\*]
68: _
69: array array object 9
70: .TE
71: .tl ''Table 8.1''
72: .(f
73: \*[\(dg\*]Only the first character of the string is significant (i.e \*(lqs\*(rq
74: is ok for \*(lqsubroutine\*(rq)
75: .)f
76: .)z
77: .br
78: .sh 2 functions
79: .pp
80: The basic Lisp function is the lambda function.
81: When a lambda function is called, the actual arguments are
82: evaluated from left to right and are lambda-bound to the
83: formal parameters of the lambda function.
84: .pp
85: An nlambda function is usually used for functions which are invoked
86: by the user at top level.
87: Some built-in functions which evaluate their arguments in special ways are
88: also nlambdas (e.g \fIcond\fP, \fIdo\fP, \fIor\fP).
89: When an nlambda function is called, the list of unevaluated arguments
90: is lambda bound to the single formal parameter of the nlambda function.
91: .pp
92: Some programmers will use an nlambda function
93: when they are not sure how many arguments
94: will be passed.
95: Then, the first thing the nlambda function does is map \fIeval\fP over
96: the list of unevaluated arguments it has been passed.
97: This is usually the wrong thing to do, as it will not work compiled if
98: any of the arguments are local variables.
99: The solution is to use a lexpr.
100: When a lexpr function is called, the arguments
101: are evaluated and a fixnum whose value is
102: the number of arguments is lambda-bound to the single
103: formal parameter of the lexpr function.
104: The lexpr can then access the arguments using the \fIarg\fP function.
105: .pp
106: When a function is compiled,
107: .i special
108: declarations may be needed to
109: preserve its behavior.
110: An argument is not lambda-bound to the name of
111: the corresponding formal parameter
112: unless that formal parameter has been declared
113: .i special
114: (see \(sc12.3.2.2).
115: .pp
116: Lambda and lexpr functions both compile into a binary object with
117: a discipline of lambda.
118: However, a compiled lexpr still acts like an interpreted lexpr.
119: .sh 2 macros
120: .pp
121: An important feature of Lisp
122: is its ability to manipulate programs as data.
123: As a result of this, most Lisp implementations
124: have very powerful macro facilities.
125: The Lisp language's macro facility
126: can be used to incorporate popular features of the other
127: languages into Lisp.
128: For example, there are macro packages
129: which allow one to create records (ala Pascal)
130: and refer to elements of those records by the field names.
131: The
132: .i struct
133: package imported from Maclisp does this.
134: Another popular use for macros is to create more readable control
135: structures which expand into
136: .i cond ,
137: .i or
138: and
139: .i and .
140: One such example is the If macro.
141: It allows you to write
142: .sp 1v
143: .nf
144: .ft I
145: (If (equal numb 0) then (print 'zero) (terpr)
146: \ elseif (equal numb 1) then (print 'one) (terpr)
147: \ else (print '|I give up|))
148: .ft P
149: .sp 1v
150: which expands to
151: .sp 1v
152: .ft I
153: (cond
154: \ \ \ \ ((equal numb 0) (print 'zero) (terpr))
155: \ \ \ \ ((equal numb 1) (print 'one) (terpr))
156: \ \ \ \ (t (print '|I give up|)))
157: .ft P
158: .sp 1v
159: .fi
160: .sh 3 macro\ forms
161: .pp
162: A macro is a function which accepts a Lisp expression as input and returns
163: another Lisp expression.
164: The action the macro takes is called macro expansion.
165: Here is a simple example:
166: .sp 1v
167: .nf
168: \-> \fI(def first (macro (x) (cons 'car (cdr x))))\fP
169: first
170: \-> \fI(first '(a b c))\fP
171: a
172: \-> \fI(apply 'first '(first '(a b c)))\fP
173: (car '(a b c))
174: .fi
175: .sp 1v
176: The first input line defines a macro called
177: .i first .
178: Notice that the macro has one formal parameter, \fIx\fP.
179: On the second input line, we ask the interpreter to evaluate
180: \fI(first\ '(a\ b\ c))\fP.
181: .i Eval
182: sees that
183: .i first
184: has a function definition of type macro, so it evaluates
185: .i first 's
186: definition,
187: passing to
188: .i first ,
189: as an argument, the form
190: .i eval
191: itself
192: was trying to
193: evaluate: \fI(first\ '(a\ b\ c))\fP.
194: The
195: .i first
196: macro chops off the car of the argument with
197: .i cdr ,
198: cons' a
199: .i car
200: at the beginning of the list and returns \fI(car\ '(a\ b\ c))\fP,
201: which
202: .i eval
203: evaluates.
204: The value
205: .i a
206: is returned as the value of \fI(first\ '(a\ b\ c))\fP.
207: Thus whenever
208: .i eval
209: tries to evaluate a list whose car has a macro definition
210: it ends up doing (at least) two operations, the first of which
211: is a call to the macro
212: to let it macro expand the form, and the other is the evaluation of the
213: result of the macro.
214: The result of the macro may be yet another call to a macro, so
215: .i eval
216: may have to do even more evaluations until it can finally determine
217: the value of an expression.
218: One way to see how a macro will expand is to use
219: .i apply
220: as shown on the third input line above.
221: .sh +0 defmacro
222: .pp
223: The macro
224: .i defmacro
225: makes it easier to define macros because it allows you to name the arguments
226: to the macro call.
227: For example, suppose we find ourselves often writing code like
228: \fI(setq\ stack\ (cons\ newelt\ stack)\fP.
229: We could define a macro named \fIpush\fP to do this for us.
230: One way to define it is:
231: .nf
232: .sp 1v
233: \-> \fI(de\kAf push
234: \h'|\nAu'(macro (x) (list 'setq (caddr x) (list 'cons (cadr x) (caddr x)))))\fP
235: push
236: .fi
237: .sp 1v
238: then \fI(push\ newelt\ stack)\fP will expand to the form mentioned above.
239: The same macro written using defmacro would be:
240: .nf
241: .sp 1v
242: \->\fI\kA (defmacro push (value stack)
243: \h'|\nAu'(list 'setq ,stack (list 'cons ,value ,stack)))\fP
244: push
245: .fi
246: .sp 1v
247: Defmacro allows you to name the arguments of the macro call, and makes the
248: macro definition look more like a function definition.
249: .sh +0 the\ backquote\ character\ macro
250: .pp
251: The default syntax for
252: .Fr
253: has four characters with associated character macros.
254: One is semicolon for comments.
255: Two others are the backquote and comma which are
256: used by the backquote character
257: macro.
258: The fourth is the sharp sign macro described in the next section.
259: .pp
260: The backquote macro is used to create lists where many of the elements are
261: fixed (quoted).
262: This makes it very useful for creating macro definitions.
263: In the simplest case, a backquote acts just like a single quote:
264: .sp 1v
265: .nf
266: \->\fI`(a b c d e)\fP
267: (a b c d e)
268: .fi
269: .sp 1v
270: If a comma precedes an element of a backquoted list then that element is
271: evaluated and its value is put in the list.
272: .sp 1v
273: .nf
274: \->\fI(setq d '(x y z))\fP
275: (x y z)
276: \->\fI`(a b c ,d e)\fP
277: (a b c (x y z) e)
278: .fi
279: .sp 1v
280: If a comma followed by an at sign precedes an element in a backquoted list,
281: then that element is evaluated and spliced into the list with
282: .i append .
283: .nf
284: .sp 1v
285: \->\fI`(a b c ,@d e)\fP
286: (a b c x y z e)
287: .sp 1v
288: .fi
289: Once a list begins with a backquote, the commas may appear anywhere in the
290: list as this example shows:
291: .nf
292: .sp 1v
293: \->\fI`(a b (c d ,(cdr d)) (e f (g h ,@(cddr d) ,@d)))\fP
294: (a b (c d (y z)) (e f (g h z x y z)))
295: .sp 1v
296: .fi
297: It is also possible and sometimes even useful to use the
298: backquote macro within itself.
299: As a final demonstration of the backquote macro, we shall define the
300: first and push macros using all the power at our disposal: defmacro
301: and the backquote macro.
302: .sp 1v
303: .nf
304: \->\fI(defmacro first (list) `(car ,list))\fP
305: first
306: \->\fI(defmacro push (value stack) `(setq ,stack (cons ,value ,stack)))\fP
307: stack
308: .fi
309: .sh +0 sharp\ sign\ character\ macro
310: .pp
311: The sharp sign macro can perform a number of
312: different functions at read time.
313: The character directly following the sharp sign determines which function
314: will be done, and following Lisp s-expressions may serve as arguments.
315: .sh +1 conditional\ inclusion
316: .lp
317: If you plan to run one source file in more than one environment then
318: you may want to some pieces of code to be included or not included
319: depending on the environment.
320: The C language uses \*(lq#ifdef\*(lq and \*(lq#ifndef\*(rq for this
321: purpose, and Lisp uses \*(lq#+\*(rq and \*(lq#\-\*(rq.
322: The environment that the sharp sign macro checks is the
323: \fI(status\ features)\fP list which is initialized when the Lisp
324: system is built and which may be altered by
325: \fI(sstatus\ feature\ foo)\fP and \fI(sstatus\ nofeature\ bar)\fP
326: The form of conditional inclusion is
327: .br
328: .tl ''\fI#+when what\fP''
329: where
330: .i when
331: is either a symbol or an expression involving symbols and the functions
332: .i and ,
333: .i or ,
334: and
335: .i not .
336: The meaning is that
337: .i what
338: will only be read in if
339: .i when
340: is true.
341: A symbol in
342: .i when
343: is true only if it appears in the
344: .i (status\ features)
345: list.
346: .Eb
347: ; suppose we want to write a program which references a file
348: ; and which can run at ucb, ucsd and cmu where the file naming conventions
349: ; are different.
350: ;
351: \-> \fI(de\kAfun howold (name)
352: \h'|\nAu'\kC(terpr)
353: \h'|\nCu'\kB(load #\kA+(or ucb ucsd) "/usr/lib/lisp/ages.l"
354: \h'|\nAu'#+cmu "/usr/lisp/doc/ages.l")
355: \h'|\nBu'\kA(patom name)
356: \h'|\nBu'\kA(patom " is ")
357: \h'|\nAu'\kB(print (cdr (assoc name agefile)))
358: \h'|\nBu'\kA(patom "years old")
359: \h'|\nAu'(terpr))\fP
360: .Ee
361: The form
362: .br
363: .tl ''\fI#\-when what\fP''
364: is equivalent to
365: .br
366: .tl ''\fI#+(not when) what\fP''
367: .sh +0 fixnum\ character\ equivalents
368: .lp
369: When working with fixnum equivalents of characters, it is often hard to
370: remember the number corresponding to a character.
371: The form
372: .br
373: .tl ''\fI#/c\fP''
374: is equivalent to the fixnum representation of character c.
375: .Eb
376: ; a function which returns t if the user types y else it returns nil.
377: ;
378: \-> \fI(de\kBfun yesorno nil
379: \h'|\nBu'(progn \kA(ans)
380: \h'|\nAu'\kB(setq ans (tyi))
381: \h'|\nBu'(cond \kA((equal ans #/y) t)
382: \h'|\nAu'(t nil))))\fP
383: .Ee
384: .sh +0 read\ time\ evaluation
385: .lp
386: Occasionally you want to express a constant as a Lisp expression, yet you
387: don't want to pay the penalty of evaluating this expression each time it
388: is referenced.
389: The form
390: .br
391: .tl ''\fI#.expression\fP''
392: evaluates the expression at read time and returns its value.
393: .Eb
394: ; a function to test if any of bits 1 3 or 12 are set in a fixnum.
395: ;
396: \-> \fI(de\kCfun testit (num)
397: \h'|\nCu'(cond \kA(\kB(zerop (boole 1 num #.(+ (lsh 1 1) (lsh 1 3) (lsh 1 12))))
398: \h'|\nBu'nil)
399: \h'|\nAu'(t t)))\fP
400: .Ee
401: .sh 2 fclosures
402: .pp
403: Fclosures are a type of functional object.
404: The purpose is to remember the values of some variables
405: between invocations of the functional object and to protect this
406: data from being inadvertently overwritten by other Lisp functions.
407: Fortran programs usually exhibit this behavior for their variables.
408: (In fact, some versions of Fortran would require the
409: variables to be in COMMON).
410: Thus it is easy to write a linear congruent random number generator
411: in Fortran, merely by keeping the seed as a variable in the function.
412: It is much more risky to do so in Lisp, since any special variable you
413: picked, might be used by some other function.
414: Fclosures are an attempt to provide most of the same functionality as
415: closures in Lisp Machine Lisp, to users of
416: .Fr .
417: Fclosures are related to closures in this way:
418: .br
419: (fclosure '(a b) 'foo) <==>
420: .br
421: (let ((a a) (b b)) (closure '(a b) 'foo))
422: .sh 3 an\ example
423: .sp 1v
424: .in 0
425: .nf
426: .sz -2
427: .hl
428: % \fBlisp\fP
429: Franz Lisp, Opus 38.60
430: \->\fB(defun code (me count)
431: (print (list 'in x))
432: (setq x (+ 1 x))
433: (cond ((greaterp count 1) (funcall me me (sub1 count))))
434: (print (list 'out x)))\fP
435: code
436: \->\fB(defun tester (object count)
437: (funcall object object count) (terpri))\fP
438: tester
439: \->\fB(setq x 0)\fP
440: 0
441: \->\fB(setq z (fclosure '(x) 'code))\fP
442: fclosure[8]
443: \->\fB (tester z 3)\fP
444: (in 0)(in 1)(in 2)(out 3)(out 3)(out 3)
445: nil
446: \->\fBx\fP
447: 0
448: .hl
449: .fi
450: .sz +2
451: .sp 3v
452: .pp
453: The function \fIfclosure\fP creates a new object
454: that we will call an fclosure,
455: (although it is actually a vector).
456: The fclosure contains a functional object, and a set of symbols and
457: values for the symbols. In the above example, the fclosure functional
458: object is the function code.
459: The set of symbols and values just contains the symbol `x' and
460: zero, the value of `x' when the fclosure was created.
461: .lp
462: When an fclosure is funcall'ed:
463: .ip 1)
464: The Lisp system lambda binds the symbols in the fclosure to their values in the fclosure.
465: .ip 2)
466: It continues the funcall on the functional object of the fclosure.
467: .ip 3)
468: Finally, it un-lambda binds the symbols in the fclosure and at the
469: same time stores the current values of the symbols in the fclosure.
470: .sp 1v
471: .pp
472: Notice that the fclosure is saving the value of the symbol `x'.
473: Each time a fclosure is created, new space is allocated for saving
474: the values of the symbols. Thus if we execute fclosure again, over
475: the same function, we can have two independent counters:
476: .sp 1v
477: .in 0
478: .nf
479: .sz -2
480: .hl
481: \-> \fB(setq zz (fclosure '(x) 'code))\fP
482: fclosure[1]
483: \-> \fB(tester zz 2)\fP
484: (in 0)(in 1)(out 2)(out 2)
485: \-> \fB(tester zz 2)\fP
486: (in 2)(in 3)(out 4)(out 4)
487: \-> \fB(tester z 3)\fP
488: (in 3)(in 4)(in 5)(out 6)(out 6)(out 6)
489: .hl
490: .fi
491: .sz +2
492: .sp 3v
493: .sh 3 useful\ functions
494: .pp
495: Here are some quick some summaries of functions dealing with closures.
496: They are more formally defined in \(sc2.8.4.
497: To recap, fclosures are made by
498: \fI(fclosure 'l_vars 'g_funcobj)\fP.
499: l_vars is a list of symbols (not containing nil),
500: g_funcobj is any object that can be funcalled.
501: (Objects which can be funcalled, include compiled Lisp functions,
502: lambda expressions, symbols, foreign functions, etc.)
503: In general, if you want a compiled function to be closed over a
504: variable, you must declare the variable to be special within the function.
505: Another example would be:
506: .(l
507: (fclosure '(a b) #'(lambda (x) (plus x a)))
508: .)l
509: Here, the #' construction will make the compiler compile the lambda expression.
510: .pp
511: There are times when you want to share variables between fclosures.
512: This can be done if the fclosures are created at the same time using
513: \fIfclosure-list\fP.
514: The function \fIfclosure-alist\fP returns an assoc list giving
515: the symbols and values in the fclosure. The predicate
516: \fIfclosurep\fP returns t iff its argument is a fclosure.
517: Other functions imported from Lisp Machine Lisp are
518: .i symeval-in-fclosure,
519: .i let-fclosed,
520: and
521: .i set-in-fclosure.
522: Lastly, the function \fIfclosure-function\fP returns the function argument.
523: .sh 3 internal\ structure
524: .pp
525: Currently, closures are implemented as vectors, with property being the
526: symbol fclosure. The functional object is the first entry.
527: The remaining entries are structures which point to the symbols
528: and values for the closure, (with a reference count to determine
529: if a recursive closure is active).
530: .sh 2 foreign\ subroutines\ and\ functions
531: .pp
532: .Fr
533: has the ability to dynamically load object files produced by other compilers
534: and to call functions defined in those files.
535: These functions are called
536: .i foreign
537: functions.*
538: .(f
539: *This topic is also discussed in Report PAM-124 of the Center for
540: Pure and Applied Mathematics, UCB, entitled ``Parlez-Vous Franz?
541: An Informal Introduction to Interfacing Foreign Functions to Franz LISP'',
542: by James R. Larus
543: .)f
544: There are seven types of foreign functions.
545: They are characterized by
546: the type of result they return, and by differences in the interpretation
547: of their arguments.
548: They come from two families: a group suited for languages which pass
549: arguments by reference (e.g. Fortran), and a group suited for languages
550: which pass arguments by value (e.g. C).
551: .sp 1v
552: .lp
553: There are four types in the first group:
554: .ip \fBsubroutine\fP
555: This does not return anything.
556: The Lisp system
557: always returns t after calling a subroutine.
558: .ip \fBfunction\fP
559: This returns whatever the function returns.
560: This must be a valid Lisp object or it may cause the Lisp system to fail.
561: .ip \fBinteger-function\fP
562: This returns an integer which the Lisp system makes into a fixnum and returns.
563: .ip \fBreal-function\fP
564: This returns a double precision real number which the Lisp
565: system makes into a flonum and returns.
566: .sp 1v
567: .lp
568: There are three types in the second group:
569: .ip \fBc-function\fP
570: This is like an integer function, except for its different interpretation
571: of arguments.
572: .ip \fBdouble-c-function\fP
573: This is like a real-function.
574: .ip \fBvector-c-function\fP
575: This is for C functions which return a structure.
576: The first argument to such functions must be a vector (of type vectori),
577: into which the result is stored.
578: The second Lisp argument
579: becomes the first argument to the C function, and so on
580: .lp
581: A foreign function is accessed through a binary object just like a
582: compiled Lisp function.
583: The difference is that the discipline field of a binary object
584: for a foreign function is a string
585: whose first character is given in the following table:
586: .(b
587: .TS
588: box center ;
589: c | c .
590: letter type
591: =
592: s subroutine
593: _
594: f function
595: _
596: i integer-function
597: _
598: r real-function.
599: _
600: c c-function
601: _
602: v vector-c-function
603: _
604: d double-c-function
605: _
606: .TE
607: .)b
608: Two functions are provided for setting-up foreign functions.
609: .i Cfasl
610: loads an object file into the Lisp system and sets up one foreign
611: function binary object.
612: If there are more than one function in an object file,
613: .i getaddress
614: can be used to set up additional foreign function objects.
615: .pp
616: Foreign functions are called just like other functions, e.g
617: \fI(funname\ arg1\ arg2)\fP.
618: When a function in the Fortran group is called,
619: the arguments are evaluated and then examined.
620: List, hunk and symbol arguments are passed unchanged to
621: the foreign function.
622: Fixnum and flonum arguments are copied into a temporary location and
623: a pointer to the value is passed (this is because Fortran uses call
624: by reference and it is dangerous to modify the contents of a fixnum
625: or flonum which something else might point to).
626: If the argument is an array object,
627: the data field of the array object is
628: passed to the foreign function
629: (This is the easiest way to send large
630: amounts of data to and receive large amounts of data from a foreign
631: function).
632: If a binary object is an argument, the entry field of that object is
633: passed to the foreign function (the entry field is the address of a function,
634: so this amounts to passing a function as an argument).
635: .pp
636: When a function in the C group is called,
637: fixnum and flownum arguments are passed by value.
638: For almost all other arguments,
639: the address is merely provided to the C routine.
640: The only exception arises when you want to invoke a C routine
641: which expects a ``structure'' argument. Recall that a (rarely used)
642: feature of the C language is the ability to pass structures by value.
643: This copies the structure onto the stack. Since the Franz's nearest
644: equivalent to a C structure is a vector, we provide an escape clause
645: to copy the contents of an immediate-type vector by value. If the
646: property field of a vectori argument, is the symbol
647: \*(lqvalue-structure-argument\*(rq,
648: then the binary data of this immediate-type vector is copied
649: into the argument list of the C routine.
650: .pp
651: The method a foreign function uses to access the arguments provided
652: by Lisp is dependent on the language of the foreign function.
653: The following scripts demonstrate how how Lisp can interact with three
654: languages: C, Pascal and Fortran.
655: C and Pascal have pointer types and the first script shows how to use
656: pointers to extract information from Lisp objects.
657: There are two functions defined for each language.
658: The first (cfoo in C, pfoo in Pascal) is given four arguments, a
659: fixnum, a flonum-block array, a hunk of at least two
660: fixnums and a list of
661: at least two fixnums.
662: To demonstrate that the values were passed, each ?foo function prints
663: its arguments (or parts of them).
664: The ?foo function then modifies the second element of
665: the flonum-block array and returns a 3 to Lisp.
666: The second function (cmemq in C, pmemq in Pascal) acts just like the
667: Lisp
668: .i memq
669: function (except it won't work for fixnums whereas the lisp
670: .i memq
671: will work for small fixnums).
672: In the script, typed input is in
673: .b bold ,
674: computer output is in roman
675: and comments are in
676: .i italic.
677: .in 0
678: .nf
679: .sp 2v
680: .sz -2
681: .hl
682: \fIThese are the C coded functions \fP
683: % \fBcat ch8auxc.c\fP
684: /* demonstration of c coded foreign integer-function */
685:
686: /* the following will be used to extract fixnums out of a list of fixnums */
687: struct listoffixnumscell
688: { struct listoffixnumscell *cdr;
689: int *fixnum;
690: };
691:
692: struct listcell
693: { struct listcell *cdr;
694: int car;
695: };
696:
697: cfoo(a,b,c,d)
698: int *a;
699: double b[];
700: int *c[];
701: struct listoffixnumscell *d;
702: {
703: printf("a: %d, b[0]: %f, b[1]: %f\n", *a, b[0], b[1]);
704: printf(" c (first): %d c (second): %d\n",
705: *c[0],*c[1]);
706: printf(" ( %d %d ... )\n ", *(d->fixnum), *(d->cdr->fixnum));
707: b[1] = 3.1415926;
708: return(3);
709: }
710:
711: struct listcell *
712: cmemq(element,list)
713: int element;
714: struct listcell *list;
715: {
716: for( ; list && element != list->car ; list = list->cdr);
717: return(list);
718: }
719: .sp 2v
720: \fIThese are the Pascal coded functions \fP
721: % \fBcat ch8auxp.p\fP
722: type pinteger = ^integer;
723: realarray = array[0..10] of real;
724: pintarray = array[0..10] of pinteger;
725: listoffixnumscell = record
726: cdr : ^listoffixnumscell;
727: fixnum : pinteger;
728: end;
729: plistcell = ^listcell;
730: listcell = record
731: cdr : plistcell;
732: car : integer;
733: end;
734:
735: function pfoo ( var a : integer ;
736: var b : realarray;
737: var c : pintarray;
738: var d : listoffixnumscell) : integer;
739: begin
740: writeln(' a:',a, ' b[0]:', b[0], ' b[1]:', b[1]);
741: writeln(' c (first):', c[0]^,' c (second):', c[1]^);
742: writeln(' ( ', d.fixnum^, d.cdr^.fixnum^, ' ...) ');
743: b[1] := 3.1415926;
744: pfoo := 3
745: end ;
746:
747: { the function pmemq looks for the Lisp pointer given as the first argument
748: in the list pointed to by the second argument.
749: Note that we declare " a : integer " instead of " var a : integer " since
750: we are interested in the pointer value instead of what it points to (which
751: could be any Lisp object)
752: }
753: function pmemq( a : integer; list : plistcell) : plistcell;
754: begin
755: while (list <> nil) and (list^.car <> a) do list := list^.cdr;
756: pmemq := list;
757: end ;
758: .sp 2v
759: \fIThe files are compiled\fP
760: % \fBcc -c ch8auxc.c\fP
761: 1.0u 1.2s 0:15 14% 30+39k 33+20io 147pf+0w
762: % \fBpc -c ch8auxp.p\fP
763: 3.0u 1.7s 0:37 12% 27+32k 53+32io 143pf+0w
764: .sp 2v
765: % \fBlisp\fP
766: Franz Lisp, Opus 38.60
767: .ft I
768: .fi
769: First the files are loaded and we set up one foreign function binary.
770: We have two functions in each file so we must choose one to tell cfasl about.
771: The choice is arbitrary.
772: .ft P
773: .br
774: .nf
775: \->\fB (cfasl 'ch8auxc.o '_cfoo 'cfoo "integer-function")\fP
776: /usr/lib/lisp/nld -N -A /usr/local/lisp -T 63000 ch8auxc.o -e _cfoo -o /tmp/Li7055.0 -lc
777: #63000-"integer-function"
778: \->\fB (cfasl 'ch8auxp.o '_pfoo 'pfoo "integer-function" "-lpc")\fP
779: /usr/lib/lisp/nld -N -A /tmp/Li7055.0 -T 63200 ch8auxp.o -e _pfoo -o /tmp/Li7055.1 -lpc -lc
780: #63200-"integer-function"
781: .ft I
782: Here we set up the other foreign function binary objects
783: .ft P
784: \->\fB (getaddress '_cmemq 'cmemq "function" '_pmemq 'pmemq "function")\fP
785: #6306c-"function"
786: .ft I
787: .fi
788: We want to create and initialize an array to pass to the cfoo function.
789: In this case we create an unnamed array and store it in the value cell of
790: testarr.
791: When we create an array to pass to the Pascal program we will use a named
792: array just to demonstrate the different way that named and unnamed arrays
793: are created and accessed.
794: .br
795: .nf
796: .ft P
797: \->\fB (setq testarr (array nil flonum-block 2))\fP
798: array[2]
799: \->\fB (store (funcall testarr 0) 1.234)\fP
800: 1.234
801: \->\fB (store (funcall testarr 1) 5.678)\fP
802: 5.678
803: \->\fB (cfoo 385 testarr (hunk 10 11 13 14) '(15 16 17))\fP
804: a: 385, b[0]: 1.234000, b[1]: 5.678000
805: c (first): 10 c (second): 11
806: ( 15 16 ... )
807: 3
808: .ft I
809: .fi
810: Note that cfoo has returned 3 as it should.
811: It also had the side effect of changing the second value of the array to
812: 3.1415926 which check next.
813: .br
814: .nf
815: .ft P
816: \->\fB (funcall testarr 1)\fP
817: 3.1415926
818: .sp 2v
819: .fi
820: .ft I
821: In preparation for calling pfoo we create an array.
822: .ft P
823: .nf
824: \->\fB (array test flonum-block 2)\fP
825: array[2]
826: \->\fB (store (test 0) 1.234)\fP
827: 1.234
828: \->\fB (store (test 1) 5.678)\fP
829: 5.678
830: \->\fB (pfoo 385 (getd 'test) (hunk 10 11 13 14) '(15 16 17))\fP
831: a: 385 b[0]: 1.23400000000000E+00 b[1]: 5.67800000000000E+00
832: c (first): 10 c (second): 11
833: ( 15 16 ...)
834: 3
835: \->\fB (test 1)\fP
836: 3.1415926
837: .sp 1v
838: \fI Now to test out the memq's
839: \-> \fB(cmemq 'a '(b c a d e f))\fP
840: (a d e f)
841: \-> \fB(pmemq 'e '(a d f g a x))\fP
842: nil
843: .hl
844: .fi
845: .sz +2
846: .sp 3v
847: .pp
848: The Fortran example will be much shorter since in Fortran
849: you can't follow pointers
850: as you can in other languages.
851: The Fortran function ffoo is given three arguments: a fixnum, a
852: fixnum-block array and a flonum.
853: These arguments are printed out to verify that they made it and
854: then the first value of the array is modified.
855: The function returns a double precision value which is converted to a flonum
856: by lisp and printed.
857: Note that the entry point corresponding to the Fortran function ffoo is
858: _ffoo_ as opposed to the C and Pascal convention of preceding the name with
859: an underscore.
860: .sp 1v
861: .in 0
862: .nf
863: .sz -2
864: .hl
865:
866: % \fBcat ch8auxf.f\fP
867: double precision function ffoo(a,b,c)
868: integer a,b(10)
869: double precision c
870: print 2,a,b(1),b(2),c
871: 2 format(' a=',i4,', b(1)=',i5,', b(2)=',i5,' c=',f6.4)
872: b(1) = 22
873: ffoo = 1.23456
874: return
875: end
876: % \fBf77 -c ch8auxf.f\fP
877: ch8auxf.f:
878: ffoo:
879: 0.9u 1.8s 0:12 22% 20+22k 54+48io 158pf+0w
880: % \fBlisp\fP
881: Franz Lisp, Opus 38.60
882: \-> \fB(cfasl 'ch8auxf.o '_ffoo_ 'ffoo "real-function" "-lF77 -lI77")\fP
883: /usr/lib/lisp/nld -N -A /usr/local/lisp -T 63000 ch8auxf.o -e _ffoo_
884: -o /tmp/Li11066.0 -lF77 -lI77 -lc
885: #6307c-"real-function"
886: .sp 1v
887: \-> \fB(array test fixnum-block 2)\fP
888: array[2]
889: \->\fB (store (test 0) 10)\fP
890: 10
891: \-> \fB(store (test 1) 11)\fP
892: 11
893: \-> \fB(ffoo 385 (getd 'test) 5.678)\fP
894: a= 385, b(1)= 10, b(2)= 11 c=5.6780
895: 1.234559893608093
896: \-> \fB(test 0)\fP
897: 22
898:
899: .hl
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.