Annotation of researchv10dc/vol2/cin/cin.m, revision 1.1

1.1     ! root        1: |make(rp)
        !             2: 
        !             3: |insert(../monk/monk.mac)
        !             4: 
        !             5: |comment(VOL2HEADER)|set_counter(page 325-1)|set_string(page_headers "'''")|set_string(even_headers "'The C Interpreter: A Tutorial for Cin Version 0.18''\f(NIcin\fP'")|set_string(odd_headers "'\f(NIcin\fP''The C Interpreter: A Tutorial for Cin Version 0.18'")|set_string(even_footers "_\\nP__UNIX Papers_")|set_string(odd_footers "'Research Tenth Edition''\\nP'")
        !             6: 
        !             7: |environment(computeroutput;
        !             8:        verbatim on, file.information, line.spacing 1,
        !             9:        fill off, size -1, space -1, font cw, blank.lines -1,
        !            10:        tab.stops "\w'        'u 2u*\w'        'u 3u*\w'        'u 4u*\w'        'u 5u*\w'        'u 6u*\w'        'u 7u*\w'        'u 8u*\w'        'u 9u*\w'        'u 10u*\w'        'u 11u*\w'        'u";
        !            11: 
        !            12:        tab.stops, blank.lines -1, SPACE)
        !            13: 
        !            14: |author(name "T. J. Kowalski", initials TJK, location MH, department 11229,
        !            15:        extension x2771, room 2C-568)
        !            16: |document(number 11229-880606-07TMS, file_case 25952,
        !            17:        work_program 311401-2199)
        !            18: 
        !            19: |author(name "H. H. Goguen", initials HHG, location MH, department 11229,
        !            20:        extension x2771, room 2C-568)
        !            21: |document(number 11229-880606-07TMS, file_case 25952,
        !            22:        work_program 311401-2199)
        !            23: 
        !            24: |author(name "J. J. Puttress", initials JJP, location MH, department 11229,
        !            25:        extension x7290, room 2C-577)
        !            26: |document(number 11229-880606-07TMS, file_case 25952,
        !            27:        work_program 311401-2199)
        !            28: 
        !            29: |date(June 6, 1988)
        !            30: 
        !            31: |title(The C Interpreter:
        !            32: A Tutorial for Cin Version 0.18)
        !            33: 
        !            34: |begin(abstract)
        !            35: The C interpreter, |i(cin), is the core of an interactive programming environment for
        !            36: the C programming language.
        !            37: We believe that by providing integrated facilities to create,
        !            38: edit,
        !            39: browse,
        !            40: execute,
        !            41: and debug programs,
        !            42: this environment should enhance the productivity
        !            43: of C programmers at |s(AT&T) and improve the quality of their code.
        !            44: Furthermore,
        !            45: we feel that |i(cin) provides an easy-to-use instructional environment.
        !            46: |p
        !            47: This memorandum is a tutorial guide to help users get started.
        !            48: Although it does not cover everything,
        !            49: it provides enough information for most users' daily needs.
        !            50: Topics discussed include
        !            51: creating simple programs,
        !            52: testing individual functions and expressions,
        !            53: inspecting and modifying variables,
        !            54: using program views, and setting breakpoints.
        !            55: |end(abstract)
        !            56: 
        !            57: |titlebox
        !            58: 
        !            59: |style(two_column)
        !            60: 
        !            61: |unnumbered_section(Introduction)
        !            62: 
        !            63: Interactive programming environments are common for |s(LISP),
        !            64: |reference(Teitelman Masinter Interlisp Programming Environment)
        !            65: |reference(Sandewall Programming in an Interactive Environment 1978)
        !            66: |s(PASCAL),
        !            67: |reference(Delisle Menicosy Schwartz Viewing a Programming Environment)
        !            68: |reference(Reiss Graphical Program Development with PECAN)
        !            69: |reference(Brown Sedgewick A System for Algorithm Animation)
        !            70: |s(PL/C),
        !            71: |reference(Archer Conway COPE: A Cooperative Programming Environment)
        !            72: |reference(Teitelbaum Reps The Cornell Program Synthesizer 1981)
        !            73: and Smalltalk.
        !            74: |reference(Goldberg Robson Smalltalk-80: The Language and Its Implementation)
        !            75: |reference(Tesler The Smalltalk Environment)
        !            76: Some work has been done on various pieces of a C program environment, including
        !            77: syntax directed editors,
        !            78: |reference(Horgan Moore Techniques for Improving Language-Based Editors)
        !            79: interpreters,
        !            80: |reference(Saber-C 1988)
        !            81: |reference(Feuer si - An Interpreter for the C Language)
        !            82: |reference(Ostby A C interpreter)
        !            83: debuggers,|reference(Adams Muchnick Dbxtool A Window-Based Symbolic Debugger)
        !            84: |reference(Cargill The Feel of Pi)
        !            85: and browsers.
        !            86: |reference(Steffen Interactive Examination of a C Program with Cscope)
        !            87: |p
        !            88: |i(Cin) is a C interpreter: an interactive program
        !            89: for creating, testing, modifying, and debugging a C program,
        !            90: using directions provided by a user at a terminal.
        !            91: The program can be a single function in a single file,
        !            92: or a large collection of files and functions as in System 75.
        !            93: |reference(System 75: Project Development Environment 1985)
        !            94: |i(Cin) is part of the Integrated C Programming Environment,
        !            95: |cw(cens),
        !            96: currently being developed by Department 11229.
        !            97: It implements correct full C,
        !            98: enables rapid prototyping,
        !            99: permits extensive error checking,
        !           100: facilitates incremental update,
        !           101: manages multiple software views,
        !           102: and
        !           103: provides a programmable command language.
        !           104: |p
        !           105: This tutorial is meant to simplify learning |i(cin).
        !           106: We suggest that you read this document,
        !           107: simultaneously using |i(cin) to follow the examples,
        !           108: then read the manual page in the appendix
        !           109: while continuing to experiment with |i(cin).
        !           110: Furthermore,
        !           111: we strongly recommend completing the exercises.
        !           112: They both reinforce material covered in the text
        !           113: and explore material not thoroughly discussed.
        !           114: |p
        !           115: This is an introduction and a tutorial.
        !           116: For that reason,
        !           117: no attempt is made to cover
        !           118: more than a part of the facilities that |i(cin) offers
        !           119: (although this fraction includes the most useful and frequently needed parts).
        !           120: Explanations of the C language and the |s(UNIX)|sp(registered) system
        !           121: are beyond the scope of this paper.
        !           122: We assume that you know how to log on to a |s(UNIX) system
        !           123: and how to express algorithms in C.
        !           124: Information on both the |s(UNIX) system
        !           125: and C is readily available from a variety of sources.
        !           126: |reference(Kernighan Pike Prentice-Hall)
        !           127: |reference(Kernighan Ritchie Prentice-Hall)
        !           128: 
        !           129: |section(Getting Started)
        !           130: 
        !           131: We'll assume you have logged in to a |s(UNIX) system
        !           132: and have just received the shell prompt, e.g. ``$''.
        !           133: The easiest way to start |i(cin) is to type
        !           134: 
        !           135: |begin(computeroutput)
        !           136: |i($ )cin -i
        !           137: |i(cin>)
        !           138: |end(computeroutput)
        !           139: 
        !           140: You are now ready to go
        !           141: |sp(Em dash) |i(cin) is waiting for your instructions.
        !           142: |i(Cin) shows this by echoing a
        !           143: 
        !           144: |begin(computeroutput)
        !           145: |i(cin>)
        !           146: |end(computeroutput)
        !           147: 
        !           148: to your terminal.
        !           149: Throughout this tutorial, responses from |i(cin) are in |i(italics).
        !           150: |p
        !           151: This section shows how to use the interactive mode of |i(cin),
        !           152: that is, a mode where we can enter and execute programs interactively.
        !           153: Later we'll talk about changing and debugging programs.
        !           154: As our first problem,
        !           155: let's leap the hurdle of creating, compiling, loading, and running
        !           156: a program that prints ``hello, world'' on our terminal.
        !           157: Though this is a painful task when we use the normal editor, compiler,
        !           158: loader, and shell to run the program,
        !           159: it's easy in |i(cin).
        !           160: |p
        !           161: When |i(cin) is started with the |cw(-i) option,
        !           162: it is like working with a blank piece
        !           163: of paper |sp(Em dash) there is no program or data present.
        !           164: They must be supplied by the person using |i(cin).
        !           165: The program,
        !           166: with its data,
        !           167: can be entered interactively
        !           168: or read into |i(cin) from a file.
        !           169: We will start by typing in a program
        !           170: and return shortly to the reading of files.
        !           171: |p
        !           172: First a bit of terminology.
        !           173: In |i(cin) jargon,
        !           174: the program currently worked on is said to be
        !           175: ``kept in the current |cw(view)''.
        !           176: Think of the |cw(view) as a work space,
        !           177: if you like,
        !           178: or simply as the information that you are going to be
        !           179: using.
        !           180: The |cw(view) is like a piece of paper,
        !           181: on which we will write things,
        !           182: then change some of them,
        !           183: and finally file the whole thing away for another day.
        !           184: |p
        !           185: The user tells |i(cin) what to do to the |cw(view)
        !           186: by typing C expressions and declarations.
        !           187: C expressions are executed immediately,
        !           188: while declarations are stored in the |cw(view).
        !           189: When an expression is executed,
        !           190: |i(cin) uses both local and global variables.
        !           191: |p
        !           192: Now we're ready to solve our problem.
        !           193: The easiest way is to write a C expression that calls the |cw(printf)
        !           194: library routine.
        !           195: 
        !           196: |begin(computeroutput)
        !           197: |i(cin>) printf("hello, world|sp(\)n");
        !           198: |i(hello, world
        !           199: cin>)
        !           200: |end(computeroutput)
        !           201: 
        !           202: |p
        !           203: Another way to solve our problem is to write a declaration for a |cw(main) function
        !           204: and call it using a C expression.
        !           205: 
        !           206: |begin(computeroutput)
        !           207: |i(cin>) void main()
        !           208: {
        !           209:   printf("hello, world|sp(\)n");
        !           210: }
        !           211: |i(cin>) main();
        !           212: |i(hello, world
        !           213: cin>)
        !           214: |end(computeroutput)
        !           215: 
        !           216: |p
        !           217: We draw your attention to the |cw(void main) declaration.
        !           218: When you're in |i(cin)'s interactive mode,
        !           219: you need to declare a return type for each function.
        !           220: This allows |i(cin)'s interactive mode
        !           221: to tell the difference between an expression calling |cw(main)
        !           222: and a declaration of |cw(main).
        !           223: Don't panic!
        !           224: You don't have to change all your C programs.
        !           225: This is only true when typing directly to interactive mode.
        !           226: The normal default declaration, |cw(int), still applies when files are read in.
        !           227: We could have designed |i(cin) to work like the
        !           228: C interpreters referenced in the introduction, which require you to
        !           229: type a special character to enter and leave a command mode,
        !           230: but we felt that declaring a return type was more consistent with C syntax.
        !           231: |p
        !           232: You also saw that |i(cin) prompts only for a C expression
        !           233: or a declaration.
        !           234: Thus, there are no prompts for the function body of |cw(main).
        !           235: This silence is preferred by experienced users,
        !           236: but sometimes disturbs beginners.
        !           237: |p
        !           238: Finally finished with our problem, we'd like to return to our shell.
        !           239: Exit |i(cin) by typing
        !           240: 
        !           241: |begin(computeroutput)
        !           242: |i(cin>) cin_quit();
        !           243: |i($)
        !           244: |end(computeroutput)
        !           245: 
        !           246: or by typing the end-of-file character (hold the |s(CTRL) key down
        !           247: and press |cw(d)).
        !           248: 
        !           249: |section(I Seemed To Have Confused It)
        !           250: 
        !           251: If you didn't get a ``hello, world'',
        !           252: then |i(cin) is confused by the directions it got.
        !           253: Let's look at some possible problems that may have occurred
        !           254: and how to correct them.
        !           255: |p
        !           256: One possibility is
        !           257: 
        !           258: |begin(computeroutput)
        !           259: |i($) cin -i
        !           260: |i(cin: not found)
        !           261: |i($)
        !           262: |end(computeroutput)
        !           263: 
        !           264: The C interpreter, |i(cin), is not available on your system in the
        !           265: directories specified by your |s(PATH) shell variable.
        !           266: Please contact your system administrator.
        !           267: If your system has |s(EXPTOOLS),
        !           268: the administrator can get |i(cin) from Alan Hastings.
        !           269: Otherwise,
        !           270: your administrator can ask for |i(cin) by sending mail to |cw(research!frodo),
        !           271: including his/her name,
        !           272: department number,
        !           273: telephone number,
        !           274: location,
        !           275: and room number.
        !           276: |p
        !           277: Another possibility is
        !           278: 
        !           279: |begin(computeroutput)
        !           280: |i($) cin -i
        !           281: |i(cin>) printff("hello, world|sp(\)n");
        !           282: |i(interactive mode: 1: warning: 'printff' undefined
        !           283: breakpoint in function 'cin_system'
        !           284:  at line 1 of file 'interactive mode'
        !           285: cin>)
        !           286: |end(computeroutput)
        !           287: 
        !           288: |cw(printf) was misspelled.
        !           289: Whenever |i(cin) encounters an undefined function or variable,
        !           290: it recursively calls a breakpoint function, |cw(cin_system),
        !           291: which places you in |i(cin)'s interactive mode waiting for input.
        !           292: The simplest corrective action is to return and ignore the problem.
        !           293: We can do this by typing
        !           294: 
        !           295: |begin(computeroutput)
        !           296: |i(cin>) cin_return();
        !           297: |i[interactive mode: 2: warning:
        !           298:  call of undefined function (returning 0L)
        !           299: cin>]
        !           300: |end(computeroutput)
        !           301: 
        !           302: or by typing the end-of-file character.
        !           303: This acts as if you decided to define a function, |cw(printff),
        !           304: that returns a |cw(long) zero.
        !           305: A future release of |i(cin) will allow you to modify the prompt to show
        !           306: the number of recursive calls to |cw(cin_system).
        !           307: Later we'll talk about additional corrective actions and
        !           308: other predefined |cw(cin_) functions and variables.
        !           309: |p
        !           310: Yet another possibility is
        !           311: 
        !           312: |begin(computeroutput)
        !           313: |i($) cin -i
        !           314: |i(cin>) printf("hello, world|sp(\)n")
        !           315: |end(computeroutput)
        !           316: 
        !           317: Neither ``hello, world'', nor the |cw(|i(cin>)) prompt appears.
        !           318: You probably forgot to type the last semicolon (|cw(;)).
        !           319: Even experienced users forget the terminating semicolon (|cw(;))
        !           320: sometimes.
        !           321: If |i(cin) seems to be ignoring you,
        !           322: 
        !           323: |begin(computeroutput)
        !           324: |i($) cin -i
        !           325: |i(cin>) printf("hello, world|sp(\)n);
        !           326: |i(interactive mode: 1: newline in string)
        !           327: |end(computeroutput)
        !           328: 
        !           329: type an extra line with just a semicolon (|cw(;)) on it,
        !           330: or in some rare cases
        !           331: 
        !           332: |begin(computeroutput)
        !           333: |i($) cin -i
        !           334: |i(cin>) void main()
        !           335: {
        !           336:        printf("hello, world|sp(\)n);
        !           337: }
        !           338: |i(interactive mode: 3: newline in string
        !           339: interactive mode: 4: syntax error
        !           340:  in parameter list of function call)
        !           341: |end(computeroutput)
        !           342: 
        !           343: an extra line with just a semicolon (|cw(;))
        !           344: followed by an extra line with just a closing curly brace (|cw(})) on it.
        !           345: Isn't error recovery wonderful!
        !           346: The next release of |i(cin) will be more friendlier.
        !           347: |p
        !           348: Throughout the rest of the tutorial,
        !           349: we will assume that our typing is perfect.
        !           350: We use the |cw(samuel)|reference(Puttress 1986 browser)
        !           351: editor to remember C statements and declarations in a scratch pad,
        !           352: sending them to |i(cin) whenever we are happy with the syntax.
        !           353: However, you can also remember and send
        !           354: C statements and declarations with |cw(sam), |cw(jim), |cw(emacs), or |cw(inedit).
        !           355: 
        !           356: |subsection(Exercise 1)
        !           357: 
        !           358: Enter |i(cin) and use the formula |e<degree~ F ~=~ ( 9 / 5 ) ~*~ degree~ C ~+~ 32>
        !           359: to create a conversion table from centigrade or Celsius temperatures to Fahrenheit
        !           360: for 20|sp(degree) C to 30|sp(degree) C.
        !           361: Do this exercise in two different ways:
        !           362: |begin(number_list)
        !           363: |item Write a C expression that calls the |cw(printf) library routine.
        !           364: |item Declare a |cw(main) function and run it in |i(cin).
        !           365: |end(number_list)
        !           366: 
        !           367: |section(Writing A Small Program)
        !           368: 
        !           369: Our next problem is to write a few routines to
        !           370: print algebraic expression trees.
        !           371: Let's start by declaring the template |cw(node) for our tree.
        !           372: 
        !           373: |begin(computeroutput)
        !           374: |i(cin>) struct node {
        !           375:   struct node *left;
        !           376:   struct node *right;
        !           377:   char *value;
        !           378:   int type;
        !           379: };
        !           380: |i(cin>)
        !           381: |end(computeroutput)
        !           382: 
        !           383: |p
        !           384: The |cw(left) and |cw(right) fields are pointers to other |cw(node)s.
        !           385: The |cw(value) field holds a character string representing
        !           386: the operator, variable, or constant associated with the node.
        !           387: The |cw(type) field shows the kind of operator,
        !           388: variable, or constant held in |cw(value) field.
        !           389: The allowable types are:
        !           390: 
        !           391: |begin(computeroutput)
        !           392: |i(cin>) #define       ADD     1
        !           393: #define        SUB     2
        !           394: #define        MUL     3
        !           395: #define        DIV     4
        !           396: #define        EXPT    5
        !           397: #define        UMINUS  6
        !           398: #define        CONST   7
        !           399: #define        VAR     8
        !           400: |end(computeroutput)
        !           401: 
        !           402: |p
        !           403: We'd like to pause and talk about prompts once again.
        !           404: You're probably puzzled why there was only one |i(cin>) for the above set
        !           405: of pre-processor statements.
        !           406: Well,
        !           407: in the 0.18 release |i(cin) prompts only for a C expression
        !           408: or a declaration, and C pre-processor statements are a little different.
        !           409: We think this is a botch and will change it in the next release,
        !           410: but until then it's a feature.|dagnote(Features are
        !           411: bugs that are not yet fixed.)
        !           412: |p
        !           413: Now that we have a data structure,
        !           414: let's write a |cw(prt) routine to display the tree
        !           415: in the format normally used for an equation.
        !           416: This requires an in-order walk; in other words |sp(Em dash)
        !           417: go left as far as you can,
        !           418: print the node,
        !           419: then go right as far as you can.
        !           420: 
        !           421: |begin(computeroutput)
        !           422: |i(cin>) void
        !           423: prt(n)
        !           424: struct node *n;
        !           425: {
        !           426:   switch(n->type) {
        !           427: 
        !           428:   default:
        !           429:     prt(n->left);
        !           430:     printf("%s ", n->value);
        !           431:     prt(n->right);
        !           432:     break;
        !           433: 
        !           434:   case UMINUS:
        !           435:     printf("%s ", n->value);
        !           436:     prt(n->right);
        !           437:     break;
        !           438: 
        !           439:   case CONST:
        !           440:   case VAR:
        !           441:     printf("%s ", n->value);
        !           442:     break;
        !           443: 
        !           444:   }
        !           445: }
        !           446: |i(cin>)
        !           447: |end(computeroutput)
        !           448: 
        !           449: |p
        !           450: A powerful feature of |i(cin) enables a routine
        !           451: to be tested as soon it is written.
        !           452: This way you can make sure it does what you want
        !           453: before incorporating it into a large program.
        !           454: |i(Cin) also takes care of allocating and deallocating
        !           455: data structures for testing.
        !           456: |p
        !           457: Let's test the |cw(prt) function.
        !           458: First we'll include the standard I/O header file
        !           459: so we can turn off output buffering.
        !           460: 
        !           461: |begin(computeroutput)
        !           462: |i(cin>) #include <stdio.h>
        !           463: |i(cin>) setbuf(stdout, NULL);
        !           464: |i(cin>) setbuf(stderr, NULL);
        !           465: |i(cin>)
        !           466: |end(computeroutput)
        !           467: 
        !           468: Next we let |i(cin) allocate storage space for a sample node,
        !           469: |cw(a1),
        !           470: and set it to hold a constant, |cw(CONST), with a value of |cw(17).
        !           471: Finally,
        !           472: we call |cw(prt) and see it print |cw(17).
        !           473: 
        !           474: |begin(computeroutput)
        !           475: |i(cin>) struct node a1;
        !           476: |i(cin>) a1.type = CONST;
        !           477: |i(cin>) a1.value = "17";
        !           478: |i(cin>) prt(&a1);
        !           479: |i(17 cin>)
        !           480: |end(computeroutput)
        !           481: 
        !           482: For constants,
        !           483: |cw(left) and |cw(right) are unused.
        !           484: |p
        !           485: It's likely that we'll want to save our work for later use.
        !           486: A simple and easy way to do this
        !           487: is to save an image of our program and data definitions as an executable file.
        !           488: Let's do this by calling the predefined function |cw(cin_dump)
        !           489: with the name of a file, |cw(./saved).
        !           490: 
        !           491: |begin(computeroutput)
        !           492: |i(cin>) cin_dump("./saved");
        !           493: |i(cin>) cin_quit();
        !           494: |i($)
        !           495: |end(computeroutput)
        !           496: 
        !           497: Any time afterwards we can invoke our saved executable and use the program
        !           498: and data definitions we have just entered.
        !           499: 
        !           500: |begin(computeroutput)
        !           501: |i($) ./saved
        !           502: |i(cin>) prt(&a1);
        !           503: |i(17 cin>)
        !           504: |end(computeroutput)
        !           505: 
        !           506: This feature is useful for customizing our |i(cin) environment,
        !           507: but in the 0.18 release of |i(cin) there is no way to print out
        !           508: the definition of a given function.
        !           509: We plan to enhance |i(cin) to do this in the future,
        !           510: but for now we recommend using an editor to keep your functions
        !           511: in files.
        !           512: |p
        !           513: Thus, we need to learn how to
        !           514: load source or object files into |i(cin).
        !           515: We'll assume you've returned to your shell,
        !           516: placed the definition for |cw(node)
        !           517: and its |cw(#define)s in |cw(node.h),
        !           518: and placed |cw(#include "node.h")
        !           519: along with the definition for |cw(prt) in |cw(prt.c).
        !           520: |p
        !           521: Now let's go back to |i(cin) and load in the |cw(prt) function.
        !           522: 
        !           523: |begin(computeroutput)
        !           524: |i($) cin -i
        !           525: |i(cin>) cin_load("prt.c");
        !           526: |i(cin>)
        !           527: |end(computeroutput)
        !           528: 
        !           529: |p
        !           530: When |i(cin) loaded |cw(prt.c), it placed
        !           531: the structure definition for |cw(node),
        !           532: the |cw(#define)s,
        !           533: and the definition for |cw(prt)
        !           534: in a |cw(view) called |cw(prt.c).
        !           535: A |cw(view) is the internal representation of a C source file |sp(Em dash)
        !           536: |cw(#define)s, static variables and functions, and global declarations.
        !           537: Outside |i(cin), the functions and data of a C program are packaged in a file;
        !           538: inside |i(cin) they are contained in a |cw(view).
        !           539: Earlier, when we typed declarations directly into the interpreter,
        !           540: they were placed into a default |cw(view) called ``interactive mode''.
        !           541: To use the declarations,
        !           542: we need to be in the |cw(view) where they are stored.
        !           543: So if we are sure we defined something, but |i(cin) can't find it,
        !           544: we have probably gotten into the wrong |cw(view).
        !           545: We can see what |cw(view)s are available by using the predefined function
        !           546: |cw(cin_views), and we can change our |cw(view) by using |cw(cin_view).
        !           547: 
        !           548: |begin(computeroutput)
        !           549: |i(cin>) cin_views();
        !           550: |i(   prt.c
        !           551:  |sp(*) interactive mode
        !           552: cin>) cin_view("prt.c");
        !           553: |i(cin>) cin_views();
        !           554: |i( |sp(*) prt.c
        !           555:    interactive mode
        !           556: cin>)
        !           557: |end(computeroutput)
        !           558: 
        !           559: |p
        !           560: We have just seen that |cw(cin_views) marks our current |cw(view)
        !           561: with an asterisk (|cw(*)).
        !           562: Do not confuse the ``interactive mode'' session,
        !           563: which is entered by typing |cw(cin -i),
        !           564: with the default interactive mode |cw(view).
        !           565: In interactive mode,
        !           566: you may access any |cw(view)
        !           567: and enter C expressions or declarations in the context of that |cw(view).
        !           568: The interactive mode |cw(view) is simply the default |cw(view),
        !           569: used for storing C declarations not associated with an external file.
        !           570: |p
        !           571: Let's use the declaration of |cw(struct node)
        !           572: and the |cw(#define) for |cw(CONST) in the current or |cw(prt.c) |cw(view)
        !           573: to initialize a |cw(struct node a1).
        !           574: 
        !           575: |begin(computeroutput)
        !           576: |i(cin>) struct node a1;
        !           577: |i(cin>) a1.type = CONST;
        !           578: |i(cin>) a1.value = "17";
        !           579: |i(cin>)
        !           580: |end(computeroutput)
        !           581: 
        !           582: |p
        !           583: Although we said our typing would be prefect,|dagnote(as you can see it's not)
        !           584: let's see what happens if we make the common mistake of passing
        !           585: a structure instead of a pointer to the structure.
        !           586: 
        !           587: |begin(computeroutput)
        !           588: |i(cin>) prt(a1);
        !           589: |i(prt.c: 7: null pointer access
        !           590: breakpoint in function 'prt' at line 7 of file 'prt.c'
        !           591: cin>)
        !           592: |end(computeroutput)
        !           593: 
        !           594: |p
        !           595: At this point we can escape to our shell and print a numbered listing
        !           596: of |cw(prt.c).
        !           597: 
        !           598: |begin(computeroutput)
        !           599: |i(cin>) system("pr -n -t prt.c");
        !           600: |i[ 1  #include "node.h"
        !           601:  2
        !           602:  3     void
        !           603:  4     prt(n)
        !           604:  5     struct node |sp(*)n;
        !           605:  6     {
        !           606:  7       switch(n|cw(->)type) {
        !           607:  8
        !           608:  9       default:
        !           609: 10         prt(n|cw(->)left);
        !           610: 11         printf("%s ", n|cw(->)value);
        !           611: 12         prt(n|cw(->)right);
        !           612: 13         break;
        !           613: 14
        !           614: 15       case UMINUS:
        !           615: 16         printf("%s ", n|cw(->)value);
        !           616: 17         prt(n|cw(->)right);
        !           617: 18         break;
        !           618: 19
        !           619: 20       case CONST:
        !           620: 21       case VAR:
        !           621: 22         printf("%s ", n|cw(->)value);
        !           622: 23         break;
        !           623: 24
        !           624: 25       }
        !           625: 26     }
        !           626: cin>]
        !           627: |end(computeroutput)
        !           628: 
        !           629: |p
        !           630: By a quick process of elimination,
        !           631: we realize that
        !           632: |cw(n) must be our problem,
        !           633: because line 7 only has one pointer variable.
        !           634: When you are in a |i(cin) breakpoint function,
        !           635: |i(cin) computes the value of expressions in the current execution context
        !           636: |sp(Em dash) an expression is evaluated just as though
        !           637: it were placed in the program source at the current point of execution.
        !           638: Thus, we can check to see if |cw(n) is zero by printing its value.
        !           639: 
        !           640: |begin(computeroutput)
        !           641: |i(cin>) printf("%d|sp(\)n", n);
        !           642: |i(0)
        !           643: |i(cin>)
        !           644: |end(computeroutput)
        !           645: 
        !           646: |p
        !           647: If we failed to notice our ``passing
        !           648: a structure instead of a pointer to the structure'' typo,
        !           649: we might think that |cw(prt) got into trouble because it called itself.
        !           650: We can check this by using the predefined function |cw(cin_where).
        !           651: 
        !           652: |begin(computeroutput)
        !           653: |i(cin>) cin_where();
        !           654: |i{cin_system()   [prt.c:1]
        !           655: prt(n = 0x0)   [prt.c:7]
        !           656: cin_system()   [interactive mode:32]
        !           657: cin>}
        !           658: |end(computeroutput)
        !           659: 
        !           660: This tells us that we are currently in |i(cin)'s breakpoint function,
        !           661: |cw(cin_system),
        !           662: looking at a call of |cw(prt) that was made from
        !           663: interactive mode.
        !           664: Because there are not two calls to |cw(prt),
        !           665: we are assured it didn't recursively call itself.
        !           666: |p
        !           667: As you can see from the reference to line number 32,
        !           668: the authors need to struggle further with what line numbers should mean in
        !           669: interactive mode.
        !           670: In particular, |cw(cin_where) and |cw(cin_break),
        !           671: discussed later,
        !           672: don't seem to use sensible line numbers for functions defined in interactive mode.
        !           673: |p
        !           674: Let's fix the problem with |cw(n) by modifying its value to be
        !           675: |cw(&a1) and allowing the program to continue.
        !           676: 
        !           677: |begin(computeroutput)
        !           678: |i(cin>) n = &a1;
        !           679: |i(cin>) cin_return();
        !           680: |i(17 cin>)
        !           681: |end(computeroutput)
        !           682: 
        !           683: Most debuggers don't permit you to continue after a serious error.
        !           684: Whenever possible,
        !           685: |i(cin) allows you to recover from an error
        !           686: once you've taken corrective action.
        !           687: If we don't want to take corrective action,
        !           688: we can remove all calls of |i(cin)'s breakpoint function by calling |cw(exit).
        !           689: 
        !           690: |begin(computeroutput)
        !           691: |i(cin>) exit(0);
        !           692: |i(cin>)
        !           693: |end(computeroutput)
        !           694: 
        !           695: Sometimes there is no way to fix the problem
        !           696: and all we can do is |cw(cin_quit).
        !           697: |p
        !           698: Now let's define a function that creates a node,
        !           699: placing the function in |cw(create.c).
        !           700: We can enter our favorite editor by
        !           701: 
        !           702: |begin(computeroutput)
        !           703: |i(cin>) system("${EDITOR-/bin/ed} foo.c");
        !           704: |i(?foo.c)
        !           705: |end(computeroutput)
        !           706: 
        !           707: and printing out our file
        !           708: 
        !           709: |begin(computeroutput)
        !           710: |i(cin>) system("pr -n -t create.c");
        !           711: |i[ 1  #include <stdio.h>
        !           712:  2     #include "node.h"
        !           713:  3
        !           714:  4     struct node |sp(*)
        !           715:  5     create(left, right, type, value)
        !           716:  6     struct node |sp(*)left, |sp(*)right;
        !           717:  7     char |sp(*)value;
        !           718:  8     {
        !           719:  9       struct node |sp(*)n;
        !           720: 10       struct node |sp(*)memory();
        !           721: 11
        !           722: 12       if (n = memory(
        !           723: 13        sizeof(struct node))) {
        !           724: 14         n|cw(->)left = left;
        !           725: 15         n|cw(->)right = right;
        !           726: 16         n|cw(->)type = type;
        !           727: 17         n|cw(->)value = value;
        !           728: 18         return(n);
        !           729: 19       }
        !           730: 20
        !           731: 21       fprintf(stderr,
        !           732: 22        "No memory to create a node|sp(\)n");
        !           733: 23       exit(1);
        !           734: 24     }
        !           735: cin>] cin_load("create.c");
        !           736: |i[create.c: 8: warning: function 'create'
        !           737: has implicit return and 'return e;' (line 18)
        !           738: cin>]
        !           739: |end(computeroutput)
        !           740: 
        !           741: |p
        !           742: The error message warns us that the function |cw(create),
        !           743: which is declared starting on line 8,
        !           744: ends without returning a value.
        !           745: This is fine, because the function |cw(exit)
        !           746: would never let us get to the end of the routine.
        !           747: |p
        !           748: Now let's change our |cw(view) to the |cw(create.c) declarations,
        !           749: make a few nodes, and print the expression tree
        !           750: for |cw[2 * (17 - x)].
        !           751: We can represent the expression tree graphically as
        !           752: 
        !           753: |begin(here)
        !           754: |begin(picture)
        !           755: scale=100
        !           756: box invis ht 96 wid 144 with .sw at 0,0
        !           757: "\fR\s10\&|sp(-) (t1)\f1\s0" at 122,42
        !           758: "\fR\s10\&x (t3)\f1\s0" at 160,-10
        !           759: "\fR\s10\&17 (t2)\f1\s0" at 80,-10
        !           760: line from 104,40 to 144,0
        !           761: line from 104,40 to 64,0
        !           762: "\fR\s10\&2 (t5)\f1\s0" at 24,26
        !           763: "\fR\s10\&|sp(*) (t4)\f1\s0" at 80,86
        !           764: line from 64,80 to 104,40
        !           765: line from 64,80 to 24,40
        !           766: |end(picture)
        !           767: |end(here)
        !           768: 
        !           769: where the labels in parentheses are the variable names for the |cw(struct node)
        !           770: pointers
        !           771: and the other symbols are the |cw(value)s for the |cw(node)s.
        !           772: 
        !           773: |begin(computeroutput)
        !           774: |i(cin>) cin_view("create.c");
        !           775: |i(cin>) struct node *t1, *t2, *t3;
        !           776: |i(cin>) t3 = create((struct node *)0,
        !           777: (struct node *)0, VAR, "x");
        !           778: |i(create.c: 12: warning: 'memory' undefined
        !           779: breakpoint in function 'create'
        !           780: at line 12 of file 'create.c'
        !           781: cin>)
        !           782: |end(computeroutput)
        !           783: 
        !           784: |p
        !           785: A common programming practice is to leave ``stubs'',
        !           786: or functions to be defined at a later date.
        !           787: |i(Cin) will stop when it encounters functions or variables that are not defined,
        !           788: permitting you to define them.
        !           789: Here |i(cin) has stopped because it can't find a definition for |cw(memory).
        !           790: 
        !           791: |begin(computeroutput)
        !           792: |i(cin>) struct node *
        !           793: memory(n)
        !           794: unsigned n;
        !           795: {
        !           796:   struct node *malloc();
        !           797:   return malloc(n);
        !           798: }
        !           799: |i(cin>) cin_return();
        !           800: |i(cin>) t2 = create((struct node *)0,
        !           801: (struct node *)0, CONST, "17");
        !           802: |i(cin>) t1 = create(t2, t3, ADD, "+");
        !           803: |i(cin>) struct node *t4, *t5;
        !           804: |i(cin>) t5 = create((struct node *)0,
        !           805: (struct node *)0, CONST, "2");
        !           806: |i(cin>) t4 = create(t5, t1, MUL, "*");
        !           807: |i(cin>) prt(t4);
        !           808: |i(2 |sp(*) 17 + x cin>)
        !           809: |end(computeroutput)
        !           810: 
        !           811: We'd like to emphasize that declarations can be mixed
        !           812: with C expressions in interactive mode.
        !           813: 
        !           814: |subsection(Exercise 2)
        !           815: 
        !           816: Use |i(cin) and your favorite editor to enhance the |cw(prt) function
        !           817: by adding parentheses to the output that show the nesting levels;
        !           818: e.g., |cw<prt(t4)> should output |cw<( 2 * ( 17 + x ) )>.
        !           819: 
        !           820: |section(Debugging With Breakpoints)
        !           821: 
        !           822: We've already seen that any legal C expression can be used
        !           823: when |i(cin) enters the breakpoint function,
        !           824: but we haven't seen how to force |i(cin)
        !           825: to enter a breakpoint function.
        !           826: The easiest way is to use your editor and insert calls to the
        !           827: predefined function |cw(cin_system) into your program.
        !           828: 
        !           829: |begin(computeroutput)
        !           830: 1      hello()
        !           831: 2      {
        !           832: 3        int i;
        !           833: 4        i = 17;
        !           834: 5        printf("hello, %d", i);
        !           835: 6        cin_system();
        !           836: 7        printf("world %d times|sp(\)n", i);
        !           837: 8      }
        !           838: |end(computeroutput)
        !           839: 
        !           840: |p
        !           841: So if we were to load in |cw(hello.c) and run it:
        !           842: 
        !           843: |begin(computeroutput)
        !           844: cin> |i($) cin -i
        !           845: |i(cin>) cin_load("hello.c");
        !           846: |i(cin>) hello();
        !           847: |i(breakpoint in function 'hello' at line 6 of file 'hello.c'
        !           848: hello, 17cin>) i = 3;
        !           849: |i(cin>) cin_return();
        !           850: |i(world 3 times
        !           851: cin>)
        !           852: |end(computeroutput)
        !           853: 
        !           854: We'd be able to change the value of |cw(i),
        !           855: or anything else, for that matter,
        !           856: to whatever we want.
        !           857: This is like placing |cw(printf)'s in our code that allow us
        !           858: to print or modify anything.
        !           859: |p
        !           860: We can obtain a less permanent breakpoint using the predefined function
        !           861: |cw(cin_break), and remove it using |cw(cin_unbreak).
        !           862: Let's return to the original |cw(prt) routine contained in |cw(prt.c),
        !           863: assert a breakpoint on line 7,
        !           864: and run it with |cw(t4).
        !           865: Because we've already debugged |cw(create) and |cw(memory),
        !           866: we can use the C compiler to create object files for them,
        !           867: continuing to debug |cw(prt) in source form.
        !           868: By mixing object files with source files, we get the speed of compiled code
        !           869: for functions that are debugged,
        !           870: combined with the error checking of interpreted code
        !           871: for functions we are testing.
        !           872: 
        !           873: |begin(computeroutput)
        !           874: |i($) cc -O -c create.c memory.c
        !           875: |i(create.c:
        !           876: memory.c:
        !           877: $) cin -i prt.c create.o memory.o
        !           878: |i(cin>) cin_view("prt.c");
        !           879: |i(cin>) struct node *t1, *t2, *t3;
        !           880: |i(cin>) struct node *create();
        !           881: |i(cin>) #include <stdio.h>
        !           882: |i(cin>) t3 = create((struct node *)0,
        !           883: (struct node *)0, VAR, "x");
        !           884: |i(cin>) t2 = create((struct node *)0,
        !           885: (struct node *)0, CONST, "17");
        !           886: |i(cin>) t1 = create(t2, t3, ADD, "+");
        !           887: |i(cin>) struct node *t4, *t5;
        !           888: |i(cin>) t5 = create((struct node *)0,
        !           889: (struct node *)0, CONST, "2");
        !           890: |i(cin>) t4 = create(t5, t1, MUL, "*");
        !           891: |i(cin>)
        !           892: |end(computeroutput)
        !           893: 
        !           894: |p
        !           895: |cw(Cin_break) and |cw(cin_unbreak) both require us to be in the
        !           896: |cw(view) where the function is defined and restrict us to functions
        !           897: that are being interpreted.
        !           898: We plan to enhance |i(cin) to remove these restrictions in the future.
        !           899: 
        !           900: |begin(computeroutput)
        !           901: |i(cin>) cin_break("prt", 7);
        !           902: |i(breakpoint in function prt at line 7
        !           903: cin>) prt(t4);
        !           904: |i(breakpoint in function 'prt' at line 7 of file 'prt.c'
        !           905: cin>) cin_return();
        !           906: |i(breakpoint in function 'prt' at line 7 of file 'prt.c'
        !           907: cin>) cin_return();
        !           908: |i(breakpoint in function 'prt' at line 7 of file 'prt.c'
        !           909: 2 |sp(*) cin>) cin_where();
        !           910: |i{cin_system()   [prt.c:1]
        !           911: prt(n = 0x9382C)   [prt.c:7]
        !           912: prt(n = 0x93854)   [prt.c:12]
        !           913: cin_system()   [stdio.h:50]
        !           914: cin>} cin_unbreak("prt", 7);
        !           915: |i(breakpoint removed from line 7 in prt
        !           916: cin>) cin_return();
        !           917: |i(17 + x cin>) cin_quit();
        !           918: |i($)
        !           919: |end(computeroutput)
        !           920: 
        !           921: We plan to enhance |i(cin) by adding another argument to |cw(cin_break).
        !           922: This argument will be a string that is executed when the breakpoint function
        !           923: is entered.
        !           924: This will let us set breakpoints that remove themselves,
        !           925: print interesting things,
        !           926: or even set other breakpoints.
        !           927: 
        !           928: |section(Program Equals Data)
        !           929: 
        !           930: A common trick of interpreters,
        !           931: especially in the |s(LISP) world,
        !           932: is to use the same representation for data handled by a program
        !           933: and the program text itself.
        !           934: |p
        !           935: As our last programming task in this tutorial,
        !           936: let's write a simple desk calculator.
        !           937: To accomplish this,
        !           938: we need to read a string from the user,
        !           939: wrap it in a |cw(printf) C expression,
        !           940: and pass it to the predefined function |cw(cin_eval).
        !           941: 
        !           942: |begin(computeroutput)
        !           943: |i($) cin -i -lm
        !           944: |i(cin>) #include <stdio.h>
        !           945: |i(cin>) #include <math.h>
        !           946: |i(cin>) char buf[1024], buf2[1024];
        !           947: |i(cin>) while(gets(buf) != NULL) {
        !           948:   sprintf(buf2,
        !           949:    "printf(|sp(\)"%%g|sp(\)|sp(\)n|sp(\)",(double)(%s));",
        !           950:    buf);
        !           951:   cin_eval(buf2);
        !           952: }
        !           953: sqrt(2.0) * sqrt(2.0)
        !           954: |i(2)
        !           955: |end(computeroutput)
        !           956: 
        !           957: In writing the |cw(printf) expression shown above,
        !           958: the trickiest part was ensuring that the argument would be appropriate
        !           959: to the |cw(g) format.
        !           960: That's what the |cw<(double)> accomplished.
        !           961: This example is also plagued with getting the right number of
        !           962: |sp(\)s and |cw(%)s.
        !           963: 
        !           964: |subsection(Exercise 3)
        !           965: 
        !           966: Enhance the desk calculator C expression to remember the
        !           967: last value as |cw(t)
        !           968: and make it into a shell file that can be easily executed.
        !           969: 
        !           970: |section(Bugs)
        !           971: 
        !           972: |center(You find 'em.
        !           973: We squash 'em!)
        !           974: |p
        !           975: The interactive mode is new with the 0.18 release of |i(cin).
        !           976: It's hard to anticipate all the errors you may encounter,
        !           977: and because of this we need your help to improve our tool.
        !           978: Thus, we welcome bug reports sent to research!frodo.
        !           979: Please include a short program along with the terminal input and
        !           980: output that creates the |i(cin) problem.
        !           981: 
        !           982: |section(Summary Of Predefined Functions)
        !           983: 
        !           984: Several pre-defined functions are provided for the user,
        !           985: where |i(name), |i(string), |i(file), |i(line), |i(func), |i(func_mod),
        !           986: and |i(func_ref) are declared as:
        !           987: 
        !           988: |begin(computeroutput)
        !           989: char *|i(name), *|i(string), *|i(file);
        !           990: int |i(line);
        !           991: long (*|i(func))(), (*|i(func_mod))(), (*|i(func_ref))();
        !           992: |end(computeroutput)
        !           993: 
        !           994: |blank_space(-1)
        !           995: |begin(computeroutput)
        !           996: void cin_bind(|i(name), |i(func))
        !           997: |end(computeroutput)
        !           998: |blank_space(-1)
        !           999: Set an alias of |i(name) for the function |i(func).
        !          1000: 
        !          1001: |begin(computeroutput)
        !          1002: int cin_break(|i(name), |i(line))
        !          1003: |end(computeroutput)
        !          1004: |blank_space(-1)
        !          1005: Set a breakpoint in function |i(name) at line number |i(line) in the current
        !          1006: |cw(view).
        !          1007: Returns 0 if breakpoint cannot be set.
        !          1008: 
        !          1009: |begin(computeroutput)
        !          1010: int cin_dump(|i(name))
        !          1011: |end(computeroutput)
        !          1012: |blank_space(-1)
        !          1013: Create an |cw(a.out) and place it in the file |i(name).
        !          1014: Returns 0 if |i(name) cannot be created.
        !          1015: 
        !          1016: |begin(computeroutput)
        !          1017: int cin_eval(|i(string))
        !          1018: |end(computeroutput)
        !          1019: |blank_space(-1)
        !          1020: Execute the C statement |i(string)
        !          1021: as if it were present in the program where the |cw(cin_eval) is located.
        !          1022: Returns 0 if |i(string) could not be parsed.
        !          1023: 
        !          1024: |begin(computeroutput)
        !          1025: int cin_load(|i(file))
        !          1026: |end(computeroutput)
        !          1027: |blank_space(-1)
        !          1028: Load |i(file) into a new |cw(view),
        !          1029: using the standard file-naming conventions for |i(cc)(1).
        !          1030: Returns 0 if |i(file) can not be loaded.
        !          1031: 
        !          1032: |begin(computeroutput)
        !          1033: void cin_return()
        !          1034: |end(computeroutput)
        !          1035: |blank_space(-1)
        !          1036: Return from a breakpoint.
        !          1037: 
        !          1038: |begin(computeroutput)
        !          1039: int cin_spy(|i(name), |i(func_mod), |i(func_ref))
        !          1040: |end(computeroutput)
        !          1041: |blank_space(-1)
        !          1042: Call the function |i(func_mod) whenever the variable |i(name) is modified.
        !          1043: Call the function |i(func_ref) whenever the variable |i(name) is referenced.
        !          1044: Either |i(func_mod) or |i(func_ref) can be |cw<(long (*)())0>.
        !          1045: Returns 0 if there are no spies active.
        !          1046: 
        !          1047: |begin(computeroutput)
        !          1048: void cin_system()
        !          1049: |end(computeroutput)
        !          1050: |blank_space(-1)
        !          1051: Enter ``interactive mode''.
        !          1052: 
        !          1053: |begin(computeroutput)
        !          1054: int cin_unbreak(|i(name), |i(line))
        !          1055: |end(computeroutput)
        !          1056: |blank_space(-1)
        !          1057: Remove a breakpoint in function |i(name) at line number |i(line) in the current
        !          1058: |cw(view).
        !          1059: Returns 0 if the breakpoint was not set.
        !          1060: 
        !          1061: |begin(computeroutput)
        !          1062: int cin_view(|i(name))
        !          1063: |end(computeroutput)
        !          1064: |blank_space(-1)
        !          1065: Change the current |cw(view) to |i(name).
        !          1066: Returns 0 if the |cw(view) was not found.
        !          1067: 
        !          1068: |begin(computeroutput)
        !          1069: void cin_views()
        !          1070: |end(computeroutput)
        !          1071: |blank_space(-1)
        !          1072: Print the available |cw(view)s.
        !          1073: The current |cw(view) is marked with an asterisk (|cw(*)).
        !          1074: 
        !          1075: |begin(computeroutput)
        !          1076: void cin_whatis(|i(name))
        !          1077: |end(computeroutput)
        !          1078: |blank_space(-1)
        !          1079: Print the type of the variable |i(name).
        !          1080: 
        !          1081: |begin(computeroutput)
        !          1082: void cin_where()
        !          1083: |end(computeroutput)
        !          1084: |blank_space(-1)
        !          1085: Print the trace of subroutine calls.
        !          1086: 
        !          1087: |begin(computeroutput)
        !          1088: void cin_quit()
        !          1089: |end(computeroutput)
        !          1090: |blank_space(-1)
        !          1091: Exit |i(cin).
        !          1092: 
        !          1093: |section(Summary Of Predefined Variables)
        !          1094: 
        !          1095: Several predefined variables are provided for the user.
        !          1096: 
        !          1097: |begin(computeroutput)
        !          1098: extern char *cin_libpath
        !          1099: |end(computeroutput)
        !          1100: |blank_space(-1)
        !          1101: A colon (|cw(:)) -separated list of libraries to search for undefined routines
        !          1102: (defaults to libraries specified on the command line and
        !          1103: ``|cw(-lc)'').
        !          1104: 
        !          1105: |begin(computeroutput)
        !          1106: extern char *cin_prompt
        !          1107: |end(computeroutput)
        !          1108: |blank_space(-1)
        !          1109: The ``interactive mode'' prompt (default ``|cw(cin>) '').
        !          1110: 
        !          1111: |section(Answers)
        !          1112: 
        !          1113: |subsection(Answer 1)
        !          1114: 
        !          1115: |blank_space(-1)
        !          1116: |begin(computeroutput)
        !          1117: |i($) cin -i
        !          1118: |i(cin>) int i;
        !          1119: |i(cin>) for (i = 20; i <= 30; ++i)
        !          1120:  printf("%d %g|sp(\)n",
        !          1121:   i, 9. / 5. * i + 32.);
        !          1122: |i(20 68
        !          1123: 21 69.8
        !          1124: 22 71.6
        !          1125: 23 73.4
        !          1126: 24 75.2
        !          1127: 25 77
        !          1128: 26 78.8
        !          1129: 27 80.6
        !          1130: 28 82.4
        !          1131: 29 84.2
        !          1132: 30 86
        !          1133: cin>) void main()
        !          1134: {
        !          1135:   int i;
        !          1136: 
        !          1137:   for (i = 20; i <= 30; ++i)
        !          1138:    printf("%d %g|sp(\)n",
        !          1139:      i, 9. / 5. * i + 32.);
        !          1140: }
        !          1141: |i(cin>) main();
        !          1142: |i(20 68
        !          1143: 21 69.8
        !          1144: 22 71.6
        !          1145: 23 73.4
        !          1146: 24 75.2
        !          1147: 25 77
        !          1148: 26 78.8
        !          1149: 27 80.6
        !          1150: 28 82.4
        !          1151: 29 84.2
        !          1152: 30 86
        !          1153: cin>) cin_quit();
        !          1154: |i($)
        !          1155: |end(computeroutput)
        !          1156: |blank_space(-1)
        !          1157: 
        !          1158: |subsection(Answer 2)
        !          1159: 
        !          1160: |blank_space(-1)
        !          1161: |begin(computeroutput)
        !          1162: void
        !          1163: prt(n)
        !          1164: struct node *n;
        !          1165: {
        !          1166:   switch(n->type) {
        !          1167: 
        !          1168:   default:
        !          1169:     printf("( ");
        !          1170:     prt(n->left);
        !          1171:     printf("%s ", n->value);
        !          1172:     prt(n->right);
        !          1173:     printf(") ");
        !          1174:     break;
        !          1175: 
        !          1176:   case UMINUS:
        !          1177:     printf("%s ", n->value);
        !          1178:     prt(n->right);
        !          1179:     break;
        !          1180: 
        !          1181:   case CONST:
        !          1182:   case VAR:
        !          1183:     printf("%s ", n->value);
        !          1184:     break;
        !          1185: 
        !          1186:   }
        !          1187: }
        !          1188: |end(computeroutput)
        !          1189: |blank_space(-1)
        !          1190: 
        !          1191: |subsection(Answer 3)
        !          1192: 
        !          1193: |blank_space(-1)
        !          1194: |begin(computeroutput)
        !          1195: (echo 'extern char *cin_prompt;
        !          1196: cin_prompt="";
        !          1197: #include <stdio.h>
        !          1198: #include <math.h>
        !          1199: char buf[1024], buf2[1024];
        !          1200: double t;
        !          1201: while(gets(buf) != NULL) {
        !          1202:   sprintf(buf2,
        !          1203:    "printf(|sp(\)"%%g|sp(\)|sp(\)n|sp(\)",t=(double)(%s));",
        !          1204:    buf);
        !          1205:     cin_eval(buf2);
        !          1206: }'; cat ) | cin -i
        !          1207: |end(computeroutput)
        !          1208: |blank_space(-1)
        !          1209: 
        !          1210: |section(Acknowledgements)
        !          1211: 
        !          1212: We thank Brian Kernighan
        !          1213: for permission to draw inspiration and borrow phrases from his editor tutorial.
        !          1214: We also thank
        !          1215: Sumit Bandyopadhyay,
        !          1216: Bill Carpenter,
        !          1217: Paul De Bra,
        !          1218: Alan Hastings,
        !          1219: Jonathan Helfman,
        !          1220: Andrew Hume,
        !          1221: Leonard Kasday,
        !          1222: Brian Kernighan,
        !          1223: Tom Kirk,
        !          1224: David Korn,
        !          1225: Lisa Kowalski,
        !          1226: Richard Maus,
        !          1227: Lawrence Mayka,
        !          1228: Doug McIlroy,
        !          1229: Marcel Meth,
        !          1230: Eric Muehrcke,
        !          1231: Jishnu Mukerji,
        !          1232: Rob Murray,
        !          1233: Sharon Peeters,
        !          1234: Mike Riley,
        !          1235: Larry Satz,
        !          1236: Judy Schmidt,
        !          1237: Timothy Schroeder,
        !          1238: Jonathan Shapiro,
        !          1239: Joe Steffen,
        !          1240: Andy Tripp,
        !          1241: Tom Walsh,
        !          1242: William Wetzel,
        !          1243: and
        !          1244: Myron Wish
        !          1245: for useful comments on previous versions of this paper.
        !          1246: 
        !          1247: |comment<
        !          1248: |style(one_column)
        !          1249: 
        !          1250: |signature(MH-11229-TJK/HHG/JJP-tjk/hhg/jjp)
        !          1251: >
        !          1252: 
        !          1253: |comment<
        !          1254: |notation(Att.
        !          1255: References)
        !          1256: 
        !          1257: |other
        !          1258: >
        !          1259: 
        !          1260: |reference_placement
        !          1261: 
        !          1262: |keywords(Rapid Prototyping,
        !          1263: Incremental Update,
        !          1264: C Programming)
        !          1265: 
        !          1266: |comment<
        !          1267: |mercury(cmp, elc)
        !          1268: 
        !          1269: |att(is_release yes)
        !          1270: 
        !          1271: |distribute_complete_memo(Executive Directors 112
        !          1272: Directors 112
        !          1273: Department Heads 1122
        !          1274: Sumit Bandyopadhyay
        !          1275: Bill Carpenter
        !          1276: Paul De Bra
        !          1277: Alan Hastings
        !          1278: Jonathan Helfman
        !          1279: Yean-Ming Huang
        !          1280: Andrew Hume
        !          1281: Leonard Kasday
        !          1282: Brian Kernighan
        !          1283: Tom Kirk
        !          1284: David Korn
        !          1285: Lisa Kowalski
        !          1286: Richard Maus
        !          1287: Lawrence Mayka
        !          1288: Doug McIlroy
        !          1289: Marcel Meth
        !          1290: Eric Muerhcke
        !          1291: Jishnu Mukerji
        !          1292: Rob Murray
        !          1293: Sharon Peeters
        !          1294: Mike Riley
        !          1295: Larry Satz
        !          1296: Judy Schmidt
        !          1297: Timothy Schroeder
        !          1298: Jonathan Shapiro
        !          1299: Joe Steffen
        !          1300: Andy Tripp
        !          1301: Tom Walsh
        !          1302: William Wetzel)
        !          1303: 
        !          1304: |distribute_cover_sheet(A. A. Penzias
        !          1305: 1122 MTS
        !          1306: Miguel Abdo
        !          1307: Tom Beattie
        !          1308: Jim Burnash
        !          1309: Tom Cargill
        !          1310: John Carter
        !          1311: Craig Cleaveland
        !          1312: Don deCourcelle
        !          1313: Helen Diamantidis
        !          1314: Laura Eaves
        !          1315: Faiq Fazal
        !          1316: Tom Foregger
        !          1317: Carol Franklin
        !          1318: Narain Gehani
        !          1319: Richard Greer
        !          1320: John Gregg
        !          1321: Jim Grenier
        !          1322: Inars Gruntals
        !          1323: Roy Harkness
        !          1324: Kurt Haserodt
        !          1325: Alan Hewett
        !          1326: Viet Hoang
        !          1327: James Holmes
        !          1328: Mike Hudson
        !          1329: Douglas Johnston
        !          1330: Jon Kaplowitz
        !          1331: Kevin Kinnear
        !          1332: Peter Kirslis
        !          1333: Balachander Krishnamurthy
        !          1334: Ajoy Kumar
        !          1335: David Lubinsky
        !          1336: Robert Lyons
        !          1337: John Malleo-Roach
        !          1338: Pat McGowan
        !          1339: Al McPherson
        !          1340: Douglas Miller
        !          1341: Datta Miruke
        !          1342: John Mocenigo
        !          1343: Dave Neal
        !          1344: Eric Olson
        !          1345: Joseph Patterson
        !          1346: Virginia Piccininni
        !          1347: Thomas Pisciotta
        !          1348: David Potter
        !          1349: Demetri Prountzos
        !          1350: Benjamin Reytblat
        !          1351: Ernie Rice
        !          1352: James Rowland
        !          1353: Ed Schan
        !          1354: William Schell
        !          1355: Carl Seaquist
        !          1356: Steve Shepherd
        !          1357: John Sherman
        !          1358: Tyrone Shiu
        !          1359: Les Shupe
        !          1360: David Smull
        !          1361: G. Mark Stewart
        !          1362: Art Storm
        !          1363: Rich Struse
        !          1364: Mark Swartz
        !          1365: Rick Thomas
        !          1366: Tim Thompson
        !          1367: Peter Ting
        !          1368: Gregg Vesonder
        !          1369: Yu-Lien Yen
        !          1370: John Young
        !          1371: Avi Zahavi)
        !          1372: 
        !          1373: |add_totals(other 4)
        !          1374: 
        !          1375: |cover_sheet
        !          1376: >

unix.superglobalmegacorp.com

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