1
0
mirror of https://github.com/PDP-10/PCC20.git synced 2026-01-13 15:17:51 +00:00
2018-10-25 11:25:56 +02:00

308 lines
4.9 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# include "cc.h"
# include "c2.h"
/*
C COMPILER
Phase P: Parser
Section 2: Statement Processing and Action Routine Support
Copyright (c) 1977 by Alan Snyder
*/
/**********************************************************************
VARIABLES
**********************************************************************/
int ciln 0; /* current internal label number */
extern int line, cblock;
/**********************************************************************
GROUP STACK
**********************************************************************/
# define gentry struct _gentry
struct _gentry {int gtype, gchain, giln;};
# define GNULL 0
# define GSWITCH 1
# define GFOR 2
# define GDO 3
# define GWHILE 4
gentry gstack[GSSIZE];
gentry *cgsp, *egsp;
gpush (gtype, niln)
{if (++cgsp >= egsp) errx (4002);
cgsp->gtype = gtype;
cgsp->giln = ciln;
cgsp->gchain = 0;
ciln =+ niln;
}
gentry *findswitch ()
{gentry *gp;
for (gp=cgsp; gp->gtype>GSWITCH; --gp);
if (gp>gstack) return (gp);
return (NULL);
}
/**********************************************************************
STACK ROUTINES FOR ACTIONS
**********************************************************************/
int stack[pssize];
int *stakp stack;
int *estkp;
int *push (i)
{if (++stakp >= estkp) errx (4007);
*stakp = i;
return (stakp);
}
pop ()
{int i;
i = *stakp--;
if (stakp < stack) errx (6002);
return (i);
}
int *setsp (nsp) int *nsp; /* set stack pointer */
{if (nsp < stack || nsp >= estkp) errx (6010);
return (stakp = nsp);
}
int *top () /* get stack pointer */
{return (stakp);}
int *get_top (nsp) int *nsp; /* get list from top of stack */
{int *ot;
ot = top ();
setsp (nsp-1);
return (ot);
}
/**********************************************************************
ACTION ROUTINES
**********************************************************************/
ainit ()
{ciln = 0;
cgsp = gstack;
egsp = cgsp + GSSIZE;
cgsp->gtype = GNULL;
estkp = stack + pssize;
dinit ();
}
astmtl (stmtl, stmt)
{return (node (n_stmtl, stmtl, stmt));}
aexprstmt (expr)
{return (node (n_exprs, line, expr));}
aif (test, if_part, else_part)
{return (node (n_if, line, test, if_part, else_part));}
awhile (expr, stmt)
{int l;
l = (cgsp--)->giln;
return (astmtl (
ailabel (l+1,
aif (expr, astmtl (stmt, abranch (l+1)), 0)),
ailabel (l, 0)));
}
apshw () {gpush (GWHILE, 2);}
ado (stmt, expr)
{int l;
l = (cgsp--)->giln;
return (astmtl (
ailabel (l+2, stmt),
astmtl (
ailabel (l+1, aif (expr, abranch (l+2), 0)),
ailabel (l, 0))));
}
apshd () {gpush (GDO, 3);}
afor (e1, e2, e3, stmt)
{int l, tnode;
l = (cgsp--)->giln;
tnode = astmtl (
stmt,
astmtl (
ailabel (l+1, (e3 ? aexprstmt (e3) : NULL)),
abranch (l+2)));
if (e2) tnode = aif (e2, tnode, 0);
tnode = astmtl (
ailabel (l+2, tnode),
ailabel (l, 0));
if (e1) tnode = astmtl (aexprstmt (e1), tnode);
return (tnode);
}
apshf () {gpush (GFOR, 3);}
aswitch (expr, stmt)
{int l, c;
c = cgsp->gchain;
l = (cgsp--)->giln;
return (astmtl (
node (n_switch, line, expr, stmt, c),
ailabel (l, 0)));
}
apshs () {gpush (GSWITCH, 1);}
abreak ()
{if (cgsp==gstack)
{error (2002, line);
return (NULL);
}
return (abranch (cgsp->giln));
}
acontinue ()
{gentry *gp;
for (gp = cgsp; gp>gstack; --gp)
if (gp->gtype > GSWITCH) /* not a switch */
return (abranch (gp->giln+1));
error (2003, line);
return (NULL);
}
areturn (expr)
{return (node (n_return, line, expr));}
agoto (expr)
{return (node (n_goto, line, astar (expr)));}
alabel (idn, stmt)
{dentry *dp;
dp = define (cblock, idn, c_label, TINT, UNDEF);
if (dp->offset == UNDEF) dp->offset = ciln++;
return (ailabel (dp->offset, stmt));
}
ailabel (iln, stmt)
{return (node (n_label, iln, stmt));}
abranch (iln)
{return (node (n_branch, iln));}
acase (c, stmt)
{gentry *gp;
if (gp = findswitch ())
{gp->gchain = node (n_case, gp->gchain, c, ciln);
return (ailabel (ciln++, stmt));
}
error (2004, line);
return (stmt);
}
adefault (stmt)
{gentry *gp;
if (gp = findswitch ())
{gp->gchain = node (n_def, gp->gchain, ciln);
return (ailabel (ciln++, stmt));
}
error (2005, line);
return (stmt);
}
anull ()
{return (NULL);}
aelist (elist, expr)
{return (node (n_elist, elist, expr));}
asubscript (e1, e2)
{return (astar (node (n_plus, e1, e2)));}
acall (func, args)
{return (node (n_call, func, args));}
adot (expr, idn)
{return (node (n_dot, expr, idn));}
aptr (expr, idn)
{return (adot (astar (expr), idn));}
astar (expr)
{return (node (n_star, expr));}
aidn (dp)
dentry *dp;
{int class;
switch (class = dp->class) {
case c_ulabel: class=c_label; break;
case c_extern: class=c_extdef; break;
case c_uauto: class=c_auto; break;
case c_typedef: errx (2042, TIDN, dp->name); class=c_auto; break;
}
return (node (n_idn, tp2o (dp->dtype), class, dp->offset));
}
aentry (idn, stmt)
{return (stmt);} /* not implemented */