Annotation of researchv10dc/cmd/icon/docs/tr86-12.roff, revision 1.1.1.1

1.1       root        1: .so tmac.tr
                      2: .DA "May 6, 1986"
                      3: .TR 86-12
                      4: .Gi
                      5: .TL
                      6: Personalized Interpreters for Version 6.0 of Icon
                      7: .AU
                      8: Ralph E. Griswold
                      9: .AE
                     10: .tr *\(**
                     11: .NH
                     12: Introduction
                     13: .PP
                     14: Despite the fact that the Icon programming language has a large repertoire
                     15: of functions and operations for string and list manipulation, as
                     16: well as for more conventional computations [1], users frequently
                     17: need to extend that repertoire. While many extensions can be
                     18: written as procedures that build on the existing repertoire, there
                     19: are some kinds of extensions for which this approach is unacceptably
                     20: inefficient, inconvenient, or simply impractical.
                     21: .PP
                     22: Icon itself is written C and its built-in functions
                     23: are written as corresponding C functions. Thus, the natural way to
                     24: extend Icon's computational repertoire is to add new C functions to it.
                     25: .PP
                     26: The Icon system is organized so that this is comparatively easy to do.
                     27: Adding a new function
                     28: does not require changes to the Icon translator,
                     29: since all functions have a common syntactic form. An entry must be made in
                     30: a table that is used by the linker and the run-time system in order to
                     31: identify built-in functions and connect references to them to the
                     32: code itself.
                     33: .PP
                     34: One method of adding new functions to Icon
                     35: is to
                     36: add the corresponding C functions to the Icon system itself
                     37: and to rebuild the entire system. This approach is impractical
                     38: for many applications. If the extensions are not of general
                     39: interest, it is inappropriate to include them in the public
                     40: version of Icon. On the other hand, Icon is a large and complicated system,
                     41: and having many private versions may create serious problems of
                     42: maintenance and disk usage. Furthermore, rebuilding the Icon system
                     43: is expensive. This approach therefore
                     44: may be impractical in a situation
                     45: such as a class in which students implement their own versions
                     46: of an extension.
                     47: .PP
                     48: To remedy these problems, a mechanism for building ``personalized
                     49: interpreters'' is included in \*U implementations of Icon.
                     50: This mechanism
                     51: .Un
                     52: allows a user to add C functions and to build a corresponding
                     53: interpreter quickly, easily, and without the necessity to have
                     54: a copy of the source code for the entire Icon system.
                     55: .PP
                     56: To construct a personalized interpreter, the user must perform
                     57: a one-time set up that copies relevant source files to a
                     58: directory specified by the user and builds the nucleus of a run-time system. Once this is
                     59: done, the user can add and modify C functions and include them
                     60: in the personalized run-time system with little effort.
                     61: .PP
                     62: Since the linker must know the names of built-in functions,
                     63: a personalized linker also is constructed. In order to run
                     64: Icon programs in a self-contained personalized run-time system,
                     65: personalized versions of the translator, \*Mpitran\fR, and the
                     66: command processor, \*Mpicont\fR,
                     67: are provided also.
                     68: .PP
                     69: The modifications that can be made to Icon via a personalized
                     70: interpreter essentially are limited to the run-time system: the
                     71: addition of new functions, modifications to existing functions
                     72: and operations, and modifications and additions to support routines. There
                     73: is no provision for changing the syntax of Icon, incorporating
                     74: new operators, keyword, or control structures.
                     75: .NH
                     76: Building and Using a Personalized Interpreter
                     77: .NH 2
                     78: Setting Up a Personalized Interpreter System
                     79: .PP
                     80: To set up a personalized interpreter, a new directory should
                     81: be created solely for the use of the interpreter; otherwise
                     82: files may be accidentally destroyed by the setup process.
                     83: For the purpose of example, suppose this directory is
                     84: named \*Mmyicon\fR. The setup consists of
                     85: .Ds
                     86: mkdir myicon
                     87: cd myicon
                     88: icon_pi
                     89: .De
                     90: Note that \*Micon_pi\fR must be run from the area in which the personalized
                     91: interpreter is to be built.
                     92: The
                     93: location of \*Micon_pi\fR may vary from site to site.
                     94: .PP
                     95: The shell script \*Micon_pi\fR constructs three subdirectories:
                     96: \*Mh\fR, \*Mstd\fR, and \*Mpi\fR. The subdirectory \*Mh\fR
                     97: contains header files that are needed in C routines. The subdirectory
                     98: \*Mstd\fR contains the machine-independent portions of the Icon system that are needed
                     99: to build a personalized interpreter.
                    100: The subdirectory \*Mpi\fR
                    101: contains a \*MMakefile\fR for building a personalized interpreter
                    102: and also is the place where source code for new C functions normally
                    103: resides. Thus, work on the personalized interpreter is done in
                    104: \*Mmyicon/pi\fR.
                    105: .PP
                    106: The \*MMakefile\fR that is constructed by \*Micon_pi\fR
                    107: contains two definitions to facilitate building personalized
                    108: interpreters:
                    109: .RS
                    110: .IP \*MOBJS\fR .5i
                    111: a list of object modules that are to be added to or replaced
                    112: in the run-time system. \*MOBJS\fR initially is empty.
                    113: .IP \*MLIB\fR
                    114: a list of library options that are used when the run-time system
                    115: is built. \*MLIB\fR initially is empty, but the math library is
                    116: loaded as a normal part of building the run-time system.
                    117: .RE
                    118: .LP
                    119: See the listing of the generic version of this \*MMakefile\fR in
                    120: Appendix A.
                    121: .NH 2
                    122: Building a Personalized Interpreter
                    123: .PP
                    124: Performing a \fImake\fR in \*Mmyicon/pi\fR creates four files
                    125: in \*Mmyicon\fR:
                    126: .Ds
                    127: .ta 1i
                    128: picont \fRcommand processor\*M
                    129: pilink \fRlinker\*M
                    130: piconx \fRrun-time system\*M
                    131: piconx.hdr     \fRheader file for linker output\*M
                    132: .De
                    133: A link to \*Mpicont\fR also is constructed in \*Mmyicon/pi\fR so that
                    134: the new personalized interpreter can be tested in the directory in
                    135: which it is made.
                    136: .PP
                    137: The file \*Mpicont\fR normally is built only on the first \fImake\fR. The
                    138: file \*Mpilink\fR is built on the first \fImake\fR and is
                    139: rebuilt whenever the repertoire of built-in functions is changed
                    140: as a result of modifications to \*Mh/fdef.h\fR.
                    141: The file \*Mpiconx\fR is rebuilt whenever the source code in the
                    142: run-time system is changed.
                    143: .PP
                    144: The user of the personalized interpreter uses \*Mpicont\fR in
                    145: the same fashion that the standard \*Micont\fR is used.
                    146: (Note that the accidental use of \*Micont\fR in place of
                    147: \*Mpicont\fR may produce mysterious results.)
                    148: In turn, \*Mpicont\fR translates a source program using
                    149: \*Mpitran\fR and links it using \*Mpilink\fR.
                    150: The resulting icode file uses \*Mpiconx\fR.
                    151: .PP
                    152: The relocation bits and symbol tables in
                    153: \*Mpiconx\fR can be removed by
                    154: .Ds
                    155: make Stripx
                    156: .De
                    157: in \*Mmyicon/pi\fR. This reduces the size of this file substantially
                    158: but may interfere with debugging.
                    159: .PP
                    160: If a \fImake\fR is performed in \*Mmyicon/pi\fR before any
                    161: run-time files are added or modified, the resulting personalized
                    162: interpreter is identical to the standard one. Such a \fImake\fR can
                    163: be performed to verify that the personalized interpreter system
                    164: is performing properly.
                    165: .NH 2
                    166: Adding a New Function
                    167: .PP
                    168: To add a new function to the personalized interpreter, it is first
                    169: necessary to provide the C code, adhering to the conventions and
                    170: data structures used throughout Icon. Some examples of
                    171: C functions are included in Appendix B
                    172: of this report. The source code for several such functions is contained in
                    173: \*Mv6/pi/pil\fR, where \*Mv6\fR is the root of the Icon system.
                    174: The directory
                    175: \*Mv6/src/iconx\fR contains the source code for the standard
                    176: functions, which also can be used as models for new ones.
                    177: .PP
                    178: Suppose that \*Mgetenv\fR from \*Mv6/pi/pil\fR is to be
                    179: added to a personalized interpreter.
                    180: The source code can be obtained by
                    181: .Ds
                    182: cp v6/pi/pil/getenv.c myicon/pi
                    183: .De
                    184: (Note that the actual paths depend on the
                    185: local hierarchy.)
                    186: .PP
                    187: Three things now need to be done to
                    188: incorporate this function in the personalized interpreter:
                    189: .IP 1.
                    190: Add a line consisting of
                    191: .Ds
                    192: FncDef(getenv)
                    193: .De
                    194: to \*Mmyicon/h/fdef.h\fR in proper alphabetical order.
                    195: This causes the linker and the run-time system to know about the new function.
                    196: .IP 2.
                    197: Add \*Mgetenv.o\fR to the definition of \*MOBJS\fR in
                    198: \*Mmyicon/pi/Makefile\fR.
                    199: This causes \*Mgetenv.c\fR to be compiled and the resulting
                    200: object file to be loaded with the run-time system when a \fImake\fR is performed.
                    201: .IP 3.
                    202: Perform a \fImake\fR in \*Mmyicon/pi\fR. The result is
                    203: new versions of \*Mpilink\fR and \*Mpiconx\fR in \*Mmyicon\fR.
                    204: .LP
                    205: The function \*Mgetenv\fR now can be used like any other built-in
                    206: function.
                    207: .PP
                    208: More than one function can be included in a single source file.
                    209: See \*Mmath.c\fR in Appendix B.
                    210: To incorporate these functions in
                    211: a personalized interpreter, \*MFncDef\fR entries should be
                    212: made for each function in \*Mmath.c\fR and \*Mmath.o\fR should be added to
                    213: \*MOBJS\fR.
                    214: .NH 2
                    215: Modifying the Existing Run-Time System
                    216: .PP
                    217: The use of personalized interpreters is not limited to the addition
                    218: of new functions. Any module in the standard run-time system can
                    219: be modified as well.
                    220: .PP
                    221: To modify an existing portion of the Icon run-time system,
                    222: copy the source code file from \*Mv6/src/iconx\fR to \*Mmyicon/pi\fR.
                    223: (Source code for a few run-time routines is placed in \*Mmyicon/std\fR
                    224: when a personalized interpreter is set up. Check this directory
                    225: first and use that file, if appropriate, rather than making
                    226: another copy in \*Mmyicon/pi\fR.) When a source-code file in
                    227: \*Mmyicon/pi\fR has been modified, place it in the \*MOBJS\fR
                    228: list just like a new file and perform a \fImake\fR. Note that
                    229: an entire module must be replaced, even if a change is made to
                    230: only one routine.
                    231: Any module that is replaced must contain all the global variables in
                    232: the original module to prevent \fIld(1)\fR from also loading the
                    233: original module. There is no way to delete routines from the run-time
                    234: system.
                    235: .PP
                    236: The directory \*Mmyicon/h\fR contains header files that are included
                    237: in various source-code files.
                    238: The file \*Mmyicon/h/rt.h\fR contains declarations and definitions that
                    239: are used throughout the run-time system. This is where the declaration
                    240: for the structure of a new type of data object would be placed.
                    241: .PP
                    242: Care
                    243: must be taken when modifying header files not to make changes that
                    244: would produce inconsistencies between previously compiled components
                    245: of the Icon run-time system and new ones.
                    246: .SH
                    247: Reference
                    248: .IP 1.
                    249: Griswold, Ralph E. and Griswold, Madge T. \fIThe Icon Programming
                    250: Language\fR. Prentice-Hall, Inc., Englewood Cliffs, New Jersey. 1983.
                    251: .am Ds
                    252: .ps 8
                    253: .vs 9
                    254: ..
                    255: .am De
                    256: .ps 10
                    257: .vs 12
                    258: ..
                    259: .de Ta
                    260: .ta .8i +.8i +.8i +.8i +.8i +.8i +.8i +.8i
                    261: ..
                    262: .Ap "Appendix A \(em Makefile for Personalized Interpreters"
                    263: .sp
                    264: .PP
                    265: The ``generic'' \*MMakefile\fR for personalized interpreters follows.
                    266: A copy, with the
                    267: value of \*MDir\fR filled in and appropriate definitions for the flags,
                    268: is placed in \*Mmyicon/pi\fR when \*Micon_pi\fR is run.
                    269: .Ds
                    270: Dir=
                    271: .Dd
                    272: RHDRS= ../h/rt.h ../h/config.h ../h/cpuconf.h ../h/memsize.h
                    273: #
                    274: #  To add or replace object files, add their names to the OBJS list below.
                    275: #  For example, to add nfncs.o and iolib.o, use:
                    276: #
                    277: #      OBJS=nfncs.o iolib.o         (this is a sample line)
                    278: #
                    279: #  For each object file added to OBJS, add a dependency line to reflect files
                    280: #  that are depended on.  In general, new functions depend on $(RHDRS).
                    281: #  For example, if nfncs.c contains new functions, use
                    282: #      
                    283: #      nfncs.o:        $(RHDRS)
                    284: #
                    285: .Dd
                    286: OBJS=
                    287: LIB=
                    288: .Dd
                    289: RTOBJS=../std/rconv.o ../std/idata.o $(OBJS)
                    290: .Dd
                    291: Pi:    ../picont ../piconx ../pilink ../piconx.hdr
                    292: .Dd
                    293: \&../picont: ../std/icont.c ../h/config.h
                    294:        rm -f ../picont picont
                    295:        $(CC) $(CFLAGS) -o ../picont -DItran="\e"$(Dir)/pitran\e""\e
                    296:                -DIconx="\e"$(Dir)/piconx\e"" \e
                    297:                -DIlink="\e"$(Dir)/pilink\e""  ../std/icont.c
                    298:        strip ../picont
                    299:        ln ../picont picont
                    300: .Dd
                    301: \&../pilink: ../std/linklib ../std/builtin.o ../std/ilink.o
                    302:        $(CC) $(LDFLAGS) -o ../pilink ../std/builtin.o ../std/ilink.o\e
                    303:                 ../std/linklib
                    304:        strip ../pilink
                    305: .Dd
                    306: \&../std/ixhdr.o:      ../h/config.h
                    307:        cd ../std;      $(CC) -c $(XCFLAGS) -DIconx="\e"$(Dir)/piconx\e"" ixhdr.c
                    308: .Dd
                    309: \&../piconx.hdr:       ../std/ixhdr.o
                    310:        $(CC) $(XLDFLAGS) ../std/ixhdr.o -o ../piconx.hdr
                    311:        strip ../piconx.hdr
                    312: .Dd
                    313: \&../piconx: ../std/rtlib $(RTOBJS)
                    314:        $(CC) $(LDFLAGS) -o ../piconx $(RTOBJS) ../std/rtlib $(LIB) -lm
                    315:        
                    316: \&../std/idata.o:              $(RHDRS) ../h/fdef.h
                    317:        cd ../std;      $(CC) -c $(CFLAGS) idata.c
                    318: .Dd
                    319: \&../std/rconv.o:              $(RHDRS) ../h/fdef.h
                    320:        cd ../std;      $(CC) -c $(CFLAGS) rconv.c
                    321: .Dd
                    322: \&../std/builtin.o:    ../std/ilink.h ../h/config.h ../h/fdef.h
                    323:        cd ../std;      $(CC) -c $(CFLAGS) builtin.c
                    324: .Dd
                    325: \&../std/ilink.o:              ../std/ilink.h ../h/config.h ../h/header.h ../h/paths.h
                    326:        cd ../std;      $(CC) -c $(CFLAGS) -DHeader="\e"$(Dir)/piconx.hdr\e""  ilink.c
                    327: .Dd
                    328: Stripx:        ../piconx
                    329:        strip ../piconx
                    330: .De
                    331: .Ap "Appendix B \(em Sample C Functions"
                    332: .sp
                    333: .SH
                    334: getenv.c:
                    335: .LP
                    336: .de Ta
                    337: .ta 3i
                    338: ..
                    339: .Ds
                    340: .ta .8i
                    341: /*
                    342:  *     GETENV
                    343:  *
                    344:  *     Get values of environment variables.
                    345:  *
                    346:  *     Stephen B. Wampler
                    347:  *
                    348:  *     Last modified 5/2/86 by Ralph E. Griswold
                    349:  *
                    350:  */
                    351: .Dd
                    352: #include "../h/rt.h"
                    353: .Dd
                    354: /*
                    355:  * getenv(s) - return contents of environment variable s
                    356:  */
                    357: .Dd
                    358: FncDcl(getenv,\*b1)
                    359:    {
                    360:    register char *p;
                    361:    register int len;
                    362:    char sbuf\^[256];
                    363:    extern char *getenv();
                    364:    extern char *alcstr();
                    365: .Dd
                    366:    if (!Qual(arg1))                    /* check legality of argument */
                    367:       runerr(103, &arg1);
                    368:    if (StrLen(arg1) \*(<= 0 || StrLen(arg1) \*(>= MaxCvtLen)
                    369:       runerr(401, &arg1);
                    370:    qtos(&arg1, sbuf);                  /* convert argument to C-style string */
                    371: .Dd
                    372:    if ((p = getenv(sbuf)) != NULL) {   /* get environment variable */
                    373:       len = strlen(p);
                    374:       strreq(len);
                    375:       StrLen(arg0) = len;
                    376:       StrLoc(arg0) = alcstr(p, len);
                    377:       Return;
                    378:       }
                    379:    else                                        /* fail if variable not in environment */
                    380:       Fail;
                    381:    }
                    382: .De
                    383: .bp
                    384: .SH
                    385: math.c:
                    386: .LP
                    387: .Ds
                    388: .ta .8i
                    389: /*
                    390:  *     MATH
                    391:  *
                    392:  *     Miscellaneous math functions.
                    393:  *
                    394:  *     Ralph E. Griswold
                    395:  *
                    396:  *     Last modified 5/2/86
                    397:  *
                    398:  */
                    399: .Dd
                    400: #include "../h/rt.h"
                    401: #include <errno.h>
                    402: .Dd
                    403: int errno;
                    404: /*
                    405:  * exp(x)
                    406:  */
                    407: FncDcl(exp,\*b1)
                    408:    {
                    409:    int t;
                    410:    double y;
                    411:    union numeric r;
                    412:    double exp();
                    413:    
                    414:    if ((t = cvreal(&arg1, &r)) == NULL) runerr(102, &arg1);
                    415:    y = exp(r.real);
                    416:    if (errno == ERANGE) runerr(252, NULL);
                    417:    mkreal(y,\*b&arg0);
                    418:    Return;
                    419:    }
                    420: .Dd
                    421: /*
                    422:  * log(x)
                    423:  */
                    424: FncDcl(log,\*b1)
                    425:    {
                    426:    int t;
                    427:    double y;
                    428:    union numeric r;
                    429:    double log();
                    430:    
                    431:    if ((t = cvreal(&arg1, &r)) == NULL) runerr(102, &arg1);
                    432:    y = log(r.real);
                    433:    if (errno == EDOM) runerr(251, NULL);
                    434:    mkreal(y,\*b&arg0);
                    435:    Return;
                    436:    }
                    437: .Dd
                    438: /*
                    439:  * log10(x)
                    440:  */
                    441: FncDcl(log10,\*b1)
                    442:    {
                    443:    int t;
                    444:    double y;
                    445:    union numeric r;
                    446:    double log10();
                    447:    
                    448:    if ((t = cvreal(&arg1, &r)) == NULL) runerr(102, &arg1);
                    449:    y = log10(r.real);
                    450:    if (errno == EDOM) runerr(251, NULL);
                    451:    mkreal(y,\*b&arg0);
                    452:    Return;
                    453:    }
                    454: .Dd
                    455: /*
                    456:  * sqrt(x)
                    457:  */
                    458: FncDcl(sqrt,\*b1)
                    459:    {
                    460:    int t;
                    461:    double y;
                    462:    union numeric r;
                    463:    double sqrt();
                    464:    
                    465:    if ((t = cvreal(&arg1, &r)) == NULL) runerr(102, &arg1);
                    466:    y = sqrt(r.real);
                    467:    if (errno == EDOM) runerr(251, NULL);
                    468:    mkreal(y,\*b&arg0);
                    469:    Return;
                    470:    }
                    471: .De

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.