Annotation of 43BSDReno/share/doc/ps2/07.fp/manCh6.rno, revision 1.1

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: .\"    @(#)manCh6.rno  6.1 (Berkeley) 4/29/86
        !             6: .\"
        !             7: .NS 1 "Implementation Notes"
        !             8: .pp
        !             9: FP was written in 3000 lines of \s-2FRANZ LISP\s+2 [Fod 80].
        !            10: Table 1 breaks down the distribution of the code by functionality.
        !            11: .(b
        !            12: .sp
        !            13: .TS
        !            14: center box;
        !            15: c|c
        !            16: l|n.
        !            17: Functionality  % (bytes)
        !            18: =
        !            19: compiler       34
        !            20: user interface 32
        !            21: dynamic stats  16
        !            22: primitives     14
        !            23: miscellaneous  3
        !            24: .TE
        !            25: .sp 4p
        !            26: .ce
        !            27: .b "Table 1"
        !            28: .sp 4p
        !            29: .)b
        !            30: .NS 2 "The Top Level"
        !            31: .pp
        !            32: The top-level function $runFp$ starts up the subsystem by calling
        !            33: the routine \fIfpMain\fP,
        !            34: that takes three arguments:
        !            35: .BB
        !            36: .np
        !            37: A boolean argument that says whether debugging output
        !            38: will be enabled.
        !            39: .np
        !            40: A Font identifier.  Currently the only one is supported \fB'asc\fP (ASCII).
        !            41: .np
        !            42: A boolean argument that identifies whether the interpreter
        !            43: was invoked from the shell.  If so then all exits from FP return the
        !            44: user back to the shell.
        !            45: .EB
        !            46: .pp
        !            47: The compiler converts the FP functions into LISP equivalents in two
        !            48: stages: first it forms the parse tree, and then it does the
        !            49: code generation.
        !            50: .sp
        !            51: .NS 2 "The Scanner"
        !            52: .sp
        !            53: .pp
        !            54: The scanner consists of a main routine, \fIget_tkn\fP, and a set of
        !            55: action functions.  There exists one set of action functions
        !            56: for each character font
        !            57: (currently only ASCII is supported).  All the action functions are named
        !            58: $scan dl "<font>"$, where $"<font>"$ is the specified font,
        !            59: and each is keyed
        !            60: on a particular character (or sometimes a particular character-type \-
        !            61: \*(EG a letter or a number).  \fIget_tkn\fP returns
        !            62: the token type, and any ancillary
        !            63: information, \*(EG for the token "name" the name itself will also be provided.
        !            64: (See Appendix C for the font-token name correspondences).
        !            65: When a character has been
        !            66: read the scanner finds the action function by doing a 
        !            67: .sp
        !            68: .ce 1
        !            69: $(get ~  'scan dl~ "<font> <char>")$
        !            70: .sp
        !            71: A syntax error message will be generated if
        !            72: no action exists for the particular character read.
        !            73: .sp
        !            74: .NS 2 "The Parser"
        !            75: .sp
        !            76: The main parsing function, \fIparse\fP, accepts a single argument, that
        !            77: identifies the parsing context, or
        !            78: type of construct being handled.
        !            79: Table 2
        !            80: shows
        !            81: the valid parsing contexts.
        !            82: .(b
        !            83: .sp 2
        !            84: .TS
        !            85: center box;
        !            86: c|c
        !            87: l|l.
        !            88: \fBid\fP       \fBconstruct\fP
        !            89: =
        !            90: top_lev        initial call
        !            91: constr$dd$     construction
        !            92: compos$dd$     composition
        !            93: alpha$dd$      apply-to-all
        !            94: insert$dd$     insert
        !            95: ti$dd$ tree insert
        !            96: arrow$dd$      T{
        !            97: .nf
        !            98: affirmative clause
        !            99: of conditional
        !           100: .fi
        !           101: T}
        !           102: semi$dd$       T{
        !           103: .nf
        !           104: negative clause
        !           105: of conditional
        !           106: .fi
        !           107: T}
        !           108: lparen$dd$     parenthetic expr.
        !           109: while$dd$      while
        !           110: .TE
        !           111: .sp
        !           112: .ce 1
        !           113: .b "Table 2, Valid Parsing Contexts"
        !           114: .)b
        !           115: .sp
        !           116: .EQ
        !           117: delim off
        !           118: .EN
        !           119: .pp
        !           120: For each type of token there exists a set of parse action functions,
        !           121: of the name \fIp$<tkn-name>\fP.  Each parse-action function is keyed
        !           122: on a valid context, and it is looked up in the same manner as
        !           123: scan action functions are looked up.  If an action function cannot
        !           124: be found, then there is a syntax error in the source code.
        !           125: .EQ
        !           126: delim $$
        !           127: .EN
        !           128: Parsing proceeds as follows: initially $parse$ is called from the top-level,
        !           129: with the context argument set to \fI\*(lqtop_lev\*(rq\fP.
        !           130: Certain tokens cause parse to
        !           131: be recursively invoked using that token as a context.  The result
        !           132: is the parse tree.
        !           133: .sp
        !           134: .NS 2 "The Code Generator"
        !           135: .pp
        !           136: The system
        !           137: compiles FP source into LISP source.  Normally, this code is interpreted by
        !           138: the \s-2FRANZ LISP\s+2 system.
        !           139: To speed up the implementation, there is an option to
        !           140: compile into machine code using the \fIliszt\fP  compiler [Joy 79].
        !           141: This feature
        !           142: improves performance tenfold,
        !           143: for some programs.
        !           144: .pp
        !           145: The compiler expands all functional forms into their LISP equivalents
        !           146: instead of
        !           147: inserting calls to functions that generate the code
        !           148: at run-time.  Otherwise, \fIliszt\fP
        !           149: would be ineffective in speeding up execution since
        !           150: all the functional forms would
        !           151: be executed interpretively.
        !           152: Although the amount of code
        !           153: generated by an expanding compiler
        !           154: is 3 or 4 times greater than
        !           155: would be generated by a non-expanding compiler, even in interpreted mode 
        !           156: the code runs twice as quickly as unexpanded code.
        !           157: With \fIliszt\fP compilation this performance advantage increases to more
        !           158: than tenfold.
        !           159: .pp
        !           160: A parse tree is either an atom or a hunk of parse trees.  An atomic parse-tree
        !           161: identifies either an fp built-in function or
        !           162: a user defined function.
        !           163: The hunk-type parse tree represents functional forms, \*(EG compose or
        !           164: construct. The first element identifies the functional form and the other
        !           165: elements are its functional parameters (they may in turn be
        !           166: functional forms).  Table 3 shows the parse-tree formats.
        !           167: .(b
        !           168: .sp 2
        !           169: .TS
        !           170: center box;
        !           171: c|c
        !           172: l|l.
        !           173: Form   Format
        !           174: =
        !           175: user-defined   <atom>
        !           176: fp builtin     <atom>
        !           177: apply-to-all   $"{" "alpha" dd~~PHI"}"$
        !           178: insert $"{"insert dd ~~PHI"}"$
        !           179: tree insert    $"{"ti dd ~~PHI"}"$
        !           180: select $"{"select dd ~mu"}"$
        !           181: constant       $"{"constant dd ~mu"}"$
        !           182: conditional    $"{"condit dd ~~PHI sub 1 ~~PHI sub 2 ~~PHI sub 3"}"$
        !           183: while  $"{"while dd ~~PHI sub 1 ~~PHI sub 2"}"$
        !           184: compose        $"{"compos dd ~~PHI sub 1 ~~PHI sub 2"}"$
        !           185: construct      $"{"constr dd ~~PHI sub 1~~PHI sub 2~~,...,~~PHI sub n ~nil"}"$
        !           186: .TE
        !           187: .sp
        !           188: Note: $PHI$ and the $PHI sub k$ are parse-trees and $mu$ is an optionally
        !           189: signed integer constant.
        !           190: .sp
        !           191: .ce 1
        !           192: .b "Table 3, Parse-Tree Formats"
        !           193: .sp
        !           194: .)b
        !           195: .NS 2 "Function Definition and Application"
        !           196: .sp
        !           197: .pp
        !           198: Once the code has been generated, then 
        !           199: the system defines the function via \fIputd\fP.
        !           200: The source code is placed onto
        !           201: a property list, $'sources$, to permit later access by the system
        !           202: commands.
        !           203: .pp
        !           204: For an application,
        !           205: the indicated function is compiled and then defined, only temporarily, as
        !           206: $tmp dd$. The single argument is read and
        !           207: $tmp dd$ is applied to it.
        !           208: .NS 2 "Function Naming Conventions"
        !           209: .pp
        !           210: When the parser detects a named primitive function, it returns the name
        !           211: $"<"name">" df$,
        !           212: where \fI<name>\fP is the name that was parsed (all primitive
        !           213: function-names
        !           214: end in $df$).  See Appendix D for the symbolic (\*(EG
        !           215: compose, $+$) function names.
        !           216: .pp
        !           217: Any name that isn't found  in the list of builtin functions
        !           218: is assumed to represent a user-defined function; hence,
        !           219: it isn't possible to redefine FP primitive functions.
        !           220: FP protects itself
        !           221: from accidental or malicious internal destruction
        !           222: by appending the suffix \*(lq$_fp$\*(rq
        !           223: to all user-defined function names, before
        !           224: they are defined.
        !           225: .NS 2 "Measurement Impelementation"
        !           226: .pp
        !           227: This work was done by Dorab Patel at UCLA.
        !           228: Most of the  measurement code is in the file 'fpMeasures.l'.
        !           229: Many of the remaining changes were effected in
        !           230: \&'primFp.l', to add calls on
        !           231: the measurement package at run-time; to  'codeGen.l', to add
        !           232: tracing of user defined functions; to  'utils.l', to add the new system
        !           233: commands; and to 'fpMain.l',
        !           234: to protect the user from forgetting to output statistics when he leaves
        !           235: FP.
        !           236: .NS 3 "Data Structures"
        !           237: .pp
        !           238: All the statistics are in the property list of the global symbol
        !           239: \fIMeasures\fP.
        !           240: Associated with each
        !           241: each function  (primitive or user-defined, or functional form)
        !           242: is an
        !           243: indicator;
        !           244: the statistics gathered for each function  are the corresponding values.
        !           245: The names corresponding to primitive functions and functional forms end
        !           246: in '$dl$fp' and the names corresponding to
        !           247: user-defined functions end in '_fp'.
        !           248: Each of the property values  is an
        !           249: association list:
        !           250: .sp
        !           251: .(l I
        !           252:     (get 'Measures 'rotl$dl$fp) ==> ((times . 0) (size . 0))
        !           253: .)l
        !           254: .sp
        !           255: .pp
        !           256: The car of the pair is the name of the statistic (\*(IE times, size)
        !           257: and the cdr is the value.
        !           258: There is one exception.
        !           259: Functional forms have a statistic called funargtyp.
        !           260: Instead of being a dotted pair, it is a list of two elements:
        !           261: .sp
        !           262: .(l I
        !           263: (get 'Measures 'compose$dl$fp) ==>
        !           264: ((times . 2) (size . 4) (funargtyp ((select$dl$fp . 2) (sub$dl$fp . 2))))
        !           265: .)l
        !           266: .sp
        !           267: .pp
        !           268: The car is the atom 'funargtyp' and the cdr is an alist.
        !           269: Each element of the alist consists of a functional
        !           270: argument-frequency dotted pair.
        !           271: .pp
        !           272: The statistic packages uses two other global symbols.
        !           273: The symbol DynTraceFlg is non-nil if dynamic statistics are being
        !           274: collected and is nil otherwise.
        !           275: The symbol TracedFns is a list (initially nil) of the names of the
        !           276: user functions being traced.
        !           277: .NS 3 "Interpretation of Data Structures"
        !           278: .NS 4 "Times"
        !           279: .pp
        !           280: The number of times this function has been called.
        !           281: All functions and functional forms have this statistic.
        !           282: .NS 4 "Size"
        !           283: .pp
        !           284: The sum of the sizes of the arguments passed to this
        !           285: function.
        !           286: This could be divided by the times statistic to give the average
        !           287: size of argument this function was passed.
        !           288: With few exceptions, the size of an object is its top-level length
        !           289: (note: version 4.0 defined the size as the total number of \fIatoms\fP
        !           290: in the object);
        !           291: the empty sequence, \*(lq<>\*(rq,
        !           292: has a size of 0 and all other atoms have size of one.
        !           293: The exceptions are: \fIapndl, distl\fP (top-level length
        !           294: of the second element), \fIapndr, distr\fP (top-level length of the first
        !           295: element), and \fItranspose\fP (top level length of each top level
        !           296: element).
        !           297: .pp
        !           298: This statistic is not collected for some primitive functions
        !           299: (mainly binary operators like +,-,\(**).
        !           300: .NS 4 "Funargno"
        !           301: .pp
        !           302: The number of functional arguments supplied to a functional
        !           303: form.
        !           304: .pp
        !           305: Currently this statistic is gatherered  only for the construction
        !           306: functional form.
        !           307: .NS 4 "Funargtyp"
        !           308: .pp
        !           309: How many times the named function was used as a
        !           310: functional parameter to the particular functional form.
        !           311: .NS 2 "Trace Information"
        !           312: .pp
        !           313: The level number of a call shows the number
        !           314: of steps required to execute the function on an ideal machine
        !           315: (\*(IE one with unbounded resources).
        !           316: The level number is calculated under an assumption of infinite
        !           317: resources, and
        !           318: the system evaluates the
        !           319: condition of a conditional before evaluating
        !           320: either of its clauses.
        !           321: The number of functions executed at each level can give an idea of the
        !           322: distribution of parallelism in the given FP program.

unix.superglobalmegacorp.com

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