static int nextlab
; /* next label allocated by alclab() */
* node construction routines
tfree
= (int *)tfree
+ 1;
syserr("out of tree space");
nodeptr
tree3(type
, a
, b
)
tfree
= (int *)tfree
+ 3;
syserr("out of tree space");
nodeptr
tree4(type
, a
, b
, c
)
tfree
= (int *)tfree
+ 4;
syserr("out of tree space");
nodeptr
tree5(type
, a
, b
, c
, d
)
tfree
= (int *)tfree
+ 5;
syserr("out of tree space");
nodeptr
tree6(type
, a
, b
, c
, d
, e
)
tfree
= (int *)tfree
+ 6;
syserr("out of tree space");
nodeptr
tree7(type
, a
, b
, c
, d
, e
, f
)
int type
, a
, b
, c
, d
, e
, f
;
tfree
= (int *)tfree
+ 7;
syserr("out of tree space");
static struct loopstk loopstk
[LOOPDEPTH
]; /* loop stack */
static struct loopstk
*loopsp
;
static struct casestk casestk
[CASEDEPTH
]; /* case stack */
static struct casestk
*casesp
;
static struct creatstk creatstk
[CREATDEPTH
]; /* create stack */
static struct creatstk
*creatsp
;
if (VAL0(TREE0(t
)) == AUGACT
)
traverse(TREE2(t
)); /* evaluate result expression */
if (VAL0(TREE0(t
)) == AUGACT
)
traverse(TREE1(t
)); /* evaluate activate expression */
if (VAL0(TREE0(t
)) == AUGACT
)
traverse(TREE0(t
)); /* evaluate first alternative */
emit("esusp"); /* and suspend with its result */
traverse(TREE1(t
)); /* evaluate second alternative */
emitl("mark", 0); /* fail if expr fails first time */
traverse(TREE0(t
)); /* evaluate first alternative */
emitl("chfail", lab
); /* change to loop on failure */
emit("esusp"); /* suspend result */
if (loopsp
->breaklab
<= 0)
lerr(LINE(t
), "invalid context for break");
emitn("unmark", loopsp
->markcount
);
emitl("goto", loopsp
->breaklab
);
traverse(TREE0(t
)); /* evaluate control expression */
traverse(TREE1(t
)); /* do rest of case (CLIST) */
if (casesp
->deftree
!= NULL
) { /* evaluate default clause */
traverse(casesp
->deftree
);
emitlab(lab
); /* end label */
if (TYPE(TREE0(t
)) == N_RES
&& /* default clause */
VAL0(TREE0(t
)) == DEFAULT
) {
if (casesp
->deftree
!= NULL
)
lerr(LINE(t
), "more than one default clause");
casesp
->deftree
= TREE1(t
);
traverse(TREE0(t
)); /* evaluate selector */
traverse(TREE1(t
)); /* evaluate expression */
emitl("goto", casesp
->endlab
); /* goto end label */
emitlab(lab
); /* label for next clause */
if (VAL0(TREE0(t
)) == AUGAND
)
if (VAL0(TREE0(t
)) != AUGAND
)
if (VAL0(TREE0(t
)) == AUGAND
)
creatsp
->nextlab
= loopsp
->nextlab
;
creatsp
->breaklab
= loopsp
->breaklab
;
loopsp
->nextlab
= 0; /* make break and next illegal */
emitl("goto", lab
+2); /* skip over code for coexpression */
emitlab(lab
); /* entry point */
emit("pop"); /* pop the result from activation */
traverse(TREE0(t
)); /* traverse code for coexpression */
emit("incres"); /* increment number of results */
emit("coret"); /* return to activator */
emit("efail"); /* drive coexpression */
emitlab(lab
+1); /* loop on exhaustion */
emit("cofail"); /* and fail each time */
emitl("create", lab
); /* create entry block */
loopsp
->nextlab
= creatsp
->nextlab
; /* legalize break and next */
loopsp
->breaklab
= creatsp
->breaklab
;
emits("field", STR0(TREE1(t
)));
if (TYPE(TREE2(t
)) == N_EMPTY
)
if (TYPE(TREE0(t
)) != N_EMPTY
)
emit("pushn1"); /* assume -1(e1,...,en) */
if (TYPE(TREE0(t
)) == N_EMPTY
)
switch (VAL0(TREE0(t
))) {
loopsp
->breaklab
= lab
+ 1;
if (TYPE(TREE2(t
)) != N_EMPTY
) { /* every e1 do e2 */
emitlab(loopsp
->nextlab
);
emitlab(loopsp
->breaklab
);
loopsp
->nextlab
= lab
+ 1;
loopsp
->breaklab
= lab
+ 2;
emitlab(loopsp
->nextlab
);
emitlab(loopsp
->breaklab
);
loopsp
->nextlab
= lab
+ 1;
loopsp
->breaklab
= lab
+ 2;
if (TYPE(TREE2(t
)) != N_EMPTY
) {
emitlab(loopsp
->nextlab
);
emitlab(loopsp
->breaklab
);
loopsp
->nextlab
= lab
+ 2;
loopsp
->breaklab
= lab
+ 3;
emitlab(loopsp
->nextlab
);
emitlab(loopsp
->breaklab
);
if (loopsp
< loopstk
|| loopsp
->nextlab
<= 0)
lerr(LINE(t
), "invalid context for next");
if (loopsp
->ltype
!= EVERY
&& loopsp
->markcount
> 1)
emitn("unmark", loopsp
->markcount
- 1);
emitl("goto", loopsp
->nextlab
);
fprintf(codefile
, "proc %s\n", STR0(TREE0(t
)));
if (TYPE(TREE1(t
)) != N_EMPTY
) {
if (TYPE(TREE2(t
)) != N_EMPTY
)
fprintf(stderr
, " %s (%d/%d)\n", STR0(TREE0(t
)),
(int *)tfree
- (int *)tree
, tsize
);
lerr(LINE(t
), "invalid context for return or fail");
if (VAL0(TREE0(t
)) != FAIL
) {
if (VAL0(TREE0(t
)) == SCANASGN
)
if (VAL0(TREE0(t
)) == SCANASGN
)
if (VAL0(TREE0(t
)) == SCANASGN
)
if (VAL0(TREE0(t
)) == PCOLON
|| VAL0(TREE0(t
)) == MCOLON
)
if (VAL0(TREE0(t
)) == PCOLON
)
else if (VAL0(TREE0(t
)) == MCOLON
)
lerr(LINE(t
), "invalid context for suspend");
syserr("traverse: undefined node type");
syserr("binop: undefined binary operator");
case NOTEQUIV
: /* unary ~ and three = operators */
case LEXNE
: /* unary ~ and two = operators */
case EQUIV
: /* three unary = operators */
case NUMNE
: /* unary ~ and = operators */
case UNION
: /* two unary + operators */
case DIFF
: /* two unary - operators */
case LEXEQ
: /* two unary = operators */
case INTER
: /* two unary * operators */
case DOT
: /* unary . operator */
case BACKSLASH
: /* unary \ operator */
case BANG
: /* unary ! operator */
case CARET
: /* unary ^ operator */
case PLUS
: /* unary + operator */
case TILDE
: /* unary ~ operator */
case MINUS
: /* unary - operator */
case NUMEQ
: /* unary = operator */
case STAR
: /* unary * operator */
case QMARK
: /* unary ? operator */
case SLASH
: /* unary / operator */
syserr("unopa: undefined unary operator");
case DOT
: /* unary . operator */
case BACKSLASH
: /* unary \ operator */
case BANG
: /* unary ! operator */
case CARET
: /* unary ^ operator */
case UNION
: /* two unary + operators */
case PLUS
: /* unary + operator */
case NOTEQUIV
: /* unary ~ and three = operators */
case LEXNE
: /* unary ~ and two = operators */
case NUMNE
: /* unary ~ and = operators */
case TILDE
: /* unary ~ operator (cset compl) */
case DIFF
: /* two unary - operators */
case MINUS
: /* unary - operator */
case EQUIV
: /* three unary = operators */
case LEXEQ
: /* two unary = operators */
case NUMEQ
: /* unary = operator */
case INTER
: /* two unary * operators */
case STAR
: /* unary * operator */
case QMARK
: /* unary ? operator */
case SLASH
: /* unary / operator */
syserr("unopb: undefined unary operator");
fprintf(codefile
, "lab L%d\n", l
);
fprintf(codefile
, "\t%s\n", s
);
fprintf(codefile
, "\t%s\tL%d\n", s
, a
);
fprintf(codefile
, "\t%s\t%d\n", s
, a
);
fprintf(codefile
, "\t%s\t%d,L%d\n", s
, a
, b
);
fprintf(codefile
, "\t%s\t%s\n", s
, a
);