Node * dupnode(Node *n) { Node *d; if (!n) return n; d = getnode(n); d->lft = dupnode(n->lft); d->rgt = dupnode(n->rgt); return d; }
void init_fields() { emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields"); fields_arr[0] = dupnode(Nnull_string); parse_extent = fields_arr[0]->stptr; save_FS = dupnode(FS_node->var_value); getnode(Null_field); *Null_field = *Nnull_string; Null_field->valref = 1; Null_field->flags = (FIELD|STRCUR|STRING); field0_valid = true; }
static Node * bin_minimal(Node *ptr) { if (ptr) switch (ptr->ntyp) { case IMPLIES: return tl_nn(OR, Not(ptr->lft), ptr->rgt); case EQUIV: return tl_nn(OR, tl_nn(AND,dupnode(ptr->lft),dupnode(ptr->rgt)), tl_nn(AND,Not(ptr->lft),Not(ptr->rgt))); } return ptr; }
NODE * do_ext(int nargs) { NODE *obj, *init = NULL, *fini = NULL, *ret = NULL; SRCFILE *s; char *init_func = NULL; char *fini_func = NULL; if (nargs == 3) { fini = POP_STRING(); fini_func = fini->stptr; } if (nargs >= 2) { init = POP_STRING(); init_func = init->stptr; } obj = POP_STRING(); s = add_srcfile(SRC_EXTLIB, obj->stptr, srcfiles, NULL, NULL); if (s != NULL) ret = load_old_ext(s, init_func, fini_func, obj); DEREF(obj); if (fini != NULL) DEREF(fini); if (init != NULL) DEREF(init); if (ret == NULL) ret = dupnode(Nnull_string); return ret; }
void addtrans(Graph *col, char *from, Node *op, char *to) { State *b; Transition *t; t = (Transition *) tl_emalloc(sizeof(Transition)); t->name = tl_lookup(to); t->cond = Prune(dupnode(op)); if (tl_verbose) { printf("\n%s <<\t", from); dump(op); printf("\n\t"); dump(t->cond); printf(">> %s\n", t->name->name); } if (t->cond) t->cond = rewrite(t->cond); for (b = never; b; b = b->nxt) if (!strcmp(b->name->name, from)) { t->nxt = b->trans; b->trans = t; return; } b = (State *) tl_emalloc(sizeof(State)); b->name = tl_lookup(from); b->colors = col; b->trans = t; if (!strncmp(from, "accept", 6)) b->accepting = 1; b->nxt = never; never = b; }
static void addcan(int tok, Node *n, Miscellaneous *miscell) { Node *m, *prev = ZN; Node **ptr; Node *N; Symbol *s, *t; int cmp; static char dumpbuf[BUFF_LEN]; static Node *can = ZN; if (!n) return; if (n->ntyp == tok) { addcan(tok, n->rgt, miscell); addcan(tok, n->lft, miscell); return; } #if 0 if ((tok == AND && n->ntyp == TRUE) || (tok == OR && n->ntyp == FALSE)) return; #endif N = dupnode(n); if (!can) { can = N; return; } s = DoDump(N,dumpbuf, miscell); if (can->ntyp != tok) /* only one element in list so far */ { ptr = &can; goto insert; } /* there are at least 2 elements in list */ prev = ZN; for (m = can; m->ntyp == tok && m->rgt; prev = m, m = m->rgt) { t = DoDump(m->lft,dumpbuf, miscell); cmp = strcmp(s->name, t->name); if (cmp == 0) /* duplicate */ return; if (cmp < 0) { if (!prev) { can = tl_nn(tok, N, can, miscell); return; } else { ptr = &(prev->rgt); goto insert; } } } /* new entry goes at the end of the list */ ptr = &(prev->rgt); insert: t = DoDump(*ptr,dumpbuf, miscell); cmp = strcmp(s->name, t->name); if (cmp == 0) /* duplicate */ return; if (cmp < 0) *ptr = tl_nn(tok, N, *ptr, miscell); else *ptr = tl_nn(tok, *ptr, N, miscell); }
static void addcan(int tok, Node *n) { Node *m, *prev = ZN; Node **ptr; Node *N; Symbol *s, *t; int cmp; if (!n) return; if (n->ntyp == tok) { addcan(tok, n->rgt); addcan(tok, n->lft); return; } N = dupnode(n); if (!can) { can = N; return; } s = DoDump(N); if (can->ntyp != tok) /* only one element in list so far */ { ptr = &can; goto insert; } /* there are at least 2 elements in list */ prev = ZN; for (m = can; m->ntyp == tok && m->rgt; prev = m, m = m->rgt) { t = DoDump(m->lft); if (t != ZS) cmp = strcmp(s->name, t->name); else cmp = 0; if (cmp == 0) /* duplicate */ return; if (cmp < 0) { if (!prev) { can = tl_nn(tok, N, can); return; } else { ptr = &(prev->rgt); goto insert; } } } /* new entry goes at the end of the list */ ptr = &(prev->rgt); insert: t = DoDump(*ptr); cmp = strcmp(s->name, t->name); if (cmp == 0) /* duplicate */ return; if (cmp < 0) *ptr = tl_nn(tok, N, *ptr); else *ptr = tl_nn(tok, *ptr, N); }
int dump_cond(Node *pp, Node *r, int first) { Node *q; int frst = first; if (!pp) return frst; q = dupnode(pp); q = rewrite(q); if (q->ntyp == PREDICATE || q->ntyp == NOT #ifndef NXT || q->ntyp == OR #endif || q->ntyp == FALSE) { if (!frst) fprintf(tl_out, " && "); dump(q); frst = 0; #ifdef NXT } else if (q->ntyp == OR) { if (!frst) fprintf(tl_out, " && "); fprintf(tl_out, "(("); frst = dump_cond(q->lft, r, 1); if (!frst) fprintf(tl_out, ") || ("); else { if (only_nxt(q->lft)) { fprintf(tl_out, "1))"); return 0; } } frst = dump_cond(q->rgt, r, 1); if (frst) { if (only_nxt(q->rgt)) fprintf(tl_out, "1"); else fprintf(tl_out, "0"); frst = 0; } fprintf(tl_out, "))"); #endif } else if (q->ntyp == V_OPER && !anywhere(AND, q->rgt, r)) { frst = dump_cond(q->rgt, r, frst); } else if (q->ntyp == AND) { frst = dump_cond(q->lft, r, frst); frst = dump_cond(q->rgt, r, frst); } return frst; }
static Node *bin_minimal(Node *ptr) { Node *a, *b; if (ptr) { switch (ptr->ntyp) { case IMPLIES: return tl_nn(OR, Not(ptr->lft), ptr->rgt); case EQUIV: a = tl_nn(AND,dupnode(ptr->lft),dupnode(ptr->rgt)); b = tl_nn(AND,Not(ptr->lft),Not(ptr->rgt)); return tl_nn(OR, a, b); } } return ptr; }
static Node *bin_minimal(Node *ptr, Miscellaneous *miscell, int *cnt, char *uform, int *tl_yychar) { Node *a, *b; if (ptr) { switch (ptr->ntyp) { case IMPLIES: return tl_nn(OR, Not(ptr->lft), ptr->rgt, miscell); case EQUIV: a = tl_nn(AND,dupnode(ptr->lft),dupnode(ptr->rgt), miscell); b = tl_nn(AND,Not(ptr->lft),Not(ptr->rgt), miscell); return tl_nn(OR, a, b, miscell); } } return ptr; }
int dequeue(struct queue *q) { if (!q->first) { return 1; } if (q->first == q->last) /* if the queue has only one element*/ q->first = q->last = NULL; else q->first = dupnode(q->last); /* pop the first element out of the queue*/ q->first = q->last; return 0; }
Node * in_cache(Node *n) { Cache *d; int nr=0; for (d = stored; d; d = d->nxt, nr++) if (isequal(d->before, n)) { CacheHits++; if (d->same && ismatch(n, d->before)) return n; return dupnode(d->after); } return ZN; }
NODE * awk_value_to_node(const awk_value_t *retval) { NODE *ext_ret_val; NODE *v; if (retval == NULL) fatal(_("awk_value_to_node: received null retval")); switch (retval->val_type) { case AWK_ARRAY: ext_ret_val = (NODE *) retval->array_cookie; break; case AWK_UNDEFINED: ext_ret_val = dupnode(Nnull_string); break; case AWK_NUMBER: ext_ret_val = make_number(retval->num_value); break; case AWK_STRING: ext_ret_val = make_str_node(retval->str_value.str, retval->str_value.len, ALREADY_MALLOCED); break; case AWK_SCALAR: v = (NODE *) retval->scalar_cookie; if (v->type != Node_var) ext_ret_val = NULL; else ext_ret_val = dupnode(v->var_value); break; case AWK_VALUE_COOKIE: ext_ret_val = dupnode((NODE *)(retval->value_cookie)); break; default: /* any invalid type */ ext_ret_val = NULL; break; } return ext_ret_val; }
int enqueue(struct queue *q, Node *phi) { if (phi == NULL) { /* errno = ENOMEM;*/ return 1; } if(phi->visited == 0){ phi->visited = 0; if (q->first == NULL){ q->first = q->last = dupnode(phi); q->first = q->last = phi; /* point first and last in the queue to the phi passed if the queue is empty*/ } else { q->last = dupnode(phi); /* stuff the phi passed in the last of the queue if the queue is not empty*/ q->last = phi; } phi->visited = 1; return 0; } return -1; }
Regexp * re_update(NODE *t) { NODE *t1; if ((t->re_flags & CASE) == IGNORECASE) { if ((t->re_flags & CONST) != 0) { assert(t->type == Node_regex); return t->re_reg; } t1 = force_string(tree_eval(t->re_exp)); if (t->re_text != NULL) { if (cmp_nodes(t->re_text, t1) == 0) { free_temp(t1); return t->re_reg; } unref(t->re_text); } t->re_text = dupnode(t1); free_temp(t1); } if (t->re_reg != NULL) refree(t->re_reg); if (t->re_cnt > 0) t->re_cnt++; if (t->re_cnt > 10) t->re_cnt = 0; if (t->re_text == NULL || (t->re_flags & CASE) != IGNORECASE) { t1 = force_string(tree_eval(t->re_exp)); unref(t->re_text); t->re_text = dupnode(t1); free_temp(t1); } t->re_reg = make_regexp(t->re_text->stptr, t->re_text->stlen, IGNORECASE, t->re_cnt); t->re_flags &= ~CASE; t->re_flags |= IGNORECASE; return t->re_reg; }
void init_fields() { emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields"); fields_arr[0] = Nnull_string; parse_extent = fields_arr[0]->stptr; save_FS = dupnode(FS_node->var_value); getnode(Null_field); *Null_field = *Nnull_string; Null_field->flags |= FIELD; Null_field->flags &= ~(NUMCUR|NUMBER|MAYBE_NUM|PERM); field0_valid = TRUE; }
int BreadthFirstTraversal(struct queue *q,Node *root,Node *subformula[],int *i) { double infval = mxGetInf(); Node *p = NULL; if (root == NULL) return 0; enqueue(q,root); /* enqueue the root node*/ while (!queue_empty_p(q)) { if(!q->first){ p = NULL; } else{ /* set subformula index*/ p = dupnode(q->first); p = q->first; p->index = *i; subformula[*i] = dupnode(p); subformula[*i] = p; subformula[*i]->BoundCheck = 0; subformula[*i]->UBound = -infval; subformula[*i]->LBound = infval; subformula[*i]->LBound_nxt = infval; subformula[*i]->UBindicator = 0; subformula[*i]->LBindicator = 0; subformula[*i]->LBindicator_nxt = 0; subformula[*i]->loop_end = 0; (*i)++; } dequeue(q); if (p->lft != NULL) BreadthFirstTraversal( q,p->lft,subformula,i); if (p->rgt != NULL) BreadthFirstTraversal( q,p->rgt,subformula,i); } return (*i-1); }
Node * cached(Node *n) { Cache *d; Node *m; if (!n) return n; if ((m = in_cache(n)) != ZN) return m; Caches++; d = (Cache *) tl_emalloc(sizeof(Cache)); d->before = dupnode(n); d->after = Canonical(n); /* n is released */ if (ismatch(d->before, d->after)) { d->same = 1; releasenode(1, d->after); d->after = d->before; } d->nxt = stored; stored = d; return dupnode(d->after); }
static void store_SYS(NODE *symbol, NODE *subs, NODE *val, void *data) { sdata_t *sd = (sdata_t *) data; if (subs != NULL && val != NULL && val->type == Node_val) { force_string(subs); if (strcmp(subs->stptr, "readline") == 0) { sd->load_file = true; unref(sd->filename); sd->filename = dupnode(val); } } }
static Node * Duplicate(Node *n) { Node *n1, *n2, *lst = ZN, *d = ZN; for (n1 = n; n1; n1 = n1->nxt) { n2 = dupnode(n1); if (lst) { lst->nxt = n2; lst = n2; } else d = lst = n2; } return d; }
void init_fields() { emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields"); emalloc(nodes, NODE **, sizeof(NODE *), "init_fields"); emalloc(field0, NODE *, sizeof(NODE), "init_fields"); field0->type = Node_val; field0->stref = 0; field0->stptr = ""; field0->flags = (STRING|STR|PERM); /* never free buf */ fields_arr[0] = field0; save_FS = dupnode(FS_node->var_value); save_fs = save_FS->stptr; }
void init_fields() { NODE *n; emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields"); getnode(n); *n = *Nnull_string; n->flags |= (SCALAR|PERM); fields_arr[0] = n; parse_extent = fields_arr[0]->stptr; save_FS = dupnode(FS_node->var_value); field0_valid = TRUE; }
static Node * flatten(Node *p) { Node *q, *r, *z = ZN; for (q = p; q; q = q->nxt) { r = dupnode(q); if (z) z = tl_nn(AND, r, z); else z = r; } if (!z) return z; z = rewrite(z); return z; }
NODE * get_actual_argument(int i, bool optional, bool want_array) { NODE *t; char *fname; int pcount; INSTRUCTION *pc; pc = TOP()->code_ptr; /* Op_ext_builtin instruction */ fname = (pc + 1)->func_name; pcount = (pc + 1)->expr_count; t = get_argument(i); if (t == NULL) { if (i >= pcount) /* must be fatal */ fatal(_("function `%s' defined to take no more than %d argument(s)"), fname, pcount); if (! optional) fatal(_("function `%s': missing argument #%d"), fname, i + 1); return NULL; } if (t->type == Node_var_new) { if (want_array) return force_array(t, false); else { t->type = Node_var; t->var_value = dupnode(Nnull_string); return t->var_value; } } if (want_array) { if (t->type != Node_var_array) fatal(_("function `%s': argument #%d: attempt to use scalar as an array"), fname, i + 1); } else { if (t->type != Node_val) fatal(_("function `%s': argument #%d: attempt to use array as a scalar"), fname, i + 1); } assert(t->type == Node_var_array || t->type == Node_val); return t; }
void trans(Node *p) { Node *op; Graph *g; if (!p || tl_errs) return; p = twocases(p); if (tl_verbose || tl_terse) { fprintf(tl_out, "\t/* Normlzd: "); dump(p); fprintf(tl_out, " */\n"); } if (tl_terse) return; op = dupnode(p); ng(ZS, getsym(tl_lookup("init")), p, ZN, ZN); while ((g = Nodes_Stack) != (Graph *) 0) { Nodes_Stack = g->nxt; expand_g(g); } if (newstates) return; fixinit(p); liveness(flatten(op)); /* was: liveness(op); */ mkbuchi(); if (tl_verbose) { printf("/*\n"); printf(" * %d states in Streett automaton\n", Base); printf(" * %d Streett acceptance conditions\n", Max_Red); printf(" * %d Buchi states\n", Total); printf(" */\n"); } }
static Node * bin_simpler(Node *ptr) { Node *a, *b; if (ptr) switch (ptr->ntyp) { case U_OPER: #ifndef NO_OPT if (ptr->rgt->ntyp == TRUE || ptr->rgt->ntyp == FALSE || ptr->lft->ntyp == FALSE) { ptr = ptr->rgt; break; } if (isequal(ptr->lft, ptr->rgt)) { /* p U p = p */ ptr = ptr->rgt; break; } if (ptr->lft->ntyp == U_OPER && isequal(ptr->lft->lft, ptr->rgt)) { /* (p U q) U p = (q U p) */ ptr->lft = ptr->lft->rgt; break; } if (ptr->rgt->ntyp == U_OPER && ptr->rgt->lft->ntyp == TRUE) { /* p U (T U q) = (T U q) */ ptr = ptr->rgt; break; } #ifdef NXT /* X p U X q == X (p U q) */ if (ptr->rgt->ntyp == NEXT && ptr->lft->ntyp == NEXT) { ptr = tl_nn(NEXT, tl_nn(U_OPER, ptr->lft->lft, ptr->rgt->lft), ZN); } #endif #endif break; case V_OPER: #ifndef NO_OPT if (ptr->rgt->ntyp == FALSE || ptr->rgt->ntyp == TRUE || ptr->lft->ntyp == TRUE) { ptr = ptr->rgt; break; } if (isequal(ptr->lft, ptr->rgt)) { /* p V p = p */ ptr = ptr->rgt; break; } /* F V (p V q) == F V q */ if (ptr->lft->ntyp == FALSE && ptr->rgt->ntyp == V_OPER) { ptr->rgt = ptr->rgt->rgt; break; } /* p V (F V q) == F V q */ if (ptr->rgt->ntyp == V_OPER && ptr->rgt->lft->ntyp == FALSE) { ptr->lft = False; ptr->rgt = ptr->rgt->rgt; break; } #endif break; case IMPLIES: #ifndef NO_OPT if (isequal(ptr->lft, ptr->rgt)) { ptr = True; break; } #endif ptr = tl_nn(OR, Not(ptr->lft), ptr->rgt); ptr = rewrite(ptr); break; case EQUIV: #ifndef NO_OPT if (isequal(ptr->lft, ptr->rgt)) { ptr = True; break; } #endif a = rewrite(tl_nn(AND, dupnode(ptr->lft), dupnode(ptr->rgt))); b = rewrite(tl_nn(AND, Not(ptr->lft), Not(ptr->rgt))); ptr = tl_nn(OR, a, b); ptr = rewrite(ptr); break; case AND: #ifndef NO_OPT /* p && (q U p) = p */ if (ptr->rgt->ntyp == U_OPER && isequal(ptr->rgt->rgt, ptr->lft)) { ptr = ptr->lft; break; } if (ptr->lft->ntyp == U_OPER && isequal(ptr->lft->rgt, ptr->rgt)) { ptr = ptr->rgt; break; } /* p && (q V p) == q V p */ if (ptr->rgt->ntyp == V_OPER && isequal(ptr->rgt->rgt, ptr->lft)) { ptr = ptr->rgt; break; } if (ptr->lft->ntyp == V_OPER && isequal(ptr->lft->rgt, ptr->rgt)) { ptr = ptr->lft; break; } /* (p U q) && (r U q) = (p && r) U q*/ if (ptr->rgt->ntyp == U_OPER && ptr->lft->ntyp == U_OPER && isequal(ptr->rgt->rgt, ptr->lft->rgt)) { ptr = tl_nn(U_OPER, tl_nn(AND, ptr->lft->lft, ptr->rgt->lft), ptr->lft->rgt); break; } /* (p V q) && (p V r) = p V (q && r) */ if (ptr->rgt->ntyp == V_OPER && ptr->lft->ntyp == V_OPER && isequal(ptr->rgt->lft, ptr->lft->lft)) { ptr = tl_nn(V_OPER, ptr->rgt->lft, tl_nn(AND, ptr->lft->rgt, ptr->rgt->rgt)); break; } #ifdef NXT /* X p && X q == X (p && q) */ if (ptr->rgt->ntyp == NEXT && ptr->lft->ntyp == NEXT) { ptr = tl_nn(NEXT, tl_nn(AND, ptr->rgt->lft, ptr->lft->lft), ZN); break; } #endif if (isequal(ptr->lft, ptr->rgt) /* (p && p) == p */ || ptr->rgt->ntyp == FALSE /* (p && F) == F */ || ptr->lft->ntyp == TRUE) /* (T && p) == p */ { ptr = ptr->rgt; break; } if (ptr->rgt->ntyp == TRUE /* (p && T) == p */ || ptr->lft->ntyp == FALSE) /* (F && p) == F */ { ptr = ptr->lft; break; } /* (p V q) && (r U q) == p V q */ if (ptr->rgt->ntyp == U_OPER && ptr->lft->ntyp == V_OPER && isequal(ptr->lft->rgt, ptr->rgt->rgt)) { ptr = ptr->lft; break; } #endif break; case OR: #ifndef NO_OPT /* p || (q U p) == q U p */ if (ptr->rgt->ntyp == U_OPER && isequal(ptr->rgt->rgt, ptr->lft)) { ptr = ptr->rgt; break; } /* p || (q V p) == p */ if (ptr->rgt->ntyp == V_OPER && isequal(ptr->rgt->rgt, ptr->lft)) { ptr = ptr->lft; break; } /* (p U q) || (p U r) = p U (q || r) */ if (ptr->rgt->ntyp == U_OPER && ptr->lft->ntyp == U_OPER && isequal(ptr->rgt->lft, ptr->lft->lft)) { ptr = tl_nn(U_OPER, ptr->rgt->lft, tl_nn(OR, ptr->lft->rgt, ptr->rgt->rgt)); break; } if (isequal(ptr->lft, ptr->rgt) /* (p || p) == p */ || ptr->rgt->ntyp == FALSE /* (p || F) == p */ || ptr->lft->ntyp == TRUE) /* (T || p) == T */ { ptr = ptr->lft; break; } if (ptr->rgt->ntyp == TRUE /* (p || T) == T */ || ptr->lft->ntyp == FALSE) /* (F || p) == p */ { ptr = ptr->rgt; break; } /* (p V q) || (r V q) = (p || r) V q */ if (ptr->rgt->ntyp == V_OPER && ptr->lft->ntyp == V_OPER && isequal(ptr->lft->rgt, ptr->rgt->rgt)) { ptr = tl_nn(V_OPER, tl_nn(OR, ptr->lft->lft, ptr->rgt->lft), ptr->rgt->rgt); break; } /* (p V q) || (r U q) == r U q */ if (ptr->rgt->ntyp == U_OPER && ptr->lft->ntyp == V_OPER && isequal(ptr->lft->rgt, ptr->rgt->rgt)) { ptr = ptr->rgt; break; } #endif break; } return ptr; }
void gen(Node *n, int retain) { int i; if(n==0) return; switch(n->t){ case NArrayref: arygen(n->l, n->r, 0, 0L); if(!retain) popgen(n->l->o.s->val->type->r); return; case NBecome: didbecome=1; if(n->l->t==NCall && !bflag){ callgen(n->l, Ibecome); return; } gen(n->l, 1); n=n->r; if(n->o.t==TID) n=typeoftid(n); switch(n->o.t){ case TInt: case TChar: emit(Istoreauto); emitconst(-WS*(4+length(formals))); break; case TArray: case TChan: case TProg: case TStruct: emit(Istoreptrauto); emitconst(-WS*(4+length(formals))); break; case TUnit: break; default: panic("can't compile %t become", n); } scopedecrefgen(); trlrgen(); return; case NBegin: callgen(n->l, Ibegin); return; case NBreak: if(breakloc==-1) lerror(n, "break not in loop"); if(breakloc) /* chain previous break to here */ patch(breakloc, (long)(here()-breakloc-1)*WS); emit(Ijmp); breakloc=here(); emitconst(0L); return; case NCall: callgen(n, Icall); if(!retain) popgen(etypeoft(n->l)->r); return; case NComplete: gen(n->l, retain); return; case NContinue: if(continueloc==-1) lerror(n, "continue not in loop"); if(continueloc) /* chain previous continue to here */ patch(continueloc, (long)(here()-continueloc-1)*WS); emit(Ijmp); continueloc=here(); emitconst(0L); return; case NDecl: case NDeclsc: declare(n, 0, 0, 1); return; case NExpr: switch(n->o.i){ case GE: i=Ige; Binop: gen(n->l, 1); gen(n->r, 1); if(eqtype(etypeof(n->l), &arychartype)){ emit(Istrcmp); constgen(0L); } emit(i); Popit: if(!retain) emit(Ipop); return; case LE: i=Ile; goto Binop; case NE: i=Ine; goto Binop; case EQ: i=Ieq; goto Binop; case '>': i=Igt; goto Binop; case '<': i=Ilt; goto Binop; case '+': i=Iadd; goto Binop; case '-': i=Isub; goto Binop; case '*': i=Imul; goto Binop; case '/': i=Idiv; goto Binop; case '%': i=Imod; goto Binop; case '&': i=Iand; goto Binop; case '|': i=Ior; goto Binop; case '^': i=Ixor; goto Binop; case LSH: i=Ilsh; goto Binop; case RSH: i=Irsh; goto Binop; case ANDAND: condgen(n->l, n->r, Ijmptrue, Ijmpfalse, 0L, 1L, retain); return; case OROR: condgen(n->l, n->r, Ijmpfalse, Ijmptrue, 1L, 0L, retain); return; case CAT: gen(n->l, 1); gen(n->r, 1); emit(Icat); return; case DEL: gen(n->l, 1); gen(n->r, 1); emit(Idel); return; case PRINT: gen(n->l, 1); printgen(n->l); emit(Isprnt); if(!retain) emit(Iprint); return; case SND: gen(n->l, 1); constgen((long)Cissnd); emit(Icommset1); emit(Icommcln1); gen(n->r, 1); if(isptrtype(etypeoft(n->l)->r)) emit(Isndptr); else emit(Isnd); if(!retain) popgen(etypeof(n)); return; case RCV: gen(n->l, 1); constgen(0L); /* not Cissnd */ emit(Icommset1); emit(Icommcln1); if(!retain) popgen(etypeof(n)); return; case '=': gen(n->r, 1); if(retain) dupgen(etypeof(n->r), 1); lgen(n->l); return; case LEN: gen(n->l, 1); emit(Ilen); goto Popit; case REF: if(isptrtype(etypeof(n->l))){ gen(n->l, 1); emit(Iref); }else constgen(1L); goto Popit; case DEF: if(retain && n->l->t==NID && isinttype(etypeof(n->l))){ constgen(1L); return; } /* * don't really need to call lgen1, which will uniquify our * array for us, but it does no harm, and it's easy. */ lgen1(n->l, Idefauto, Idef, Idefary); goto Popit; case UMINUS: gen(n->l, 1); emit(Ineg); goto Popit; case '~': gen(n->l, 1); emit(Inot); goto Popit; case '!': gen(n->l, 1); emit(Ilnot); goto Popit; case INC: lgen1(n->l, Iincauto, Iinc, Iincary); goto Popit; case DEC: lgen1(n->l, Idecauto, Idec, Idecary); goto Popit; default: panic("can't compile %e expression", n); } case NExprlist: /* * This is an arg or element list; first is pushed last */ gen(n->r, 1); gen(n->l, 1); return; case NID: if(!retain) return; switch(type_of(n)->o.t){ case TInt: case TChar: if(n->o.s->val->isauto){ emit(Ipushauto); emitconst(n->o.s->val->store.off); }else{ emit(Ipush); emitconst((long)&n->o.s->val->store.l); } return; case TProg: case TArray: case TChan: case TStruct: if(n->o.s->val->isauto){ emit(Ipushptrauto); emitconst(n->o.s->val->store.off); }else{ emit(Ipushptr); emitconst((long)&n->o.s->val->store.l); } return; case TUnit: if(retain) constgen(0L); return; case TType: lerror(n, "attempt to evaluate type variable %m", n); default: panic("can't compile type %t", n->o.s->val->type); } case NIf: ifgen(n); return; case NList: gen(n->l, 0); gen(n->r, 0); return; case NLoop: loopgen(n); return; case NMk: mkgen(n->l, n->r); return; case NNum: if(retain) constgen(n->o.l); return; case NProg: if(retain) proggen(n->l, n->r); return; case NResult: if(resultloc==0) lerror(n, "result not in val"); gen(n->l, 1); emit(Ijmp); emitconst((long)(resultloc-here()-1)*WS); return; case NScope: pushscope(); if(nscope==1){ int nauto; autooffset=0; emit(Ipushfp); nauto=here(); emitconst(0L); gen(n->l, 0); patch((int)nauto, autooffset); emit(Ipop); /* Ipopfp() */ }else gen(n->l, 0); scopedecrefgen(); popscope(); return; case NSelect: selgen(n->l); return; case NSmash:{ Value *vl, *vr; vl=n->l->o.s->val; vr=n->r->o.s->val; if(vr->type->o.t==TType){ freenode(vl->type); vl->type=dupnode(vr->type); return; } gen(n->r, 1); /* * Free old values; tricky: push as int, pop as ptr */ if(isptrtype(vl->type)){ if(vl->isauto){ emit(Ipushauto); emitconst(vl->store.off); }else{ emit(Ipush); emitconst((long)&vl->store.l); } emit(Ipopptr); } if(vl->isauto){ emit(Istoreauto); emitconst(vl->store.l); return; } emit(Istore); emitconst((long)&vl->store.l); return; } case NString: if(retain){ emit(Ipushdata); emitconst((long)n->o.st); emitstore(n->o.st); n->o.st->ref++; } return; case NStructref: arygen(n->l, n->r, 1, n->o.l); return; case NSwitch: switchgen(n->l, n->r); return; case NUnit: if(retain) constgen(0L); return; case NVal: valgen(n->l); if(!retain) popgen(n->o.n); return; } panic("can't compile node %n", n); return; }
void mkgen(Node *t, Node *v) { switch(t->o.t){ case TAggr: lerror(v, "can't derive type in mk %m", v); case TChar: case TInt: case TUnit: if(v) gen(v, 1); else constgen(0L); return; case TID: mkgen(typeoftid(t), v); return; case TChan: if(v) gen(v, 1); else{ constgen((long)(sizeof(Chan)-sizeof(Store))); mallocgen(t); } return; case TArray: if(v==0){ if(t->l==0) constgen(0L); else gen(t->l, 1); mallocgen(t); return; } gen(v, 1); if(v->t!=NExprlist && eqtype(t, etypeof(v))) return; if(v->t==NString && eqtype(t, etypeof(v))) constgen(v->o.st->len); else constgen(length(v)); emit(Idup); if(t->l) gen(t->l, 1); else constgen(0L); emit(Imax); mallocgen(t); if(t->r->o.t==TChar){ if(v->t==NString) emit(Imemcpychar); else emit(Imemcpycharint); }else emit(Imemcpy); return; case TProg: if(v==0){ v=new(NProg, dupnode(t), (Node *)0, (Node *)0); gen(v, 1); freenode(v); return; } gen(v, 1); return; case TStruct: if(v==0){ mallocgen(t); return; } gen(v, 1); if(v->t!=NExprlist && eqtype(t, etypeof(v))) return; constgen((long)length(v)); mallocgen(t); emit(Imemcpystruct); return; default: panic("mkgen: bad type %t", t); }
static void expand_g(Graph *g) { Node *now, *n1, *n2, *nx; int can_release; if (!g->New) { Debug2("\nDone with %s", g->name->name); if (tl_verbose) dump_graph(g); if (not_new(g)) { if (tl_verbose) printf("\tIs Not New\n"); return; } if (g->Next) { Debug(" Has Next ["); for (n1 = g->Next; n1; n1 = n1->nxt) { Dump(n1); Debug(", "); } Debug("]\n"); ng(ZS, getsym(g->name), g->Next, ZN, ZN); } return; } if (tl_verbose) { Symbol *z; printf("\nExpand %s, from ", g->name->name); for (z = g->incoming; z; z = z->next) printf("%s, ", z->name); printf("\n\thandle:\t"); Explain(g->New->ntyp); dump_graph(g); } if (g->New->ntyp == AND) { if (g->New->nxt) { n2 = g->New->rgt; while (n2->nxt) n2 = n2->nxt; n2->nxt = g->New->nxt; } n1 = n2 = g->New->lft; while (n2->nxt) n2 = n2->nxt; n2->nxt = g->New->rgt; releasenode(0, g->New); g->New = n1; push_stack(g); return; } can_release = 0; /* unless it need not go into Old */ now = g->New; g->New = g->New->nxt; now->nxt = ZN; if (now->ntyp != TRUE) { if (g->Old) { for (n1 = g->Old; n1->nxt; n1 = n1->nxt) if (isequal(now, n1)) { can_release = 1; goto out; } n1->nxt = now; } else g->Old = now; } out: switch (now->ntyp) { case FALSE: push_stack(g); break; case TRUE: releasenode(1, now); push_stack(g); break; case PREDICATE: case NOT: if (can_release) releasenode(1, now); push_stack(g); break; case V_OPER: Assert(now->rgt != ZN, now->ntyp); Assert(now->lft != ZN, now->ntyp); Assert(now->rgt->nxt == ZN, now->ntyp); Assert(now->lft->nxt == ZN, now->ntyp); n1 = now->rgt; n1->nxt = g->New; if (can_release) nx = now; else nx = getnode(now); /* now also appears in Old */ nx->nxt = g->Next; n2 = now->lft; n2->nxt = getnode(now->rgt); n2->nxt->nxt = g->New; g->New = flatten(n2); push_stack(g); ng(ZS, g->incoming, n1, g->Old, nx); break; case U_OPER: Assert(now->rgt->nxt == ZN, now->ntyp); Assert(now->lft->nxt == ZN, now->ntyp); n1 = now->lft; if (can_release) nx = now; else nx = getnode(now); /* now also appears in Old */ nx->nxt = g->Next; n2 = now->rgt; n2->nxt = g->New; goto common; #ifdef NXT case NEXT: Assert(now->lft != ZN, now->ntyp); nx = dupnode(now->lft); nx->nxt = g->Next; g->Next = nx; if (can_release) releasenode(0, now); push_stack(g); break; #endif case OR: Assert(now->rgt->nxt == ZN, now->ntyp); Assert(now->lft->nxt == ZN, now->ntyp); n1 = now->lft; nx = g->Next; n2 = now->rgt; n2->nxt = g->New; common: n1->nxt = g->New; ng(ZS, g->incoming, n1, g->Old, nx); g->New = flatten(n2); if (can_release) releasenode(1, now); push_stack(g); break; } }
static int not_new(Graph *g) { Graph *q1; Node *tmp, *n1, *n2; Mapping *map; tmp = flatten(g->Old); /* duplicate, collapse, normalize */ g->Other = g->Old; /* non normalized full version */ g->Old = tmp; g->oldstring = DoDump(g->Old); tmp = flatten(g->Next); g->nxtstring = DoDump(tmp); if (tl_verbose) dump_graph(g); Debug2("\tformula-old: [%s]\n", g->oldstring?g->oldstring->name:"true"); Debug2("\tformula-nxt: [%s]\n", g->nxtstring?g->nxtstring->name:"true"); for (q1 = Nodes_Set; q1; q1 = q1->nxt) { Debug2(" compare old to: %s", q1->name->name); Debug2(" [%s]", q1->oldstring?q1->oldstring->name:"true"); Debug2(" compare nxt to: %s", q1->name->name); Debug2(" [%s]", q1->nxtstring?q1->nxtstring->name:"true"); if (q1->oldstring != g->oldstring || q1->nxtstring != g->nxtstring) { Debug(" => different\n"); continue; } Debug(" => match\n"); if (g->incoming) q1->incoming = catSlist(g->incoming, q1->incoming); /* check if there's anything in g->Other that needs adding to q1->Other */ for (n2 = g->Other; n2; n2 = n2->nxt) { for (n1 = q1->Other; n1; n1 = n1->nxt) if (isequal(n1, n2)) break; if (!n1) { Node *n3 = dupnode(n2); /* don't mess up n2->nxt */ n3->nxt = q1->Other; q1->Other = n3; } } map = (Mapping *) tl_emalloc(sizeof(Mapping)); map->from = g->name->name; map->to = q1; map->nxt = Mapped; Mapped = map; for (n1 = g->Other; n1; n1 = n2) { n2 = n1->nxt; releasenode(1, n1); } for (n1 = g->Old; n1; n1 = n2) { n2 = n1->nxt; releasenode(1, n1); } for (n1 = g->Next; n1; n1 = n2) { n2 = n1->nxt; releasenode(1, n1); } return 1; } if (newstates) tl_verbose=1; Debug2(" New Node %s [", g->name->name); for (n1 = g->Old; n1; n1 = n1->nxt) { Dump(n1); Debug(", "); } Debug2("] nr %d\n", Base); if (newstates) tl_verbose=0; Base++; g->nxt = Nodes_Set; Nodes_Set = g; return 0; }