home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
awk
/
awk320sr.zip
/
AWKGEN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-28
|
8KB
|
394 lines
/*
* Awk code generator
*
* Copyright (C) 1988, 1989, 1990, 1991 by Rob Duff
* All rights reserved
*/
#include <stdio.h>
#include <mem.h>
#include "awk.h"
#include "awklex.h"
short linenum = 0; /* line number for next opcode */
short lastptr = 0; /* index to previous opcode */
short codeptr = 0; /* index into code buffer */
short lastlabel = 0; /* index into jump target list */
short nextlabel = 1;
LABLE labels[MAXLABEL]; /* table to hold jump targets */
TRIX trix;
void putline(void);
void genline(void);
int
getlabel()
{
int label;
if (lastlabel >= MAXLABEL)
yyerror("label overflow");
label = lastlabel++;
labels[label].where = 0;
labels[label].label = nextlabel++;
#ifdef LDEBUG
print_label("get", label);
#endif
return(label);
}
void putlabel(int label)
{
#ifdef LDEBUG
print_label("put", label);
#endif
lastlabel--;
if (labels[label].where < 0)
yyerror("undefined label");
if (label != lastlabel)
yyerror("lost label");
}
void uselabel(int label, int value)
{
int i;
#ifdef LDEBUG
print_label("use", label);
print_label("for", value);
#endif
i = labels[label].where;
labels[label].where = labels[value].where;
labels[value].where = i;
}
void genlabel(int label)
{
int i, loc, tmp;
loc = -labels[label].where;
labels[label].where = codeptr + 1;
while (loc > 0) {
for (i = 0; i < sizeof(short); i++)
trix.sval[i] = code[loc+i];
tmp = trix.ival;
trix.ival = codeptr - (loc + sizeof(short));
for (i = 0; i < sizeof(short); i++)
code[loc+i] = trix.sval[i];
loc = tmp;
}
#ifdef LDEBUG
printf("set %d(%d)\n", labels[label].label, labels[label].where);
#endif
genline();
}
LINK*
genact(char *cp)
{
LINK *lp;
lp = yyalloc(sizeof(LINK));
lp->cnext = NULL;
lp->ccode = cp;
return lp;
}
RULE*
genrule(char *start, char *stop)
{
RULE *rp;
rp = yyalloc(sizeof(RULE));
rp->start = start;
rp->stop = stop;
rp->seen = 0;
rp->flag = 0;
rp->action = NULL;
rp->next = NULL;
return rp;
}
char*
gencode()
{
char *cp;
#ifdef CDEBUG
print_code(code);
#endif
cp = yyalloc(codeptr);
memcpy(cp, code, codeptr);
code[0] = C_END;
codeptr = 0;
lastptr = 0;
lastlabel = 0;
stackptr = stacktop;
return cp;
}
void putline()
{
int i;
if (awkline > 0 && linenum > 0) {
code[codeptr++] = C_LINE;
trix.sptr = yyname;
for (i = 0; i < sizeof(char*); i++)
code[codeptr++] = trix.sval[i];
trix.ival = linenum;
for (i = 0; i < sizeof(short); i++)
code[codeptr++] = trix.sval[i];
linenum = 0;
}
}
void genline()
{
linenum = yyline;
}
void gendrop(void)
{
int op;
op = code[lastptr];
if (op == C__PRE || op == C__POST || op == C__STORE || op == C__COPY)
code[lastptr] = op + 1;
else {
putline();
lastptr = codeptr;
code[codeptr++] = C_DROP;
}
}
void genstore(int arg)
{
int op;
putline();
if (code[lastptr] == C_LOAD) {
codeptr = lastptr;
op = C__COPY;
}
else if (code[lastptr] == C_FETCH) {
code[lastptr] = C_ADDR;
op = C__COPY;
}
else if (code[lastptr] == C_PLUCK) {
code[lastptr] = C_FIELD;
op = C__COPY;
}
else
op = C__STORE;
lastptr = codeptr;
code[codeptr++] = op;
code[codeptr++] = arg;
}
void genbyte(int op)
{
putline();
lastptr = codeptr;
code[codeptr++] = op;
}
void gentwo(int op, int arg)
{
putline();
lastptr = codeptr;
code[codeptr++] = op;
code[codeptr++] = arg;
}
void gendcon(double dcon)
{
int i;
putline();
lastptr = codeptr;
code[codeptr++] = C_DCON;
trix.dval = dcon;
for (i = 0; i < sizeof(double); i++)
code[codeptr++] = trix.sval[i];
}
void genicon(int icon)
{
int i;
putline();
lastptr = codeptr;
if (icon <= 255) {
code[codeptr++] = C_CCON;
trix.cval = (char)icon;
for (i = 0; i < sizeof(char); i++)
code[codeptr++] = trix.sval[i];
}
else {
code[codeptr++] = C_ICON;
trix.ival = (int)icon;
for (i = 0; i < sizeof(short); i++)
code[codeptr++] = trix.sval[i];
}
}
void genlcon(long lcon)
{
int i;
putline();
lastptr = codeptr;
code[codeptr++] = C_LCON;
trix.lval = (long)lcon;
for (i = 0; i < sizeof(long); i++)
code[codeptr++] = trix.sval[i];
}
void genscon(char *scon)
{
int i;
putline();
lastptr = codeptr;
code[codeptr++] = C_SCON;
trix.sptr = scon;
for (i = 0; i < sizeof(char*); i++)
code[codeptr++] = trix.sval[i];
}
void genrcon(char *rcon)
{
int i;
putline();
lastptr = codeptr;
code[codeptr++] = C_RCON;
trix.vptr = rcon;
for (i = 0; i < sizeof(void*); i++)
code[codeptr++] = trix.sval[i];
}
void genfield(double field)
{
int i;
if ( field < 0 || field >= MAXFIELD )
yyerror("Field number out of range");
putline();
lastptr = codeptr;
code[codeptr++] = C_FIELD;
trix.vptr = fieldtab + (int)field;
for (i = 0; i < sizeof(void*); i++)
code[codeptr++] = trix.sval[i];
}
void genfcon(int fcon)
{
int i;
putline();
lastptr = codeptr;
code[codeptr++] = C_FCON;
trix.vptr = files + fcon;
for (i = 0; i < sizeof(void*); i++)
code[codeptr++] = trix.sval[i];
}
void genaddr(IDENT *var)
{
int i;
LIST *lp;
putline();
lastptr = codeptr;
i = 0;
for (lp = yydisplay; lp != NULL; lp = lp->lnext) {
if (lp->litem == var) {
code[codeptr++] = C_AUTO;
trix.ival = i;
for (i = 0; i < sizeof(int); i++)
code[codeptr++] = trix.sval[i];
return;
}
i++;
}
if (var->vitem == NULL) {
var->vitem = nextvar++;
code[codeptr++] = C_ADDR;
}
else if ((ITEM*)(var->vitem) - vartab < builtin)
code[codeptr++] = C_BUILT;
else
code[codeptr++] = C_ADDR;
trix.vptr = var->vitem;
for (i = 0; i < sizeof(void*); i++)
code[codeptr++] = trix.sval[i];
}
void gencall(int func, int args)
{
putline();
lastptr = codeptr;
code[codeptr++] = C_CALL;
code[codeptr++] = func;
code[codeptr++] = args;
}
void genuser(IDENT *func, int args)
{
int i;
putline();
lastptr = codeptr;
code[codeptr++] = C_USER;
trix.vptr = func;
for (i = 0; i < sizeof(void*); i++)
code[codeptr++] = trix.sval[i];
code[codeptr++] = args;
}
void genjump(int kind, int label)
{
int i, loc;
putline();
lastptr = codeptr;
code[codeptr++] = kind;
loc = labels[label].where;
if (loc <= 0) {
trix.ival = -loc;
labels[label].where = -codeptr;
}
else
trix.ival = loc - (codeptr + sizeof(short) + 1);
for (i = 0; i < sizeof(short); i++)
code[codeptr++] = trix.sval[i];
}
int
lastcode()
{
return code[lastptr];
}
double
lastdcon()
{
codeptr = lastptr;
return *(double*)(&code[lastptr+1]);
}
void
lastvoid()
{
codeptr = lastptr;
}
void
lastop(int op)
{
code[lastptr] = op;
}