From: Alex Smith Date: Mon, 23 Jun 2008 03:32:37 +0000 (-0400) Subject: feh2.c support for CREATEd operators X-Git-Tag: 0.29~225 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=8682ff06a9534ec437b4b879898f45ed49fad858;p=intercal.git feh2.c support for CREATEd operators --- diff --git a/src/feh2.c b/src/feh2.c index cea82f8..a06d3e9 100644 --- a/src/feh2.c +++ b/src/feh2.c @@ -1211,6 +1211,10 @@ static void revprexpr(node *np, FILE *fp, node *target) } /*@=temptrans@*/ /*@=kepttrans@*/ /*@=compdestroy@*/ /*@=branchstate@*/ +/*@observer@*/ static char* E000string; /* AIS */ + +static int prunknownstr(node*, FILE*); /* AIS */ + /* AIS: Destaticed */ /* Splint doesn't understand the concept of a function which might or might not free its argument. That's a pity, because its checking would come in @@ -1239,8 +1243,25 @@ void prexpr(node *np, FILE *fp, int freenode) (void) fprintf(fp, ")"); break; - case UNKNOWNOP: /* AIS //tk */ - (void) fprintf(fp, "0"); + case UNKNOWNOP: /* AIS */ + if(!useickec || !createsused) + { + /* CREATEd operators require -ea */ + (void) fprintf(fp, "(ick_lose(IE000, ick_lineno, \"%s\"),0)", + E000string); + break; + } + /* We need to do the same as UNKNOWN statements, but as an expression. + This is achieved with the helper function ick_dounop in ick_ec.c. */ + (void) fprintf(fp, "ick_dounop(\""); + prunknownstr(np->lval, fp); + if(freenode) free(np->lval); + (void) fprintf(fp, "\", "); + prexpr(np->rval->lval, fp, freenode); + (void) fprintf(fp, ", "); + prexpr(np->rval->rval, fp, freenode); + (void) fprintf(fp, ", lineno, \"%s\")", E000string); + if(freenode) free(np->rval); break; case BACKSLAT: /* AIS */ @@ -1556,11 +1577,11 @@ static int prunknownstr(node *np, FILE* fp) return i; case BADCHAR: if (np->constant > 256) - (void) fprintf(fp, "o%c%c", - (char)(np->constant / 256), - (char)(np->constant % 256)); + (void) fprintf(fp, "o%xx%x", + (int)(np->constant / 256), + (int)(np->constant % 256)); else - (void) fprintf(fp, "u%c", (char)np->constant); + (void) fprintf(fp, "u%x", (int)np->constant); return 2; case US_ID: (void) fputc((char)np->constant, fp); return 0; case US_ELEM: (void) fputc(';', fp); return 1; @@ -1810,9 +1831,19 @@ void emit(tuple *tn, FILE *fp) emitlineno = tn[1].ick_lineno; else emitlineno = iyylineno; - if(!pickcompile) /* AIS: PICs can't report errors, so don't bother with ick_lineno */ + if(!pickcompile) /* AIS: PICs can't report errors, + so don't bother with ick_lineno */ (void) fprintf(fp, " ick_lineno = %d;\n", emitlineno); + /* AIS: figure out which line we're on, so E000 can be done correctly */ + if (tn < tuples + ick_lineno - 1) + dim = tn[1].ick_lineno - tn->ick_lineno; + else + dim = iyylineno - tn->ick_lineno; + if (tn->sharedline) + ++dim; + E000string=nice_text(textlines + tn->ick_lineno, dim); + /* AIS: set weaving status if necessary */ if(tn->setweave) (void) fprintf(fp, " weaving = %d;\n", tn->setweave>0); diff --git a/src/ick_ec.c b/src/ick_ec.c index ea3ced0..b0b0372 100644 --- a/src/ick_ec.c +++ b/src/ick_ec.c @@ -50,6 +50,15 @@ static int ick_forgetamount = 0; unsigned long ick_global_goto; void* ick_global_createdata; +/* Do a CREATEd operator check and call. */ +/*@maynotreturn@*/ uint32_t ick_dounop(char* unopstr, + uint32_t arg1, + uint32_t arg2, + int emitlineno, + /*@observer@*/ char* errstr) +{ +} + /* Do a NEXT or goto. Gotos don't work with an empty NEXT stack, but that's trivial to correct by doing a NEXT at the start of the program. */ /*@maynotreturn@*/ void ick_dogoto(unsigned long linelabel, diff --git a/src/ick_ec.h b/src/ick_ec.h index 6ad6408..78e16b7 100644 --- a/src/ick_ec.h +++ b/src/ick_ec.h @@ -240,6 +240,7 @@ void ick_scheduleforget(unsigned short); /*@noreturn@*/ void ick_doresume(unsigned short, int); /*@maynotreturn@*/ void ick_checksuckpoint(unsigned long); void ick_runstartups(void); +/*@maynotreturn@*/ uint32_t ick_dounop(char*, uint32_t, uint32_t, int, char*); void ick_allecfuncs(void); /* in generated program */