Пример #1
0
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;
}
Пример #2
0
Файл: field.c Проект: gvlx/gawk
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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);
}
Пример #7
0
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);
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
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;
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
Файл: re.c Проект: WndSks/msys
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;
}
Пример #16
0
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;
}
Пример #17
0
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);
} 
Пример #18
0
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);
}
Пример #19
0
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);
		}
	}
}
Пример #20
0
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;
}
Пример #21
0
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;
}
Пример #22
0
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;
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
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");
	}
}
Пример #26
0
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;
}
Пример #27
0
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;
}
Пример #28
0
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);
	}
Пример #29
0
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;
	}
}
Пример #30
0
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;
}