return cs;
}
+/* mkBlocks:
+ */
+static int mkBlock(comp_block* bp, Expr_t * prog, char *src, parse_block *inp, Sfio_t* tmps, int i)
+{
+ int rv = 0;
+
+ codePhase = 1;
+ if (inp->begg_stmt) {
+ sfprintf(tmps, "_begin_g_%d", i);
+ symbols[0].type = T_graph;
+ tchk[V_this][1] = Y(G);
+ bp->begg_stmt = compile(prog, src, inp->begg_stmt,
+ inp->l_beging, sfstruse(tmps), 0, VOIDTYPE);
+ if (getErrorErrors())
+ goto finishBlk;
+ rv |= BEGG;
+ }
+
+ codePhase = 2;
+ if (inp->node_stmts) {
+ symbols[0].type = T_node;
+ tchk[V_this][1] = Y(V);
+ bp->n_nstmts = inp->n_nstmts;
+ bp->node_stmts = mkStmts(prog, src, inp->node_stmts,
+ inp->n_nstmts, "_nd", tmps);
+ if (getErrorErrors())
+ goto finishBlk;
+ bp->walks |= WALKSG;
+ }
+
+ codePhase = 3;
+ if (inp->edge_stmts) {
+ symbols[0].type = T_edge;
+ tchk[V_this][1] = Y(E);
+ bp->n_estmts = inp->n_estmts;
+ bp->edge_stmts = mkStmts(prog, src, inp->edge_stmts,
+ inp->n_estmts, "_eg", tmps);
+ if (getErrorErrors())
+ goto finishBlk;
+ bp->walks |= WALKSG;
+ }
+
+ finishBlk:
+ if (getErrorErrors()) {
+ free (bp->node_stmts);
+ free (bp->edge_stmts);
+ bp->node_stmts = 0;
+ bp->edge_stmts = 0;
+ }
+
+ return (rv | bp->walks);
+}
+
/* doFlags:
* Convert command line flags to actions in END_G.
*/
comp_prog *p;
Sfio_t *tmps = state->tmp;
char *endg_sfx = 0;
+ int i, useflags = 0;
/* Make sure we have enough bits for types */
assert(BITS_PER_BYTE * sizeof(tctype) >= (1 << TBITS));
goto finish;
}
- codePhase = 1;
- if (inp->begg_stmt) {
- symbols[0].type = T_graph;
- tchk[V_this][1] = Y(G);
- p->begg_stmt = compile(p->prog, inp->source, inp->begg_stmt,
- inp->l_beging, "_begin_g", 0, VOIDTYPE);
- if (getErrorErrors())
- goto finish;
- }
+ if (inp->blocks) {
+ comp_block* bp;
+ parse_block* ibp = inp->blocks;
- codePhase = 2;
- if (inp->node_stmts) {
- symbols[0].type = T_node;
- tchk[V_this][1] = Y(V);
- p->n_nstmts = inp->n_nstmts;
- p->node_stmts = mkStmts(p->prog, inp->source, inp->node_stmts,
- inp->n_nstmts, "_nd", tmps);
- if (getErrorErrors())
- goto finish;
- }
+ p->blocks = bp = newof(0, comp_block, inp->n_blocks, 0);
- codePhase = 3;
- if (inp->edge_stmts) {
- symbols[0].type = T_edge;
- tchk[V_this][1] = Y(E);
- p->n_estmts = inp->n_estmts;
- p->edge_stmts = mkStmts(p->prog, inp->source, inp->edge_stmts,
- inp->n_estmts, "_eg", tmps);
- if (getErrorErrors())
- goto finish;
+ for (i = 0; i < inp->n_blocks; bp++, i++) {
+ useflags |= mkBlock (bp, p->prog, inp->source, ibp, tmps, i);
+ if (getErrorErrors())
+ goto finish;
+ else {
+ ibp = ibp->next;
+ p->n_blocks++;
+ }
+ }
}
+ p->flags = useflags;
codePhase = 4;
if (inp->endg_stmt || endg_sfx) {
}
setErrorLine (0); /* execution errors have no line numbers */
+ if (p->end_stmt)
+ p->flags |= ENDG;
+
finish:
if (getErrorErrors()) {
freeCompileProg (p);
void
freeCompileProg (comp_prog *p)
{
+ comp_block* bp;
+ int i;
+
if (!p) return;
exclose (p->prog, 1);
- free (p->node_stmts);
- free (p->edge_stmts);
+ for (i = 0; i < p->n_blocks; i++) {
+ bp = p->blocks + i;
+ free (bp->node_stmts);
+ free (bp->edge_stmts);
+ }
+ free (p->blocks);
free (p);
}
/* walksGraph;
- * Returns true if program actually has node or edge statements.
+ * Returns true if block actually has node or edge statements.
*/
-int walksGraph(comp_prog * p)
+int walksGraph(comp_block * p)
{
- return (p->n_nstmts || p->n_estmts);
+ return (p->walks);
}
/* usesGraph;
*/
int usesGraph(comp_prog * p)
{
- return (walksGraph(p) || p->begg_stmt || p->endg_stmt);
+ return (p->flags);
}
void ptchk(void)
return opts;
}
-static void evalEdge(Gpr_t * state, comp_prog * xprog, Agedge_t * e)
+static void evalEdge(Gpr_t * state, Expr_t* prog, comp_block * xprog, Agedge_t * e)
{
int i;
case_stmt *cs;
for (i = 0; i < xprog->n_estmts; i++) {
cs = xprog->edge_stmts + i;
if (cs->guard)
- okay = (exeval(xprog->prog, cs->guard, state)).integer;
+ okay = (exeval(prog, cs->guard, state)).integer;
else
okay = 1;
if (okay) {
if (cs->action)
- exeval(xprog->prog, cs->action, state);
+ exeval(prog, cs->action, state);
else
agsubedge(state->target, e, TRUE);
}
}
}
-static void evalNode(Gpr_t * state, comp_prog * xprog, Agnode_t * n)
+static void evalNode(Gpr_t * state, Expr_t* prog, comp_block * xprog, Agnode_t * n)
{
int i;
case_stmt *cs;
for (i = 0; i < xprog->n_nstmts; i++) {
cs = xprog->node_stmts + i;
if (cs->guard)
- okay = (exeval(xprog->prog, cs->guard, state)).integer;
+ okay = (exeval(prog, cs->guard, state)).integer;
else
okay = 1;
if (okay) {
if (cs->action)
- exeval(xprog->prog, cs->action, state);
+ exeval(prog, cs->action, state);
else
agsubnode(state->target, n, TRUE);
}
static trav_fns FWDfns = { agfstout, (nxttedgefn_t) agnxtout, 0, 0 };
static trav_fns REVfns = { agfstin, (nxttedgefn_t) agnxtin, 0, 0 };
-static void travBFS(Gpr_t * state, comp_prog * xprog)
+static void travBFS(Gpr_t * state, Expr_t* prog, comp_block * xprog)
{
nodestream nodes;
queue *q;
nd = nData(n);
MARK(nd);
POP(nd);
- evalNode(state, xprog, n);
+ evalNode(state, prog, xprog, n);
for (cure = agfstedge(g, n); cure;
cure = agnxtedge(g, cure, n)) {
nd = nData(cure->node);
if (MARKED(nd))
continue;
- evalEdge(state, xprog, cure);
+ evalEdge(state, prog, xprog, cure);
if (!ONSTACK(nd)) {
push(q, cure->node);
PUSH(nd);
freeQ(q);
}
-static void travDFS(Gpr_t * state, comp_prog * xprog, trav_fns * fns)
+static void travDFS(Gpr_t * state, Expr_t* prog, comp_block * xprog, trav_fns * fns)
{
Agnode_t *n;
queue *stk;
MARK(nd);
PUSH(nd);
if (fns->visit & PRE_VISIT)
- evalNode(state, xprog, n);
+ evalNode(state, prog, xprog, n);
more = 1;
while (more) {
if (cure)
*/
if (fns->undirected) {
if (ONSTACK(nd))
- evalEdge(state, xprog, cure);
+ evalEdge(state, prog, xprog, cure);
} else
- evalEdge(state, xprog, cure);
+ evalEdge(state, prog, xprog, cure);
} else {
- evalEdge(state, xprog, cure);
+ evalEdge(state, prog, xprog, cure);
push(stk, entry);
entry = cure;
curn = cure->node;
cure = 0;
if (fns->visit & PRE_VISIT)
- evalNode(state, xprog, curn);
+ evalNode(state, prog, xprog, curn);
MARK(nd);
PUSH(nd);
}
} else {
if (fns->visit & POST_VISIT)
- evalNode(state, xprog, curn);
+ evalNode(state, prog, xprog, curn);
nd = nData(curn);
POP(nd);
cure = entry;
freeQ(stk);
}
-static void travNodes(Gpr_t * state, comp_prog * xprog)
+static void travNodes(Gpr_t * state, Expr_t* prog, comp_block * xprog)
{
Agnode_t *n;
Agraph_t *g = state->curgraph;
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- evalNode(state, xprog, n);
+ evalNode(state, prog, xprog, n);
}
}
-static void travEdges(Gpr_t * state, comp_prog * xprog)
+static void travEdges(Gpr_t * state, Expr_t* prog, comp_block * xprog)
{
Agnode_t *n;
Agedge_t *e;
Agraph_t *g = state->curgraph;
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
- evalEdge(state, xprog, e);
+ evalEdge(state, prog, xprog, e);
}
}
}
-static void travFlat(Gpr_t * state, comp_prog * xprog)
+static void travFlat(Gpr_t * state, Expr_t* prog, comp_block * xprog)
{
Agnode_t *n;
Agedge_t *e;
Agraph_t *g = state->curgraph;
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- evalNode(state, xprog, n);
+ evalNode(state, prog, xprog, n);
if (xprog->n_estmts > 0) {
for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
- evalEdge(state, xprog, e);
+ evalEdge(state, prog, xprog, e);
}
}
}
/* traverse:
*/
-static void traverse(Gpr_t * state, comp_prog * xprog)
+static void traverse(Gpr_t * state, Expr_t* prog, comp_block * bp)
{
char *target;
- if (state->name_used) {
- sfprintf(state->tmp, "%s%d", state->tgtname, state->name_used);
- target = sfstruse(state->tmp);
- } else
- target = state->tgtname;
- state->name_used++;
- state->target = openSubg(state->curgraph, target);
+ if (!state->target) {
+ if (state->name_used) {
+ sfprintf(state->tmp, "%s%d", state->tgtname, state->name_used);
+ target = sfstruse(state->tmp);
+ } else
+ target = state->tgtname;
+ state->name_used++;
+ state->target = openSubg(state->curgraph, target);
+ }
if (!state->outgraph)
state->outgraph = state->target;
switch (state->tvt) {
case TV_flat:
- travFlat(state, xprog);
+ travFlat(state, prog, bp);
break;
case TV_bfs:
- travBFS(state, xprog);
+ travBFS(state, prog, bp);
break;
case TV_dfs:
DFSfns.visit = PRE_VISIT;
- travDFS(state, xprog, &DFSfns);
+ travDFS(state, prog, bp, &DFSfns);
break;
case TV_fwd:
FWDfns.visit = PRE_VISIT;
- travDFS(state, xprog, &FWDfns);
+ travDFS(state, prog, bp, &FWDfns);
break;
case TV_rev:
REVfns.visit = PRE_VISIT;
- travDFS(state, xprog, &REVfns);
+ travDFS(state, prog, bp, &REVfns);
break;
case TV_postdfs:
DFSfns.visit = POST_VISIT;
- travDFS(state, xprog, &DFSfns);
+ travDFS(state, prog, bp, &DFSfns);
break;
case TV_postfwd:
FWDfns.visit = POST_VISIT;
- travDFS(state, xprog, &FWDfns);
+ travDFS(state, prog, bp, &FWDfns);
break;
case TV_postrev:
REVfns.visit = POST_VISIT | PRE_VISIT;
- travDFS(state, xprog, &REVfns);
+ travDFS(state, prog, bp, &REVfns);
break;
case TV_prepostdfs:
DFSfns.visit = POST_VISIT | PRE_VISIT;
- travDFS(state, xprog, &DFSfns);
+ travDFS(state, prog, bp, &DFSfns);
break;
case TV_prepostfwd:
FWDfns.visit = POST_VISIT | PRE_VISIT;
- travDFS(state, xprog, &FWDfns);
+ travDFS(state, prog, bp, &FWDfns);
break;
case TV_prepostrev:
REVfns.visit = POST_VISIT;
- travDFS(state, xprog, &REVfns);
+ travDFS(state, prog, bp, &REVfns);
break;
case TV_ne:
- travNodes(state, xprog);
- travEdges(state, xprog);
+ travNodes(state, prog, bp);
+ travEdges(state, prog, bp);
break;
case TV_en:
- travEdges(state, xprog);
- travNodes(state, xprog);
+ travEdges(state, prog, bp);
+ travNodes(state, prog, bp);
break;
}
}
gpr_info info;
int rv = 0;
options* opts = 0;
- int incoreGraphs;
+ int i, incoreGraphs;
setErrorErrors (0);
ingDisc.dflt = sfstdin;
while ((state->curgraph = nextGraph(ing))) {
state->infname = fileName(ing);
- /* begin graph */
- if (incoreGraphs && (opts->compflags & CLONE))
- state->curgraph = clone (0, (Agobj_t*)(state->curgraph));
- state->curobj = (Agobj_t *) state->curgraph;
- state->tvroot = 0;
- if (xprog->begg_stmt)
- exeval(xprog->prog, xprog->begg_stmt, state);
+ for (i = 0; i < xprog->n_blocks; i++) {
+ comp_block* bp = xprog->blocks + i;
- /* walk graph */
- if (walksGraph(xprog))
- traverse(state, xprog);
+ /* begin graph */
+ if (incoreGraphs && (opts->compflags & CLONE))
+ state->curgraph = (Agraph_t*)clone (0, (Agobj_t*)(state->curgraph));
+ state->curobj = (Agobj_t *) state->curgraph;
+ state->tvroot = 0;
+ if (bp->begg_stmt)
+ exeval(xprog->prog, bp->begg_stmt, state);
+
+ /* walk graph */
+ if (walksGraph(bp))
+ traverse(state, xprog->prog, bp);
+ }
/* end graph */
state->curobj = (Agobj_t *) state->curgraph;
return kind;
}
+/* addBlock:
+ * create new block and append to list;
+ * return new item as tail
+ */
+static parse_block *addBlock (parse_block * last, char *stmt, int line,
+ int n_nstmts, case_info *nodelist, int n_estmts, case_info *edgelist)
+{
+ parse_block* item = newof(0, parse_block, 1, 0);
+
+ item->l_beging = line;
+ item->begg_stmt = stmt;
+ item->n_nstmts = n_nstmts;
+ item->n_estmts = n_estmts;
+ item->node_stmts = nodelist;
+ item->edge_stmts = edgelist;
+ if (last)
+ last->next = item;
+
+ return item;
+}
+
/* addCase:
* create new case_info and append to list;
* return new item as tail
char *guard = NULL;
char *action = NULL;
int more;
+ parse_block *blocklist = 0;
case_info *edgelist = 0;
case_info *nodelist = 0;
+ parse_block *blockl = 0;
case_info *edgel = 0;
case_info *nodel = 0;
+ int n_blocks = 0;
int n_nstmts = 0;
int n_estmts = 0;
int line = 0, gline = 0;
+ int l_beging;
+ char *begg_stmt;
prog = newof(0, parse_prog, 1, 0);
if (!prog) {
free (prog);
return 0;
}
-
+
+ begg_stmt = 0;
more = 1;
while (more) {
switch (parseCase(str, &guard, &gline, &action, &line)) {
&(prog->l_begin));
break;
case BeginG:
- bindAction(BeginG, action, line, &(prog->begg_stmt),
- &(prog->l_beging));
+ if (action && (begg_stmt || nodelist || edgelist)) { /* non-empty block */
+ blockl = addBlock(blockl, begg_stmt, l_beging,
+ n_nstmts, nodelist, n_estmts, edgelist);
+ if (!blocklist)
+ blocklist = blockl;
+ n_blocks++;
+
+ /* reset values */
+ n_nstmts = n_estmts = 0;
+ edgel = nodel = edgelist = nodelist = 0;
+ begg_stmt = 0;
+ }
+ bindAction(BeginG, action, line, &begg_stmt, &l_beging);
break;
case End:
bindAction(End, action, line, &(prog->end_stmt),
}
}
- prog->node_stmts = nodelist;
- prog->edge_stmts = edgelist;
- prog->n_nstmts = n_nstmts;
- prog->n_estmts = n_estmts;
+ if (begg_stmt || nodelist || edgelist) { /* non-empty block */
+ blockl = addBlock(blockl, begg_stmt, l_beging,
+ n_nstmts, nodelist, n_estmts, edgelist);
+ if (!blocklist)
+ blocklist = blockl;
+ n_blocks++;
+ }
+
+ prog->n_blocks = n_blocks;
+ prog->blocks = blocklist;
sfclose(str);
}
}
+static void
+freeBlocks (parse_block* ip)
+{
+ parse_block* nxt;
+ while (ip) {
+ nxt = ip->next;
+ free (ip->begg_stmt);
+ freeCaseList (ip->node_stmts);
+ freeCaseList (ip->edge_stmts);
+ ip = nxt;
+ }
+}
+
void
freeParseProg (parse_prog * prog)
{
if (!prog) return;
free (prog->begin_stmt);
- free (prog->begg_stmt);
- freeCaseList (prog->node_stmts);
- freeCaseList (prog->edge_stmts);
+ freeBlocks (prog->blocks);
free (prog->endg_stmt);
free (prog->end_stmt);
free (prog);