home *** CD-ROM | disk | FTP | other *** search
- Path: iam!chx400!cernvax!mcsun!uunet!bbn.com!rsalz
- From: rsalz@uunet.uu.net (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v20i052: Portable compiler of the FP language, Part03/06
- Message-ID: <2060@papaya.bbn.com>
- Date: 24 Oct 89 16:05:20 GMT
- Lines: 1467
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Edoardo Biagioni <biagioni@cs.unc.edu>
- Posting-number: Volume 20, Issue 52
- Archive-name: fpc/part03
-
- # This is a shell archive.
- # Remove everything above and including the cut line.
- # Then run the rest of the file through sh.
- -----cut here-----cut here-----cut here-----cut here-----
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # code.c
- # code.h
- # expr.c
- echo shar: extracting code.c '(20383 characters)'
- sed 's/^XX//' << \SHAR_EOF > code.c
- XX/* code.c: produce code for the function encoded by the parse tree. */
- XX
- XX#include <stdio.h>
- XX#include <strings.h>
- XX#include "fpc.h"
- XX#include "parse.h"
- XX#include "code.h"
- XX#include "fp.h"
- XX
- XXstatic fpexpr preoptimize ();
- XXstatic void putheader ();
- XXstatic void putfinish ();
- XX
- XXextern void codeexpr ();
- XXextern char * sprintf ();
- XX
- XXstatic int varsneeded;
- XXstatic int selneeded;
- XX
- XX/* assumes that oldname ends in .fp. Returns "" if for some reason
- XX the file should not be opened. */
- XXvoid newfname (oldname, newname)
- XXchar * oldname, * newname;
- XX{
- XX int len;
- XX
- XX len = strlen (oldname);
- XX if ((oldname [len - 3] != '.') ||
- XX (oldname [len - 2] != 'f') ||
- XX (oldname [len - 1] != 'p'))
- XX {
- XX *newname = '\0';
- XX return;
- XX }
- XX (void) strcpy (newname, oldname);
- XX newname [len - 2] = 'c'; /* change .fp to .c */
- XX newname [len - 1] = '\0';
- XX}
- XX
- XXvoid code (fun, tree)
- XXchar * fun;
- XXfpexpr tree;
- XX{
- XX tree = preoptimize (tree);
- XX countvars (tree);
- XX putheader (fun, varsneeded, selneeded, tree);
- XX codeexpr (tree, "data", "res");
- XX putfinish (fun);
- XX}
- XX
- XXstatic void putdefine (name, val)
- XXchar * name, *val;
- XX{
- XX (void) fprintf (outf, "#define %s\t%s\n", name, val);
- XX}
- XX
- XXstatic void putdefnum (name, val)
- XXchar * name;
- XXint val;
- XX{
- XX (void) fprintf (outf, "#define %s\t%d\n", name, val);
- XX}
- XX
- XXstatic void putmain ()
- XX{
- XX char inproc [MAXIDLEN], outproc [MAXIDLEN];
- XX
- XX/* implementation should be refined, for now we don't do -c */
- XX if (check || (makeast && rstring) || traceptr)
- XX (void) fprintf (outf, "#include <stdio.h>\n");
- XX if (makemain && makeast && rstring)
- XX (void) fprintf (outf, "#include <sgtty.h>\n\n");
- XX else
- XX (void) fprintf (outf, "\n");
- XX if (makemain)
- XX {
- XX (void) strcpy (inproc, (rstring ? "getfpstring" : "getfpdata"));
- XX (void) strcpy (outproc, (wstring ? "putfpstrings" : "putfpdata"));
- XX if (makeast)
- XX (void) strcpy (inproc, (rstring ? "getfpchar" : "getfpdata"));
- XX if (redirout)
- XX (void) strcpy (outproc, "putcommands");
- XX (void) fprintf (outf, "main (argc, argv)\nint argc;\nchar * argv [];\n{\n");
- XX (void) fprintf (outf, " extern fp_data %s (), %s ();\n", inproc, mainfn);
- XX (void) fprintf (outf, " extern int fpargc;\n extern char ** fpargv;\n");
- XX if (check)
- XX if (printspace)
- XX (void) fprintf (outf, " extern void printstorage ();\n");
- XX else
- XX (void) fprintf (outf, " extern void checkstorage ();\n");
- XX if (makeast)
- XX {
- XX (void) fprintf (outf, " extern struct fp_object nilobj;\n");
- XX (void) fprintf (outf, " fp_data state;\n");
- XX (void) fprintf (outf, " static struct fp_constant initstate = ");
- XX (void) fprintf (outf, "{(short) NILOBJ, (short) 2};\n");
- XX if (rstring)
- XX {
- XX (void) fprintf (outf, " struct sgttyb newtty, oldtty;\n");
- XX (void) fprintf (outf, " struct sgttyb * savetty;\n");
- XX }
- XX }
- XX (void) fprintf (outf, " extern void %s ();\n fp_data input, result;\n\n",
- XX outproc);
- XX if (makeee || makedeb)
- XX (void) fprintf (outf,
- XX " (void) fprintf (stderr, \"entering main\\n\");\n");
- XX (void) fprintf (outf, " fpargc = argc;\n fpargv = argv;\n");
- XX if (makeast) /* produce an applicative state transition system */
- XX {
- XX if (rstring)
- XX {
- XX (void) fprintf (outf, " savetty = &oldtty;\n");
- XX (void) fprintf (outf, " ioctl (0, TIOCGETP, &oldtty);\n");
- XX (void) fprintf (outf, " ioctl (0, TIOCGETP, &newtty);\n");
- XX (void) fprintf (outf, " newtty.sg_flags |= CBREAK;\n");
- XX (void) fprintf (outf, " ioctl (0, TIOCSETP, &newtty);\n");
- XX }
- XX (void) fprintf (outf, " state = (fp_data) & initstate;\n");
- XX (void) fprintf (outf, " input = newpair ();\n");
- XX (void) fprintf (outf, " input->fp_header.fp_next->fp_entry =");
- XX (void) fprintf (outf, " (fp_data) & nilobj;\n");
- XX (void) fprintf (outf, " input->fp_entry = & nilobj;\n");
- XX (void) fprintf (outf, " while (1)\n {\n");
- XX (void) fprintf (outf, " result = %s (input);\n", mainfn);
- XX if (check)
- XX {
- XX (void) fprintf (outf, " if ((result->fp_type != VECTOR) ||\n");
- XX (void) fprintf (outf, " (result->fp_header.fp_next == 0) ||\n");
- XX (void) fprintf (outf, " (result->%s != 0))\n",
- XX "fp_header.fp_next->fp_header.fp_next");
- XX (void) fprintf (outf,
- XX " genbottom (\"non-pair returned in AST\", result);\n");
- XX }
- XX (void) fprintf (outf,
- XX " state = result->fp_header.fp_next->fp_entry;\n");
- XX (void) fprintf (outf, " %s (result->fp_entry);\n", outproc);
- XX (void) fprintf (outf, " if (state->fp_type == NILOBJ)\n");
- XX (void) fprintf (outf, " break;\n");
- XX (void) fprintf (outf, " inc_ref (state);\n");
- XX (void) fprintf (outf, " dec_ref (result);\n");
- XX (void) fprintf (outf, " input = newpair ();\n");
- XX (void) fprintf (outf,
- XX " input->fp_header.fp_next->fp_entry = state;\n");
- XX (void) fprintf (outf, " input->fp_entry = %s ();\n", inproc);
- XX (void) fprintf (outf, " }\n dec_ref (result);\n");
- XX if (rstring)
- XX (void) fprintf (outf, " ioctl (0, TIOCSETP, &oldtty);\n");
- XX }
- XX else /* normal, non-ast system */
- XX {
- XX if (useparms)
- XX {
- XX (void) fprintf (outf, " if (fpargc != 1)\n");
- XX (void) fprintf (outf, " input = & nilobj;\n");
- XX (void) fprintf (outf, " else\n ");
- XX }
- XX (void) fprintf (outf, " input = %s ();\n", inproc);
- XX (void) fprintf (outf, " result = %s (input);\n", mainfn);
- XX (void) fprintf (outf, " %s (result);\n", outproc);
- XX (void) fprintf (outf, " dec_ref (result);\n");
- XX }
- XX if (makeee || makedeb)
- XX (void) fprintf (outf,
- XX " (void) fprintf (stderr, \"exiting main\\n\");\n");
- XX if (check)
- XX if (printspace)
- XX (void) fprintf (outf, " printstorage ();\n");
- XX else
- XX (void) fprintf (outf, " checkstorage ();\n");
- XX (void) fprintf (outf, " return (0);\n}\n\n");
- XX }
- XX}
- XX
- XXvoid putfileheader (in, out)
- XXchar * in;
- XXchar * out;
- XX{
- XX (void) fprintf (outf, "/* %s: target file generated by fpc from source %s */\n\n",
- XX out, in);
- XX putdefnum ("FALSEOBJ ", FALSEOBJ);
- XX putdefnum ("TRUEOBJ ", TRUEOBJ);
- XX putdefnum ("INTCONST ", INTCONST);
- XX putdefnum ("FLOATCONST", FLOATCONST);
- XX putdefnum ("ATOMCONST ", ATOMCONST);
- XX putdefnum ("CHARCONST ", CHARCONST);
- XX putdefnum ("NILOBJ ", NILOBJ);
- XX putdefnum ("VECTOR ", VECTOR);
- XX (void) fprintf (outf, "\ntypedef struct fp_object * fp_data;\n\n");
- XX (void) fprintf (outf,
- XX "struct fp_object\n{\n short fp_type;\n short fp_ref;\n");
- XX (void) fprintf (outf, " union\n {\n long fp_int;\n int fp_char;\n");
- XX (void) fprintf (outf, " char * fp_atom;\n float fp_float;\n");
- XX (void) fprintf (outf, " fp_data fp_next;\n } fp_header;\n");
- XX (void) fprintf (outf, " fp_data fp_entry;\n};\n\n");
- XX (void) fprintf (outf, "struct fp_constant\n{\n short fp_type;\n");
- XX (void) fprintf (outf, " short fp_ref;\n %s fp_value;\n", HEADERTYPE);
- XX (void) fprintf (outf, " fp_data fp_entry;\n};\n\n");
- XX (void) fprintf (outf, "struct fp_floatc\n{\n short fp_type;\n");
- XX (void) fprintf (outf, " short fp_ref;\n %s fp_value;\n};\n\n", HEADERFLOAT);
- XX (void) fprintf (outf, "struct fp_charc\n{\n short fp_type;\n");
- XX (void) fprintf (outf, " short fp_ref;\n %s fp_value;\n};\n\n", HEADERCHAR);
- XX if (check)
- XX {
- XX (void) fprintf (outf, "struct stackframe\n{\n char * st_name;\n");
- XX (void) fprintf (outf, " fp_data st_data;\n");
- XX (void) fprintf (outf, " struct stackframe * st_prev;\n};\n");
- XX (void) fprintf (outf, "extern struct stackframe * stack;\n\n");
- XX }
- XX (void) fprintf (outf, "extern fp_data newvect ();\n");
- XX (void) fprintf (outf, "extern fp_data newpair ();\n");
- XX (void) fprintf (outf, "extern fp_data newcell ();\n");
- XX (void) fprintf (outf, "extern fp_data newconst ();\n");
- XX (void) fprintf (outf, "extern void returnvect ();\n");
- XX (void) fprintf (outf, "extern struct fp_object nilobj;\n");
- XX (void) fprintf (outf, "extern struct fp_object tobj;\n");
- XX (void) fprintf (outf, "extern struct fp_object fobj;\n\n");
- XX if (makedeb || makeee || traceptr)
- XX (void) fprintf (outf, "extern int depthcount;\nextern int indent ();\n\n");
- XX if (makedeb || traceptr)
- XX (void) fprintf (outf, "extern void printfpdata ();\n\n");
- XX if (check)
- XX (void) fprintf (outf, "extern void genbottom ();\n\n");
- XX putdefine ("inc_ref(d)", "((d)->fp_ref++)");
- XX putdefine ("dec_ref(d)",
- XX"if (((d)->fp_type == VECTOR) && \\\n\t\t\t\t(--((d)->fp_ref) <= 0)) returnvect (d)");
- XX putdefine ("abs(n)", "((n) < 0 ? - (n) : (n))");
- XX (void) fprintf (outf, "\n");
- XX putmain ();
- XX}
- XX
- XXvoid putfiletail ()
- XX{
- XX (void) fprintf (outf, "\n");
- XX}
- XX
- XXstatic void traverse (tree, fn, pre)
- XX/* traverses the tree, calling fn on each and every node */
- XXfpexpr tree;
- XXvoid ((* fn) ());
- XXint pre;
- XX{
- XX fpexpr save = tree;
- XX
- XX if (pre)
- XX (* fn) (tree);
- XX switch (tree->exprtype)
- XX {
- XX case COND:
- XX traverse (tree->fpexprv.conditional [0], (* fn), pre);
- XX traverse (tree->fpexprv.conditional [1], (* fn), pre);
- XX traverse (tree->fpexprv.conditional [2], (* fn), pre);
- XX break;
- XX case BU:
- XX case BUR:
- XX traverse (tree->fpexprv.bulr.bufun, (* fn), pre);
- XX traverse (tree->fpexprv.bulr.buobj, (* fn), pre);
- XX break;
- XX case WHILE:
- XX traverse (tree->fpexprv.whilestat [0], (* fn), pre);
- XX traverse (tree->fpexprv.whilestat [1], (* fn), pre);
- XX break;
- XX case COMP:
- XX case CONSTR:
- XX while (tree != 0)
- XX {
- XX traverse (tree->fpexprv.compconstr.compexpr, (* fn), pre);
- XX tree = tree->fpexprv.compconstr.compnext;
- XX }
- XX break;
- XX case AA:
- XX case INSERT:
- XX case RINSERT:
- XX case TREE:
- XX case MULTI:
- XX traverse (tree->fpexprv.aains, (* fn), pre);
- XX break;
- XX case LIST:
- XX while (tree != 0)
- XX {
- XX traverse (tree->fpexprv.listobj.listel, (* fn), pre);
- XX tree = tree->fpexprv.listobj.listnext;
- XX }
- XX break;
- XX case SEL:
- XX case RSEL:
- XX case FNCALL:
- XX case NIL:
- XX case TRUE:
- XX case FALSE:
- XX case INT:
- XX case FLOAT:
- XX case SYM:
- XX case CHAR:
- XX break;
- XX default:
- XX yyerror ("compiler error 11");
- XX }
- XX if (! pre)
- XX (* fn) (save);
- XX}
- XX
- XXstatic void opt (tree)
- XXfpexpr tree;
- XX{
- XX if (((tree->exprtype == INSERT) ||
- XX (tree->exprtype == RINSERT) ||
- XX (tree->exprtype == TREE)) &&
- XX (tree->fpexprv.aains->exprtype == FNCALL) &&
- XX ((strcmp (tree->fpexprv.aains->fpexprv.funcall, "plus") == 0) ||
- XX (strcmp (tree->fpexprv.aains->fpexprv.funcall, "times") == 0) ||
- XX (strcmp (tree->fpexprv.aains->fpexprv.funcall, "and") == 0) ||
- XX (strcmp (tree->fpexprv.aains->fpexprv.funcall, "or") == 0)))
- XX/* means we can replace the call to insert by a call to MULTI */
- XX tree->exprtype = MULTI;
- XX/* wasn't that easy, now? */
- XX}
- XX
- XXstatic fpexpr preoptimize (tree)
- XXfpexpr tree;
- XX{ /* as long as it doesn't change the meaning of the program,
- XX * everything is fair game here */
- XX/* the only optimization we do here is change (insert <f>), where <f>
- XX * is one of {plus, times, and, or} to (multi <f>)
- XX */
- XX traverse (tree, opt, 0);
- XX return (tree);
- XX}
- XX
- XXstatic int nodevars (tree)
- XXfpexpr tree;
- XX{
- XX char errbuf [256];
- XX
- XX switch (tree->exprtype)
- XX {
- XX case COND:
- XX/* a -> b ; c : res := a; if (res) then res := b; else res := c; end */
- XX case FNCALL:
- XX/* f: res := f (arg); */
- XX case SEL:
- XX/* n: i1 := n; res := arg; while (--i1 > 0) res := cdr (res);
- XX res := car (res); */
- XX case RSEL:
- XX/* n: i1 := 0; res := arg; while (res != 0) res := cdr (res); i1++;
- XX i1 := i1 - n; res := arg; while (--i1 != 0) res := cdr (res);
- XX res := car (res); */
- XX case NIL:
- XX case TRUE:
- XX case FALSE:
- XX case INT:
- XX case FLOAT:
- XX case SYM:
- XX case CHAR:
- XX case LIST: /* called for each list element */
- XX return (0);
- XX
- XX case COMP:
- XX/* a o b o c o d : r1 := d (arg); r2 := c (r1); r1 := b (r2); res := a (r1); */
- XX if ((tree->fpexprv.compconstr.compnext != 0) && /* should never happen */
- XX(tree->fpexprv.compconstr.compnext->fpexprv.compconstr.compnext != 0))
- XX return (2);
- XX case CONSTR:
- XX/* [a, b] : res := new (2); chase := res; chase->car := b (arg);
- XX chase = cdr (chase); chase->car := a (arg); */
- XX case BU:
- XX/* bu op v : res := v; r1 := newvect (res, arg); res := op (r1); */
- XX case BUR:
- XX/* bur op v : res := v; r1 := newvect (arg, res); res := op (r1); */
- XX case MULTI:
- XX/* \/f: r1 := arg; res := car (r1);
- XX while (r1 != 0) res := op (res, car (r1)); r1 := cdr (r1); */
- XX return (1);
- XX
- XX case RINSERT:
- XX/* \a : res := car (arg); r1 := cdr (arg);
- XX while (r1 != 0) r2 := cons (res, cons (car (r1), nil));
- XX res := a (r2); r1 := cdr (r1); */
- XX case AA:
- XX/* aa e : if (arg == <>) then res := arg;
- XX else r1 := arg; res := newvect (1); r2 := res;
- XX while (r1 != 0) r2->el := e (car r1); r1 := cdr (r1);
- XX if (r1 != 0) r2->next = newvect (1); r2 = cdr (r2); */
- XX case WHILE:
- XX/* while pred f : res := arg;
- XX while (1)
- XX r1 := pred (res); if (! r1) then break; arg := f (res); res := arg; */
- XX return (2);
- XX
- XX case INSERT:
- XX/* /a : r1 := 0; r2 := arg;
- XX while (r2 != 0) r3 := cons (car (r2), r1); r1 := r3; r2 := cdr (r2);
- XX res := car (r1); r1 := cdr (r1);
- XX while (r1 != 0) r2 := cons (car (r1), cons (res, nil)); res := a (r2);
- XX r1 := cdr (r1); */
- XX return (3);
- XX
- XX case TREE:
- XX/* \/a: r1 := arg;
- XX while (cdr (r1) != 0)
- XX r2 := r1; r1 := newcell (); r3 := r1;
- XX while (r2 != 0)
- XX if (cdr (r2) == 0) rplaca (r3, car (r2)); r2 := 0;
- XX else
- XX r4 := cons (car (r2), cons (cadr (r2), nil)); r2 := cddr (r2);
- XX rplaca (r3, a(r4));
- XX if (r2 != 0) rplacd (r3, newcell ()); r3 := cdr (r3);
- XX res := car (r1); */
- XX return (5); /* one more needed for storage management */
- XX
- XX default:
- XX (void) sprintf (errbuf, "compiler error 12, type is %d", tree->exprtype);
- XX yyerror (errbuf);
- XX return (-1);
- XX }
- XX}
- XX
- XXstatic void countvar (tree)
- XXfpexpr tree;
- XX{
- XX varsneeded += nodevars (tree);
- XX selneeded = selneeded ||
- XX (((tree->exprtype == SEL) || (tree->exprtype == RSEL)) &&
- XX (tree->fpexprv.lrsel > 1));
- XX}
- XX
- XXstatic countvars (tree)
- XXfpexpr tree;
- XX{
- XX varsneeded = 0;
- XX selneeded = 0;
- XX traverse (tree, countvar, 1);
- XX}
- XX
- XXstatic int constcount;
- XX
- XXstatic void declconst (tree)
- XXfpexpr tree;
- XX/* traverse procedure called in post-order traversal. It generates a
- XX * new "constant variable" for the constant and stores it in the tree.
- XX * It also generates a declaration for the constant itself, using
- XX * the "constant variables" of the elements in case of lists.
- XX * A constant declaration is of the form.
- XX * static fp_data cnn = {type, 1, val, entry}
- XX */
- XX{
- XX static char def1 [] = " static struct fp_constant ";
- XX static char def2 [] = " =\n {(short) ";
- XX static char def3 [] = ", (short) 1";
- XX fpexpr next;
- XX
- XX if (tree->exprtype >= NIL)
- XX {
- XX (void) sprintf (tree->constvar, "c%d", constcount++);
- XX/* we always use a new constant "variable" for a new constant
- XX * encountered. That may be updated later to allow sharing of
- XX * equal constants, as in equal nil/true/false and (less often)
- XX * numbers, strings or lists. Not a high priority item, on V.M.
- XX * systems */
- XX switch (tree->exprtype)
- XX {
- XX case FALSE:
- XX (void) fprintf (outf, "%s%s%s%s%s};\n", def1, tree->constvar,
- XX def2, "FALSEOBJ", def3);
- XX break;
- XX case TRUE:
- XX (void) fprintf (outf, "%s%s%s%s%s};\n", def1, tree->constvar,
- XX def2, "TRUEOBJ", def3);
- XX break;
- XX case NIL:
- XX (void) fprintf (outf, "%s%s%s%s%s};\n", def1, tree->constvar,
- XX def2, "NILOBJ", def3);
- XX break;
- XX case INT:
- XX (void) fprintf (outf, "%s%s%s%s%s, (%s) %d};\n", def1, tree->constvar,
- XX def2, "INTCONST", def3, HEADERTYPE,
- XX tree->fpexprv.intobj);
- XX break;
- XX case FLOAT:
- XX (void) fprintf (outf, "%s%s%s%s%s, %lf};\n",
- XX " static struct fp_floatc ", tree->constvar,
- XX def2, "FLOATCONST", def3, tree->fpexprv.floatobj);
- XX break;
- XX case SYM:
- XX (void) fprintf (outf, "%s%s%s%s%s, (%s) \"%s\"};\n", def1,
- XX tree->constvar, def2, "ATOMCONST", def3,
- XX HEADERTYPE, tree->fpexprv.symbol);
- XX break;
- XX case CHAR:
- XX (void) fprintf (outf, "%s%s%s%s%s, '\\%o'};\n",
- XX " static struct fp_charc ", tree->constvar,
- XX def2, "CHARCONST", def3, tree->fpexprv.character);
- XX break;
- XX case LIST:
- XX next = tree->fpexprv.listobj.listnext;
- XX if (next != 0)
- XX declconst (next);
- XX (void) fprintf (outf, "%s%s%s%s%s, (%s) %c%s, (fp_data) &%s};\n", def1,
- XX tree->constvar, def2, "VECTOR", def3, HEADERTYPE,
- XX ((next == 0) ? '0' : '&'),
- XX ((next == 0) ? "" : next->constvar),
- XX tree->fpexprv.listobj.listel->constvar);
- XX break;
- XX default: /* error */
- XX yyerror ("compiler error 13");
- XX }
- XX } /* else it is not a constant, ignore it */
- XX}
- XX
- XXstatic char externs [MAXIDS] [MAXIDLEN];
- XXstatic int extptr;
- XX
- XXstatic void putoneextern (tree)
- XXfpexpr tree;
- XX{
- XX int search = 0;
- XX char buf [MAXIDLEN];
- XX
- XX if (tree->exprtype == FNCALL)
- XX {
- XX if (strcmp (tree->fpexprv.funcall, "times") == 0)
- XX (void) strcpy (buf, "fptimes");
- XX else
- XX (void) strcpy (buf, tree->fpexprv.funcall);
- XX while ((search < extptr) &&
- XX (strcmp (buf, externs [search]) != 0))
- XX search++;
- XX if (search == extptr) /* must insert new name */
- XX (void) strcpy (externs [extptr++], buf);
- XX }
- XX}
- XX
- XXstatic void putexterns (tree, fun)
- XXfpexpr tree;
- XXchar * fun;
- XX{
- XX (void) strcpy (externs [0], fun);
- XX extptr = 1;
- XX traverse (tree, putoneextern, 1);
- XX if (extptr > 1)
- XX {
- XX (void) fprintf (outf, " extern fp_data");
- XX while (--extptr > 0)
- XX {
- XX (void) fprintf (outf, " %s ()%s", externs [extptr],
- XX (extptr == 1) ? ";\n" : ",");
- XX if (((extptr - 1) & DCLEMASK) == DCLEMASK)
- XX (void) fprintf (outf, "\n\t\t");
- XX }
- XX }
- XX}
- XX
- XXstatic int freevar;
- XX
- XXstatic void declvars (vars, hassel)
- XXint vars, hassel;
- XX{
- XX freevar = 0;
- XX if (hassel)
- XX (void) fprintf (outf, " register int sel;\n");
- XX (void) fprintf (outf, " fp_data");
- XX while (vars-- > 0)
- XX {
- XX (void) fprintf (outf, " d%d,", vars);
- XX if ((vars & DCLMASK) == DCLMASK)
- XX (void) fprintf (outf, "\n\t ");
- XX }
- XX (void) fprintf (outf, " res;\n");
- XX if (check)
- XX (void) fprintf (outf, " struct stackframe stackentry;\n");
- XX (void) fprintf (outf, "\n");
- XX}
- XX
- XXvoid newvar (buf)
- XXchar * buf;
- XX{
- XX (void) sprintf (buf, "d%d", freevar++);
- XX}
- XX
- XXstatic int tracingfn;
- XX
- XXstatic void entertrace (fname)
- XXchar * fname;
- XX{
- XX if (makeee || makedeb || tracingfn)
- XX {
- XX (void) fprintf (outf,
- XX " depthcount += 2;\n indent (depthcount, stderr);\n");
- XX if (makedeb || tracingfn)
- XX {
- XX (void) fprintf (outf, " (void) fprintf (stderr, \"entering %s, data is\\n\");\n",
- XX fname);
- XX (void) fprintf (outf, " printfpdata (stderr, data, depthcount);\n");
- XX (void) fprintf (outf, " (void) fprintf (stderr, \"\\n\");\n");
- XX }
- XX else
- XX (void) fprintf (outf, " (void) fprintf (stderr, \"entering %s\\n\");\n", fname);
- XX }
- XX if (check) /* keep the stack */
- XX {
- XX (void) fprintf (outf, " stackentry.st_prev = stack;\n");
- XX (void) fprintf (outf, " stackentry.st_data = data;\n inc_ref (data);\n");
- XX (void) fprintf (outf, " stackentry.st_name = \"%s\";\n", fname);
- XX (void) fprintf (outf, " stack = & stackentry;\n", fname);
- XX }
- XX}
- XX
- XXstatic void putheader (fname, vars, hassel, tree)
- XXchar * fname;
- XXint vars, hassel;
- XXfpexpr tree;
- XX{
- XX int trace;
- XX
- XX for (trace = 0;
- XX (trace < traceptr) && (strcmp (tracefns [trace], fname) != 0);
- XX trace++)
- XX ;
- XX tracingfn = (trace < traceptr); /* are we tracing this function? */
- XX (void) fprintf (outf, "fp_data %s (data)\nfp_data data;\n{\n", fname);
- XX putexterns (tree, fname);
- XX constcount = 0;
- XX traverse (tree, declconst, 0); /* declare the static constants */
- XX declvars (vars, hassel);
- XX entertrace (fname);
- XX}
- XX
- XXstatic void putfinish (fname)
- XXchar * fname;
- XX{
- XX if (makeee || makedeb || tracingfn)
- XX {
- XX (void) fprintf (outf,
- XX " indent (depthcount, stderr);\n depthcount -= 2;\n");
- XX if (makedeb || tracingfn)
- XX {
- XX (void) fprintf (outf, " (void) fprintf (stderr, \"exiting %s, result is\\n\");\n",
- XX fname);
- XX (void) fprintf (outf, " printfpdata (stderr, res, depthcount);\n");
- XX (void) fprintf (outf, " (void) fprintf (stderr, \"\\n\");\n");
- XX }
- XX else
- XX (void) fprintf (outf, " (void) fprintf (stderr, \"exiting %s\\n\");\n", fname);
- XX }
- XX if (check) /* restore the stack */
- XX {
- XX (void) fprintf (outf, " dec_ref (data);\n");
- XX (void) fprintf (outf, " stack = stackentry.st_prev;\n");
- XX }
- XX (void) fprintf (outf, " return (res);\n}\n\n");
- XX tracingfn = 0;
- XX}
- SHAR_EOF
- if test 20383 -ne "`wc -c code.c`"
- then
- echo shar: error transmitting code.c '(should have been 20383 characters)'
- fi
- echo shar: extracting code.h '(843 characters)'
- sed 's/^XX//' << \SHAR_EOF > code.h
- XX/* code.h: defines the constants used by code.c not declared in parse.h */
- XX
- XX#define DCLMASK 0x7 /* There will be at most DCLMASK+1 declarations */
- XX /* on a single line. This value only affects */
- XX /* pretty-printing and should be 2^x-1 for some x */
- XX
- XX#define DCLEMASK 0x3 /* Like DCLMASK, but for externs, which are longer */
- XX
- XX#define HEADERTYPE "long"
- XX /* this must be a type of the same size as the */
- XX /* largest element of the union {...} fp_header */
- XX /* in the declaration of fp_object. Otherwise, */
- XX /* the declaration of constants will be incorrect */
- XX
- XX#define HEADERFLOAT "float" /* this is the type of fp_float */
- XX
- XX#define HEADERCHAR "int" /* this is the type of fp_char */
- XX
- XX#define BRACE (void) fprintf (outf, "%s{\n", indentstr ()); indent (1)
- XX
- XX#define UNBRACE (void) indent (0); fprintf (outf, "%s}\n", indentstr ())
- SHAR_EOF
- if test 843 -ne "`wc -c code.h`"
- then
- echo shar: error transmitting code.h '(should have been 843 characters)'
- fi
- echo shar: extracting expr.c '(26310 characters)'
- sed 's/^XX//' << \SHAR_EOF > expr.c
- XX/* expr.c: produce code for the expression encoded by the parse tree. */
- XX
- XX#include <stdio.h>
- XX#include <strings.h>
- XX#include "fpc.h"
- XX#include "parse.h"
- XX#include "code.h"
- XX#include "fp.h"
- XX
- XXextern void newvar ();
- XXextern char * sprintf ();
- XX
- XXstatic void codecond ();
- XXstatic void codebu ();
- XXstatic void codewhile ();
- XXstatic void codecomp ();
- XXstatic void codeaa ();
- XXstatic void codeconstr ();
- XXstatic void codeinsert ();
- XXstatic void codesel ();
- XXstatic void codefncall ();
- XXstatic void codeconst ();
- XXstatic void codemulti ();
- XX
- XXvoid codeexpr (tree, invar, outvar)
- XXfpexpr tree;
- XXchar * invar, * outvar;
- XX{
- XX int type = 0;
- XX/* used to distinguish between slightly different functional forms that
- XX * use the same procedure to generate code.
- XX */
- XX
- XX switch (tree->exprtype)
- XX {
- XX case COND:
- XX codecond (tree, invar, outvar);
- XX break;
- XX case BUR:
- XX type++;
- XX case BU:
- XX codebu (tree, type, invar, outvar);
- XX break;
- XX case WHILE:
- XX codewhile (tree, invar, outvar);
- XX break;
- XX case COMP:
- XX codecomp (tree, invar, outvar);
- XX break;
- XX case AA:
- XX codeaa (tree, invar, outvar);
- XX break;
- XX case CONSTR:
- XX codeconstr (tree, invar, outvar);
- XX break;
- XX case TREE:
- XX type++;
- XX case RINSERT:
- XX type++;
- XX case INSERT:
- XX codeinsert (tree, type, invar, outvar);
- XX break;
- XX case MULTI:
- XX codemulti (tree, invar, outvar);
- XX break;
- XX case RSEL:
- XX type++;
- XX case SEL:
- XX codesel (tree, type, invar, outvar);
- XX break;
- XX case FNCALL:
- XX codefncall (tree, invar, outvar);
- XX break;
- XX default:
- XX if ((tree->exprtype >= NIL) && (tree->exprtype <= CHAR))
- XX codeconst (tree, invar, outvar);
- XX else
- XX yyerror ("compiler error 10");
- XX }
- XX}
- XX
- XXstatic int indlev = 1;
- XX
- XXstatic void indent (plus)
- XXint plus;
- XX{
- XX if (plus > 0)
- XX indlev++;
- XX else
- XX indlev--;
- XX}
- XX
- XXstatic char * indentstr ()
- XX/* returns a reference to a string with 2*indlev blanks. Notice that
- XX * successive calls will refer to the same string.... 'nuff said. */
- XX{
- XX register char * str;
- XX register int count;
- XX static char blanks [1024] = "";
- XX
- XX if (indlev > 511)
- XX yyerror ("error: expression nesting too great");
- XX count = indlev;
- XX for (str = blanks; count > 3; *(str++) = '\t')
- XX count -= 4;
- XX count *= 2;
- XX for ( ; count > 0; *(str++) = ' ')
- XX count -= 1;
- XX *str = '\0';
- XX return (blanks);
- XX}
- XX
- XXstatic void codecond (tree, invar, outvar)
- XXfpexpr tree;
- XXchar * invar, * outvar;
- XX/* a -> b ; c : res := a; if (res) then res := b; else res := c; end */
- XX{
- XX (void) fprintf (outf, "%sinc_ref (%s);\n", indentstr (), invar);
- XX codeexpr (tree->fpexprv.conditional [0], invar, outvar); /* r := a (d); */
- XX (void) fprintf (outf, "%sif (%s->fp_type%s)\n", /* if (r) */
- XX indentstr (), outvar, (check)? " == TRUEOBJ" : "");
- XX BRACE;
- XX codeexpr (tree->fpexprv.conditional [1], invar, outvar); /* r := b (d); */
- XX UNBRACE;
- XX (void) fprintf (outf, "%selse", indentstr ()); /* else */
- XX if (check)
- XX (void) fprintf (outf, " if (%s->fp_type == FALSEOBJ)", outvar);
- XX (void) fprintf (outf, "\n");
- XX BRACE;
- XX codeexpr (tree->fpexprv.conditional [2], invar, outvar); /* r := c (d); */
- XX UNBRACE;
- XX if (check)
- XX (void) fprintf (outf,
- XX "%selse\n%s genbottom (\"%s\", %s);\n",
- XX indentstr (), indentstr (), "in conditional: non-boolean pred",
- XX outvar);
- XX}
- XX
- XXstatic void codebu (tree, right, invar, outvar)
- XXfpexpr tree;
- XXint right;
- XXchar * invar, * outvar;
- XX/* bu op v : res := v; r1 := newvect (res, arg); res := op (r1);
- XX bur op v : res := v; r1 := newvect (arg, res); res := op (r1); */
- XX{
- XX char pair [MAXIDLEN];
- XX/* later on should optimize bu/r op x for op in {=, !=, +, -, *, div, mod}
- XX * and for x an atomic type */
- XX
- XX codeconst (tree->fpexprv.bulr.buobj, "", outvar);
- XX newvar (pair);
- XX (void) fprintf (outf, "%s%s = newpair ();\n", indentstr (), pair);
- XX (void) fprintf (outf, "%s%s->fp_header.fp_next->fp_entry = %s;\n",
- XX indentstr (), pair, (right) ? outvar : invar);
- XX (void) fprintf (outf, "%s%s->fp_entry = %s;\n",
- XX indentstr (), pair, (right) ? invar : outvar);
- XX codeexpr (tree->fpexprv.bulr.bufun, pair, outvar);
- XX}
- XX
- XXstatic void codewhile (tree, invar, outvar)
- XXfpexpr tree;
- XXchar * invar, * outvar;
- XX/* while pred f : res := arg;
- XX while (1)
- XX r1 := pred (res); if (! r1) then break; arg := f (res); res := arg; */
- XX{
- XX char predicate [MAXIDLEN];
- XX char result [MAXIDLEN];
- XX
- XX newvar (predicate);
- XX newvar (result);
- XX (void) fprintf (outf, "%s%s = %s;\n%swhile (1)\n",
- XX indentstr (), outvar, invar, indentstr ());
- XX BRACE;
- XX (void) fprintf (outf, "%sinc_ref (%s);\n", indentstr (), outvar);
- XX codeexpr (tree->fpexprv.whilestat [0], outvar, predicate);
- XX/* notice: need not dec_ref (predicate) since the result is
- XX ALWAYS a boolean, so dec_ref'ing it would make no difference */
- XX (void) fprintf (outf, "%sif (%s %s->fp_type)\n%s break;\n",
- XX indentstr (), ((check) ? "FALSEOBJ ==" : "!"),
- XX predicate, indentstr ());
- XX if (check)
- XX (void) fprintf (outf, "%selse if (%s->fp_type != TRUEOBJ)\n%s %s%s);\n",
- XX indentstr (), predicate, indentstr (),
- XX "genbottom (\"predicate for while is not boolean\", ", predicate);
- XX codeexpr (tree->fpexprv.whilestat [1], outvar, result);
- XX (void) fprintf (outf, "%s%s = %s;\n", indentstr (), outvar, result);
- XX UNBRACE;
- XX}
- XX
- XXstatic void codecomp (tree, invar, outvar)
- XXfpexpr tree;
- XXchar * invar, * outvar;
- XX/* a o b o c o d : r1 := d (arg); r2 := c (r1); r1 := b (r2); res := a (r1); */
- XX/* we need to alternate use of r1 and r2 since some of the functional forms
- XX will generate wierd code if given the same input and output variable */
- XX{
- XX char pass [2] [MAXIDLEN];
- XX char count = 0;
- XX
- XX newvar (pass [0]);
- XX if ((tree->fpexprv.compconstr.compnext != 0) && /* should never happen */
- XX (tree->fpexprv.compconstr.compnext->fpexprv.compconstr.compnext != 0))
- XX/* the second expression will return false if we have (a o b) */
- XX newvar (pass [1]);
- XX while (tree != 0)
- XX {
- XX if (tree->fpexprv.compconstr.compnext != 0)
- XX codeexpr (tree->fpexprv.compconstr.compexpr, invar, pass [count]);
- XX else
- XX codeexpr (tree->fpexprv.compconstr.compexpr, invar, outvar);
- XX invar = pass [count];
- XX count = (count + 1) % 2;
- XX tree = tree->fpexprv.compconstr.compnext;
- XX }
- XX}
- XX
- XXstatic void codeaa (tree, invar, outvar)
- XXfpexpr tree;
- XXchar * invar, * outvar;
- XX/* aa e : if (arg == <>) then res := arg;
- XX else r1 := arg; res := newcell (); r2 := res;
- XX while (r1 != 0) r2->el := e (car r1); r1 := cdr (r1);
- XX if (r1 != 0) r2->next = newcell (); r2 = cdr (r2); */
- XX{
- XX char chasearg [MAXIDLEN], chaseres [MAXIDLEN], tempres [MAXIDLEN],
- XX tempval [MAXIDLEN];
- XX
- XX (void) fprintf (outf, "%sif (%s->fp_type == NILOBJ)\n%s %s = %s;\n%selse",
- XX indentstr (), invar, indentstr (), outvar, invar, indentstr ());
- XX if (check)
- XX (void) fprintf (outf, " if (%s->fp_type == VECTOR)", invar);
- XX newvar (chasearg);
- XX newvar (chaseres);
- XX (void) fprintf (outf, "\n");
- XX BRACE;
- XX (void) fprintf (outf, "%s%s = %s;\n%s%s = %s = newcell ();\n",
- XX indentstr (), chasearg, invar,
- XX indentstr (), chaseres, outvar);
- XX (void) fprintf (outf, "%swhile (1)\n", indentstr ());
- XX BRACE;
- XX (void) sprintf (tempres, "%s->fp_entry", chaseres);
- XX (void) sprintf (tempval, "%s->fp_entry", chasearg);
- XX (void) fprintf (outf, "%sinc_ref (%s);\n", indentstr (), tempval);
- XX codeexpr (tree->fpexprv.aains, tempval, tempres);
- XX (void) fprintf (outf, "%sif (%s = %s->fp_header.fp_next)\n",
- XX indentstr (), chasearg, chasearg, indentstr ());
- XX (void) fprintf (outf, "%s %s = %s->fp_header.fp_next = newcell ();\n",
- XX indentstr (), chaseres, chaseres);
- XX (void) fprintf (outf, "%selse\n%s break;\n", indentstr (), indentstr ());
- XX UNBRACE;
- XX UNBRACE;
- XX if (check)
- XX (void) fprintf (outf,
- XX "%selse\n%s genbottom (\"%s\", %s);\n",
- XX indentstr (), indentstr (),
- XX "apply-to-all called with atomic argument", invar);
- XX (void) fprintf (outf, "%sdec_ref (%s);\n", indentstr (), invar);
- XX}
- XX
- XXstatic void codeconstr (tree, invar, outvar)
- XXfpexpr tree;
- XXchar * invar, * outvar;
- XX/* [a, b] : res := new (2); chase := res; chase->car := b (arg);
- XX chase = cdr (chase); chase->car := a (arg); */
- XX{
- XX int length;
- XX fpexpr subtree = tree;
- XX char chase [MAXIDLEN];
- XX char tempres [MAXIDLEN];
- XX
- XX for (length = 0; subtree != 0; length++)
- XX subtree = subtree->fpexprv.compconstr.compnext;
- XX newvar (chase);
- XX (void) sprintf (tempres, "%s->fp_entry", chase);
- XX if (length > 2)
- XX (void) fprintf (outf, "%s%s = %s = newvect (%d);\n", indentstr (),
- XX outvar, chase, length);
- XX else if (length == 2)
- XX (void) fprintf (outf, "%s%s = %s = newpair ();\n", indentstr (),
- XX outvar, chase);
- XX else
- XX (void) fprintf (outf, "%s%s = %s = newcell ();\n", indentstr (),
- XX outvar, chase);
- XX if (length > 1)
- XX (void) fprintf (outf, "%s%s->fp_ref += %d;\n", indentstr (), invar,
- XX length - 1);
- XX while (tree != 0)
- XX {
- XX codeexpr (tree->fpexprv.compconstr.compexpr, invar, tempres);
- XX tree = tree->fpexprv.compconstr.compnext;
- XX if (tree != 0)
- XX (void) fprintf (outf, "%s%s = %s->fp_header.fp_next;\n",
- XX indentstr (), chase, chase);
- XX }
- XX}
- XX
- XXstatic void codemulti (tree, invar, outvar)
- XXfpexpr tree;
- XXchar * invar, * outvar;
- XX{
- XX/* multi f: r1 := arg; res := newconst (); res->val := initval;
- XX while (r1 != 0) res := op (res, car (r1)); r1 := cdr (r1); */
- XX char var1 [MAXIDLEN];
- XX int optype; /* 0 for +, 1 for *, 2 for and, 3 for or */
- XX int isand;
- XX int isplus;
- XX char opchar; /* + for +, * for * */
- XX
- XX newvar (var1);
- XX if (strcmp (tree->fpexprv.aains->fpexprv.funcall, "plus") == 0)
- XX optype = 0;
- XX else if (strcmp (tree->fpexprv.aains->fpexprv.funcall, "times") == 0)
- XX optype = 1;
- XX else if (strcmp (tree->fpexprv.aains->fpexprv.funcall, "and") == 0)
- XX optype = 2;
- XX else if (strcmp (tree->fpexprv.aains->fpexprv.funcall, "or") == 0)
- XX optype = 3;
- XX else
- XX yyerror ("compiler error 20");
- XX if (check)
- XX {
- XX (void) fprintf (outf, "%sif (%s->fp_type != VECTOR)\n",
- XX indentstr (), invar);
- XX indent (1);
- XX (void) fprintf (outf,
- XX"%sgenbottom (\"error in insert: argument not a vector\", %s);\n",
- XX indentstr (), invar);
- XX indent (0);
- XX }
- XX/* multi f: r1 := arg; */
- XX (void) fprintf (outf, "%s%s = %s;\n", indentstr (), var1, invar);
- XX if (optype > 1)
- XX {
- XX isand = (optype == 2);
- XX/* while ((r1 != 0) && (car (r1) != true[false])) r1 := cdr (r1); */
- XX (void) fprintf (outf, "%swhile (%s && ", indentstr (), var1);
- XX if (isand)
- XX if (check)
- XX (void) fprintf (outf, "(%s->fp_entry->fp_type == TRUEOBJ))\n", var1);
- XX else
- XX (void) fprintf (outf, "%s->fp_entry->fp_type)\n", var1);
- XX else
- XX (void) fprintf (outf, "(%s->fp_entry->fp_type == FALSEOBJ))\n", var1);
- XX indent (1);
- XX (void) fprintf (outf, "%s%s = %s->fp_header.fp_next;\n", indentstr (),
- XX var1, var1);
- XX indent (0);
- XX/* if (r1 == 0) res := default else res := other */
- XX (void) fprintf (outf, "%sif (%s)\n", indentstr (), var1);
- XX indent (1);
- XX if (check)
- XX {
- XX (void) fprintf (outf, "%sif (%s->fp_entry->fp_type != %sOBJ)\n",
- XX indentstr (), var1, (isand ? "FALSE" : "TRUE"));
- XX indent (1);
- XX (void) fprintf (outf,
- XX"%sgenbottom (\"error in insert %s: argument not a boolean vector\", %s);\n",
- XX indentstr (), (isand ? "and" : "or"), invar);
- XX indent (0);
- XX (void) fprintf (outf, "%selse\n", indentstr ());
- XX indent (1);
- XX }
- XX (void) fprintf (outf, "%s%s = & %cobj;\n", indentstr (), outvar,
- XX (isand ? 'f' : 't'));
- XX if (check)
- XX indent (0);
- XX indent (0);
- XX (void) fprintf (outf, "%selse\n", indentstr ());
- XX indent (1);
- XX (void) fprintf (outf, "%s%s = & %cobj;\n", indentstr (), outvar,
- XX (isand ? 't' : 'f'));
- XX indent (0);
- XX }
- XX else /* numeric */
- XX {
- XX isplus = (optype == 0);
- XX opchar = isplus ? '+' : '*';
- XX/* multi f: r1 := arg; res := newconst (INT); res->val := 0|1; */
- XX (void) fprintf (outf, "%s%s = newconst (INTCONST);\n", indentstr (),
- XX outvar);
- XX (void) fprintf (outf, "%sif (%s->fp_entry->fp_type == INTCONST)\n",
- XX indentstr (), var1);
- XX BRACE;
- XX (void) fprintf (outf, "%s%s->fp_header.fp_int = ", indentstr (), outvar);
- XX (void) fprintf (outf, "%s->fp_entry->fp_header.fp_int;\n", var1);
- XX/* while (d0 && (d0->car->type == int)) res += d0->car->val; d0 = cdr (d0); */
- XX (void) fprintf (outf, "%swhile ((%s = %s->fp_header.fp_next) && ",
- XX indentstr (), var1, var1);
- XX (void) fprintf (outf, "(%s->fp_entry->fp_type == INTCONST))\n", var1);
- XX if (check) /* need to check for arithmetic overflow */
- XX {
- XX BRACE;
- XX if (isplus)
- XX {
- XX (void) fprintf (outf, "%sif (((%s->fp_header.fp_int < 0) == ",
- XX indentstr (), outvar);
- XX (void) fprintf (outf, "(%s->fp_entry->fp_header.fp_int < 0)) &&\n",
- XX var1);
- XX }
- XX else
- XX (void) fprintf (outf, "%sif ((%s->fp_header.fp_int != 0) &&\n",
- XX indentstr (), outvar);
- XX indent (1);
- XX indent (1);
- XX (void) fprintf (outf, "%s((%d %c abs (%s->fp_header.fp_int))",
- XX indentstr (), MAXINT, (isplus ? '-' : '/'), outvar);
- XX (void) fprintf (outf, " < abs (%s->fp_entry->fp_header.fp_int)))\n",
- XX var1);
- XX
- XX indent (0);
- XX (void) fprintf (outf, "%sgenbottom (\"overflow in insert %c\", %s);\n",
- XX indentstr (), opchar, invar);
- XX indent (0);
- XX }
- XX else
- XX indent (1);
- XX (void) fprintf (outf, "%s%s->fp_header.fp_int ", indentstr (), outvar);
- XX (void) fprintf (outf, "%c= %s->fp_entry->fp_header.fp_int;\n",
- XX opchar, var1);
- XX if (check)
- XX {
- XX UNBRACE;
- XX }
- XX else
- XX indent (0);
- XX UNBRACE;
- XX (void) fprintf (outf, "%selse\n", indentstr ());
- XX indent (1);
- XX (void) fprintf (outf, "%s%s->fp_header.fp_int = %c;\n", indentstr (),
- XX outvar, (isplus ? '0' : '1'));
- XX indent (0);
- XX (void) fprintf (outf, "%sif (%s)\n", indentstr (), var1);
- XX BRACE;
- XX (void) fprintf (outf, "%s%s->fp_header.fp_float =", indentstr (), outvar);
- XX (void) fprintf (outf, " %s->fp_header.fp_int;\n", outvar);
- XX (void) fprintf (outf, "%s%s->fp_type = FLOATCONST;\n", indentstr (),
- XX outvar);
- XX (void) fprintf (outf, "%swhile (%s)\n", indentstr (), var1);
- XX BRACE;
- XX (void) fprintf (outf, "%sif (%s->fp_entry->fp_type == FLOATCONST)\n",
- XX indentstr (), var1);
- XX indent (1);
- XX (void) fprintf (outf, "%s%s->fp_header.fp_float ", indentstr (), outvar);
- XX (void) fprintf (outf, "%c= %s->fp_entry->fp_header.fp_float;\n",
- XX opchar, var1);
- XX indent (0);
- XX if (check)
- XX {
- XX (void) fprintf (outf, "%selse if (%s->fp_entry->fp_type != INTCONST)\n",
- XX indentstr (), var1);
- XX indent (1);
- XX (void) fprintf (outf,
- XX"%sgenbottom (\"error in insert %c: argument not a numeric vector\", %s);\n",
- XX indentstr (), opchar, invar);
- XX indent (0);
- XX }
- XX (void) fprintf (outf, "%selse\n", indentstr ());
- XX indent (1);
- XX (void) fprintf (outf, "%s%s->fp_header.fp_float ", indentstr (), outvar);
- XX (void) fprintf (outf, "%c= %s->fp_entry->fp_header.fp_int;\n",
- XX opchar, var1);
- XX indent (0);
- XX (void) fprintf (outf, "%s%s = %s->fp_header.fp_next;\n", indentstr (),
- XX var1, var1);
- XX UNBRACE;
- XX UNBRACE;
- XX }
- XX (void) fprintf (outf, "%sdec_ref (%s);\n", indentstr (), invar);
- XX}
- XX
- XXstatic void codeinsert (tree, type, invar, outvar)
- XXfpexpr tree;
- XXint type; /* 0 for left, 1 for right, 2 for tree */
- XXchar * invar, * outvar;
- XX/* /a : r3 := 0; r2 := arg;
- XX while (r2 != 0) r1 := cons (car (r2), r3); r3 := r1; r2 := cdr (r2);
- XX res := car (r3); r1 := cdr (r3);
- XX while (r1 != 0) r2 := cons (car (r1), cons (res, nil));
- XX res := a (r2); r1 := cdr (r1);
- XX \a : res := car (arg); r1 := cdr (arg);
- XX while (r1 != 0) r2 := cons (res, cons (car (r1), nil));
- XX res := a (r2); r1 := cdr (r1);
- XX \/a: r1 = arg;
- XX while (r1->cdr != 0)
- XX r2 := r1; r1 := newcell (); r3 := r1;
- XX while (r2 != 0)
- XX if (r2->cdr == 0) r3->car = r2->car; r2 = 0;
- XX else
- XX r4 = newpair (); r4->car = r2->car; r2 = r2->cdr;
- XX r4->cdr->car = r2->car; r2 = r2->cdr; r3->car = a (r4);
- XX if (r2 != 0) r3->cdr = newcell (); r3 = r3->cdr;
- XX res = r1->car; */
- XX{
- XX char insertname [13];
- XX char var1 [MAXIDLEN],
- XX var2 [MAXIDLEN],
- XX var3 [MAXIDLEN],
- XX var4 [MAXIDLEN],
- XX var5 [MAXIDLEN], /* used for ref count in tree insert */
- XX argvar [MAXIDLEN], /* this is the argument to the fn in rins */
- XX varcar [MAXIDLEN];
- XX
- XX newvar (var1);
- XX newvar (var2);
- XX switch (type)
- XX {
- XX case 0: /* normal insert */
- XX (void) strcpy (insertname, "left insert");
- XX newvar (var3);
- XX (void) strcpy (argvar, var3);
- XX break;
- XX case 1: /* right insert */
- XX (void) strcpy (insertname, "right insert");
- XX (void) strcpy (argvar, invar);
- XX break;
- XX default: /* tree insert */
- XX (void) strcpy (insertname, "tree insert");
- XX newvar (var3);
- XX newvar (var4);
- XX newvar (var5);
- XX (void) sprintf (varcar, "%s->fp_entry", var3);
- XX break;
- XX }
- XX if (check)
- XX {
- XX (void) fprintf (outf, "%sif (%s->fp_type != VECTOR)\n",
- XX indentstr (), invar);
- XX (void) fprintf (outf, "%s genbottom (\"%s%s\", %s);\n", indentstr (),
- XX "non-vector passed to ", insertname, invar);
- XX }
- XX switch (type)
- XX {
- XX case 0: /* normal insert */
- XX/* r3 := 0; r2 := arg; */
- XX (void) fprintf (outf, "%s%s = 0;\n%s%s = %s;\n", indentstr (),
- XX var3, indentstr (), var2, invar);
- XX/* while (r2 != 0) r1 := cons (car (r2), r3); r3 := r1; r2 := cdr (r2); */
- XX/* i.e., reverse+copy arg into ra. Increment the refs of each element
- XX of arg, afterwards return arg, and the elements will stay. */
- XX (void) fprintf (outf, "%swhile (%s)\n", indentstr (), var2);
- XX BRACE;
- XX (void) fprintf (outf, "%s%s = newcell ();\n", indentstr (), var1);
- XX (void) fprintf (outf, "%s%s->fp_header.fp_next = %s;\n",
- XX indentstr (), var1, var3);
- XX (void) fprintf (outf, "%s%s->fp_entry = %s->fp_entry;\n%s%s = %s;\n",
- XX indentstr (), var1, var2, indentstr (), var3, var1);
- XX (void) fprintf (outf, "%sinc_ref (%s->fp_entry);\n", indentstr (), var3);
- XX (void) fprintf (outf, "%s%s = %s->fp_header.fp_next;\n",
- XX indentstr (), var2, var2);
- XX UNBRACE;
- XX (void) fprintf (outf, "%sdec_ref (%s);\n", indentstr (), invar);
- XX case 1: /* right insert */
- XX/* res := car (arg/r3); r1 := cdr (arg/r3); */
- XX (void) fprintf (outf, "%s%s = %s->fp_entry;\n", indentstr (),
- XX outvar, argvar);
- XX (void) fprintf (outf, "%s%s = %s->fp_header.fp_next;\n", indentstr (),
- XX var1, argvar);
- XX (void) fprintf (outf, "%sinc_ref (%s);\n", indentstr (), outvar);
- XX/* while (r1 != 0) r2 := cons (res, cons (car (r1), nil));
- XX r2 := cons (car (r1), cons (res, nil));
- XX res := a (r2); r1 := cdr (r1); */
- XX (void) fprintf (outf, "%swhile (%s)\n",
- XX indentstr (), var1);
- XX BRACE;
- XX (void) fprintf (outf, "%s%s = newpair ();\n", indentstr (), var2);
- XX if (type == 0)
- XX {
- XX (void) fprintf (outf, "%s%s->fp_header.fp_next->fp_entry = %s;\n",
- XX indentstr (), var2, outvar);
- XX (void) fprintf (outf, "%s%s->fp_entry = %s->fp_entry;\n",
- XX indentstr (), var2, var1);
- XX }
- XX else
- XX {
- XX (void) fprintf (outf, "%s%s->fp_entry = %s;\n",
- XX indentstr (), var2, outvar);
- XX (void) fprintf (outf,
- XX "%s%s->fp_header.fp_next->fp_entry = %s->fp_entry;\n",
- XX indentstr (), var2, var1);
- XX }
- XX (void) fprintf (outf, "%sinc_ref (%s->fp_entry);\n", indentstr (), var1);
- XX codeexpr (tree->fpexprv.aains, var2, outvar);
- XX (void) fprintf (outf, "%s%s = %s->fp_header.fp_next;\n",
- XX indentstr (), var1, var1);
- XX UNBRACE;
- XX (void) fprintf (outf, "%sdec_ref (%s);\n", indentstr (), argvar);
- XX break;
- XX default: /* tree insert */
- XX/* \/a: r1 = arg; */
- XX (void) fprintf (outf, "%s%s = %s;\n", indentstr (), var1, invar);
- XX/* while (r1->cdr != 0) */
- XX (void) fprintf (outf, "%swhile (%s->fp_header.fp_next%s)\n",
- XX indentstr (), var1, (check ? " != 0" : ""));
- XX BRACE;
- XX/* r2 = r1; r1 := r3 := newcell (); */
- XX (void) fprintf (outf, "%s%s = %s = %s;\n", indentstr (), var2,
- XX var5, var1);
- XX (void) fprintf (outf, "%s%s = %s = newcell ();\n", indentstr (),
- XX var1, var3);
- XX/* while (r2 != 0) */
- XX (void) fprintf (outf, "%swhile (%s%s)\n", indentstr (), var2,
- XX (check ? " != 0" : ""));
- XX indent (1);
- XX/* if (r2->cdr == 0) r3->car := r2->car; r2 := 0; */
- XX/* else */
- XX (void) fprintf (outf, "%sif (%s->fp_header.fp_next == 0)\n",
- XX indentstr (), var2);
- XX BRACE;
- XX (void) fprintf (outf, "%s%s->fp_entry = %s->fp_entry;\n",
- XX indentstr (), var3, var2);
- XX (void) fprintf (outf, "%sinc_ref (%s->fp_entry);\n", indentstr (), var2);
- XX (void) fprintf (outf, "%s%s = 0;\n", indentstr (), var2);
- XX UNBRACE;
- XX (void) fprintf (outf, "%selse\n", indentstr ());
- XX BRACE;
- XX/* r4 := newpair (); r4->car := r2->car; r2 := r2->cdr; */
- XX (void) fprintf (outf, "%s%s = newpair ();\n", indentstr (), var4);
- XX (void) fprintf (outf, "%s%s->fp_entry = %s->fp_entry;\n",
- XX indentstr (), var4, var2);
- XX (void) fprintf (outf, "%sinc_ref (%s->fp_entry);\n", indentstr (), var2);
- XX (void) fprintf (outf, "%s%s = %s->fp_header.fp_next;\n",
- XX indentstr (), var2, var2);
- XX/* r4->cdr->car := r2->car; r2 := r2->cdr; r3->car := a (r4); */
- XX (void) fprintf (outf,
- XX "%s%s->fp_header.fp_next->fp_entry = %s->fp_entry;\n",
- XX indentstr (), var4, var2);
- XX (void) fprintf (outf, "%sinc_ref (%s->fp_entry);\n", indentstr (), var2);
- XX (void) fprintf (outf, "%s%s = %s->fp_header.fp_next;\n",
- XX indentstr (), var2, var2);
- XX codeexpr (tree->fpexprv.aains, var4, varcar);
- XX/* if (r2 != 0) r3->cdr := newcell (); r3 := r3->cdr; */
- XX (void) fprintf (outf, "%sif (%s%s)\n", indentstr (), var2,
- XX (check ? " != 0" : ""));
- XX (void) fprintf (outf,
- XX "%s %s = %s->fp_header.fp_next = newcell ();\n",
- XX indentstr (), var3, var3);
- XX/* res := r1->car; */
- XX UNBRACE;
- XX indent (0);
- XX (void) fprintf (outf, "%sdec_ref (%s);\n", indentstr (), var5);
- XX UNBRACE;
- XX (void) fprintf (outf, "%s%s = %s->fp_entry;\n",
- XX indentstr (), outvar, var1);
- XX (void) fprintf (outf, "%sinc_ref (%s);\n", indentstr (), outvar);
- XX (void) fprintf (outf, "%sdec_ref (%s);\n", indentstr (), var1);
- XX break;
- XX }
- XX}
- XX
- XXstatic void codesel (tree, right, invar, outvar)
- XXfpexpr tree;
- XXint right;
- XXchar * invar, * outvar;
- XX/* n: i1 := n; r := d; while (--i1 != 0) r := cdr (r);
- XX r := car (r);
- XX nr: i1 := 0; r := d; while (r != 0) r := cdr (r); i1++;
- XX i1 := i1 - (n - 1); r := d; while (--i1 != 0) r := cdr (r);
- XX r := car (r); */
- XX/* notice that selectors of 1 are special cases, since they occurr
- XX * very frequently and can be optimized a bit */
- XX{
- XX char * ind;
- XX char * errmess = "argument too short for ";
- XX char checkstr [256];
- XX int selector;
- XX
- XX checkstr [0] = '\0';
- XX selector = tree->fpexprv.lrsel;
- XX ind = indentstr ();
- XX if (check)
- XX {
- XX (void) fprintf (outf, "%sif (%s->fp_type != VECTOR)\n", ind, invar);
- XX (void) fprintf (outf,
- XX "%s genbottom (\"selector %d%s applied to nonvector\", %s);\n",
- XX ind, selector, (right) ? "r" : "", invar);
- XX }
- XX if (selector == 1) /* first or last */
- XX {
- XX if (right) /* last: common special case */
- XX {
- XX (void) fprintf (outf, "%s%s = %s;\n", ind, outvar, invar); /* r := d; */
- XX (void) fprintf (outf, /* while (cdr (r) != 0) */
- XX "%swhile (%s->fp_header.fp_next)\n", ind, outvar);
- XX (void) fprintf (outf, /* r = cdr (r); */
- XX "%s %s = %s->fp_header.fp_next;\n", ind,
- XX outvar, outvar);
- XX (void) fprintf (outf, /* r = car (r); */
- XX "%s%s = %s->fp_entry;\n", ind, outvar, outvar);
- XX }
- XX else /* first: *very* common special case */
- XX/* r := car (d); */
- XX (void) fprintf (outf, "%s%s = %s->fp_entry;\n", ind, outvar, invar);
- XX }
- XX else /* selector != 1, general (i.e., non-special) case */
- XX {
- XX /* i1 := 1 or i1 := n */
- XX (void) fprintf (outf, "%ssel = %d;\n", ind, (right) ? 1 : selector);
- XX if (right)
- XX {
- XX (void) fprintf (outf, "%s%s = %s;\n", ind, outvar, invar); /* r := d; */
- XX (void) fprintf (outf, /* while ((r = cdr (r)) != 0) i1++; */
- XX "%swhile (%s = %s->fp_header.fp_next)\n%s sel++;\n",
- XX ind, outvar, outvar, ind);
- XX if (check)
- XX (void) fprintf (outf,
- XX "%sif (sel < %d)\n%s genbottom (\"%s%dr\", %s);\n",
- XX ind, selector, ind, errmess, selector, invar);
- XX /* i1 := i1 - (n - 1); */
- XX (void) fprintf (outf, "%ssel -= %d;\n", ind, selector - 1);
- XX }
- XX (void) fprintf (outf, "%s%s = %s;\n", ind, outvar, invar); /* r := d; */
- XX if (check && (! right))
- XX (void) sprintf (checkstr,
- XX"if (%s == 0)\n%s genbottom (\"%ssel %d\", %s);\n%s else\n%s ",
- XX outvar, ind, errmess, selector, invar, ind, ind);
- XX /* while (--i1 != 0) r := cdr (r); */
- XX (void) fprintf (outf,
- XX "%swhile (--sel)\n%s %s%s = %s->fp_header.fp_next;\n",
- XX ind, ind, checkstr, outvar, outvar);
- XX /* r := car (r); */
- XX if (check && (! right))
- XX (void) fprintf (outf,
- XX "%sif (%s == 0)\n%s genbottom (\"%ssel %d\", %s);\n",
- XX ind, outvar, ind, errmess, selector, invar);
- XX (void) fprintf (outf, "%s%s = %s->fp_entry;\n", ind, outvar, outvar);
- XX }
- XX (void) fprintf (outf, "%sinc_ref (%s);\n%sdec_ref (%s);\n",
- XX ind, outvar, ind, invar);
- XX}
- XX
- XXstatic void codefncall (tree, invar, outvar)
- XXfpexpr tree;
- XXchar * invar, * outvar;
- XX/* f: res := f (arg); */
- XX{
- XX if (strcmp (tree->fpexprv.funcall, "times") == 0)
- XX (void) fprintf (outf, "%s%s = %s (%s);\n",
- XX indentstr (), outvar, "fptimes", invar);
- XX else
- XX (void) fprintf (outf, "%s%s = %s (%s);\n",
- XX indentstr (), outvar, tree->fpexprv.funcall, invar);
- XX}
- XX
- XXstatic void codeconst (tree, invar, outvar)
- XXfpexpr tree;
- XXchar * invar, * outvar;
- XX{
- XX if (*invar != '\0')
- XX (void) fprintf (outf, "%sdec_ref (%s);\n", indentstr (), invar);
- XX (void) fprintf (outf, "%s%s = (fp_data) & (%s);\n%sinc_ref (%s);\n",
- XX indentstr (), outvar, tree->constvar, indentstr (), outvar);
- XX}
- SHAR_EOF
- if test 26310 -ne "`wc -c expr.c`"
- then
- echo shar: error transmitting expr.c '(should have been 26310 characters)'
- fi
- # End of shell archive
- exit 0
-
- --
- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
- Use a domain-based address or give alternate paths, or you may lose out.
-