home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / microcode / sample.c < prev    next >
C/C++ Source or Header  |  1999-01-02  |  6KB  |  143 lines

  1. /* -*-C-*-
  2.  
  3. Copyright (c) 1987, 1988, 1989, 1999 Massachusetts Institute of Technology
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or (at
  8. your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful, but
  11. WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. /* $Id: sample.c,v 9.26 1999/01/02 06:11:34 cph Exp $ */
  21.  
  22. /* This file is intended to help you find out how to write primitives.
  23.    Many concepts needed to write primitives can be found by looking
  24.    at actual primitives in the system.  Hence this file will often
  25.    ask you to look at other files that contain system primitives.  */
  26.  
  27. /* Files that contain primitives must have the following includes
  28.    near the top of the file.  */
  29. #include "scheme.h"
  30. #include "prims.h"
  31.  
  32. /* Scheme.h supplies useful macros that are used throughout the
  33.    system, and prims.h supplies macros that are used in defining
  34.    primitives.  */
  35.  
  36. /* To make a primitive, you must use the macro DEFINE_PRIMITIVE
  37.    with six arguments, followed by the body of C source code
  38.    that you want the primitive to execute.
  39.    The six arguments are:
  40.    1. A string representing the scheme name that you want to identify
  41.       this primitive with.
  42.    2. The name you want to give to this body of code (a C procedure
  43.       name).  By convention, all such names begin with `Prim_'.
  44.    3. The minimum number of arguments that this scheme primitive
  45.       should receive.  Currently this is not implemented and should be
  46.       the same as the maximum number of arguments (or 0 if the maximum
  47.       is the special symbol LEXPR).
  48.    4. The maximum number of arguments that this scheme primitive
  49.       should receive.  If this primitive will take any number of
  50.       arguments, use LEXPR here.
  51.    5. A documentation string, or 0 meaning no documentation.
  52.  
  53.    The value returned by the body of code following the
  54.    DEFINE_PRIMITIVE is the value of the scheme primitive.  Note that
  55.    this must be a SCHEME_OBJECT (with type tag and datum
  56.    field), and not an arbitrary C object.
  57.  
  58.    As an example, here is a primitive that takes no arguments and
  59.    always returns SHARP_F (SHARP_F is defined in scheme.h and
  60.    identical to the scheme object #F. SHARP_T is identical to the
  61.    scheme object #T).  */
  62.  
  63. DEFINE_PRIMITIVE ("RETURN-SHARP-F", Prim_return_sharp_f, 0, 0, 0)
  64. {
  65.   PRIMITIVE_HEADER (0);
  66.  
  67.   PRIMITIVE_RETURN (SHARP_F);
  68. }
  69.  
  70. /* This will create the primitive RETURN-SHARP-F and when a new Scheme
  71.    is made (with the Makefile properly edited to include this file),
  72.    evaluating (make-primitive-procedure 'return-sharp-f) will return a
  73.    primitive procedure that when called with no arguments, will return
  74.    #F.  */
  75.  
  76. /* Here's another example that shows the use of the `ARG_REF' macro to
  77.    get one of the arguments to the primitive: */
  78.  
  79. DEFINE_PRIMITIVE ("IDENTITY", Prim_identity, 1, 1, 0)
  80. {
  81.   PRIMITIVE_HEADER (1);
  82.  
  83.   PRIMITIVE_RETURN (ARG_REF (1));
  84. }
  85.  
  86. /* Some primitives may have to allocate space on the heap in order
  87.    to return lists or vectors.  There are two things of importance to
  88.    note here.  First, the primitive is responsible for making sure
  89.    that there is enough space on the heap for the new structure that
  90.    is being made.  For instance, in making a PAIR, two words on the
  91.    heap are used, one to point to the CAR, one for CDR.  The macro
  92.    Primitive_GC_If_Needed is supplied to let you check if there is
  93.    room on the heap.  Primitive_GC_If_Needed takes one argument which
  94.    is the amount of space you would like to allocate.  If there is not
  95.    enough space on the heap, a garbage collection happens and
  96.    afterwards the primitive is restarted with the same arguments. The
  97.    second thing to notice is that the primitive is responsible for
  98.    updating Free according to how many words of storage it has used
  99.    up.  Note that the primitive is restarted, not continued, thus any
  100.    side effects must be done after the heap overflow check since
  101.    otherwise they would be done twice.
  102.  
  103.    A pair is object which has a type TC_LIST and points to the first
  104.    element of the pair.  The macro MAKE_POINTER_OBJECT takes a type
  105.    code and an address or data and returns a scheme object with that
  106.    type code and that address or data.  See scheme.h and the files
  107.    included there for the possible type codes.  The following is the
  108.    equivalent of CONS and takes two arguments and returns the pair
  109.    which contains both arguments. For further examples on heap
  110.    allocation, see the primitives in "list.c", "hunk.c" and
  111.    "vector.c".  */
  112.  
  113. DEFINE_PRIMITIVE ("NEW-CONS", Prim_new_cons, 2, 2, 0)
  114. {
  115.   PRIMITIVE_HEADER (2);
  116.   PRIMITIVE_RETURN (cons ((ARG_REF (1)), (ARG_REF (2))));
  117. }
  118.  
  119. /* The following primitive takes three arguments and returns a list
  120.    of them.  Note how the CDR of the first two pairs points
  121.    to the next pair.  Also, scheme objects are of type SCHEME_OBJECT
  122.    (defined in object.h).  Note that the result returned can be
  123.    held in a temporary variable even before the contents of the
  124.    object are stored in heap.  */
  125.  
  126. DEFINE_PRIMITIVE ("WHY-SHOULDNT-THE-NAME-BE-RANDOM?", Prim_utterly_random, 3, 3, 0)
  127. {
  128.   PRIMITIVE_HEADER (3);
  129.   PRIMITIVE_RETURN
  130.     (cons ((ARG_REF (1)),
  131.        (cons ((ARG_REF (2)),
  132.           (cons ((ARG_REF (3)),
  133.              EMPTY_LIST))))));
  134. }
  135.  
  136. /* Here is a primitive that tries to add 3 to its argument.  */
  137.  
  138. DEFINE_PRIMITIVE ("3+", Prim_add_3, 1, 1, 0)
  139. {
  140.   PRIMITIVE_HEADER (1);
  141.   PRIMITIVE_RETURN (long_to_integer ((arg_integer (1)) + 3));
  142. }
  143.