Annotation of researchv10dc/cmd/icon/docs/tr86-12.roff, revision 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.