rsalz@uunet.uu.net (Rich Salz) (10/24/89)
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.