home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume20
/
fpc
/
part03
< prev
next >
Wrap
Text File
|
1989-10-23
|
52KB
|
1,470 lines
Subject: v20i052: Portable compiler of the FP language, Part03/06
Newsgroups: comp.sources.unix
Sender: sources
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