⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pangen2.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 5 页
字号:
		} else			fprintf(tb, ";");	} else		fprintf(tb, ";");	fprintf(tb, "\n\t\t");	if (multi_undo)	{	fprintf(tb, "ungrab_ints(trpt->bup.ovals, %d);\n\t\t",			multi_undo);		multi_undo = 0;	}	if (didcase)	{	fprintf(tb, "goto R999;\n");		bupcase = casenr;	}	if (!e->merge && !e->merge_start)		new_case(e, casenr, bupcase, Pid);gotit:	j = a;	if (e->merge_start)		j = e->merge_start;	else if (e->merge)		j = e->merge;haveit:	fprintf(tt, "%ssettr(%d,%d,%d,%d,%d,\"", fromcache?"/* c */ ":"",		e->Seqno, mark, j, casenr, bupcase);	return (fromcache)?0:casenr;}static voidput_el(Element *e, int Tt0, int Tt1){	int a, casenr, Global_ref;	Element *g = ZE;	if (e->n->ntyp == GOTO)	{	g = get_lab(e->n, 1);		g = huntele(g, e->status, -1);		cross_dsteps(e->n, g->n);		a = g->seqno;	} else if (e->nxt)	{	g = huntele(e->nxt, e->status, -1);		a = g->seqno;	} else		a = 0;	if (g	&&  (g->status&CHECK2	/* entering remotely ref'd state */	||   e->status&CHECK2))	/* leaving  remotely ref'd state */		e->status |= I_GLOB;	/* don't remove dead edges in here, to preserve structure of fsm */	if (e->merge_start || e->merge)		goto non_generic;	/*** avoid duplicate or redundant cases in pan.m ***/	switch (e->n->ntyp) {	case ELSE:		casenr = 2; /* standard else */		putskip(e->seqno);		goto generic_case;		/* break; */	case '.':	case GOTO:	case BREAK:		putskip(e->seqno); 		casenr = 1; /* standard goto */generic_case:	fprintf(tt, "\ttrans[%d][%d]\t= ", Pid, e->seqno);		fprintf(tt, "settr(%d,%d,%d,%d,0,\"",			e->Seqno, e->status&ATOM, a, casenr);		break;#ifndef PRINTF	case PRINT:		goto non_generic;	case PRINTM:		goto non_generic;#endif	case 'c':		if (e->n->lft->ntyp == CONST		&&  e->n->lft->val == 1)	/* skip or true */		{	casenr = 1;			putskip(e->seqno);			goto generic_case;		}		goto non_generic;	default:non_generic:		casenr = case_cache(e, a);		if (casenr < 0) return;	/* unreachable state */		break;	}	/* tailend of settr(...); */	Global_ref = (e->status&I_GLOB)?1:has_global(e->n);	comment(tt, e->n, e->seqno);	fprintf(tt, "\", %d, ", Global_ref);	if (Tt0 != 2)	{	fprintf(tt, "%d, %d);", Tt0, Tt1);	} else	{	Tpe(e->n);	/* sets EPT */		fprintf(tt, "%d, %d);", EPT[0], EPT[1]);	}	if ((e->merge_start && e->merge_start != a)	||  (e->merge && e->merge != a))	{	fprintf(tt, " /* m: %d -> %d,%d */\n",			a, e->merge_start, e->merge);		fprintf(tt, "	reached%d[%d] = 1;",			Pid, a); /* Sheinman's example */	}	fprintf(tt, "\n");	if (casenr > 2)		tr_map(casenr, e);	put_escp(e);}static voidnested_unless(Element *e, Element *g){	struct SeqList *y = e->esc, *z = g->esc;	for ( ; y && z; y = y->nxt, z = z->nxt)		if (z->this != y->this)			break;	if (!y && !z)		return;	if (g->n->ntyp != GOTO	&&  g->n->ntyp != '.'	&&  e->sub->nxt)	{	printf("error: (%s:%d) saw 'unless' on a guard:\n",			(e->n)?e->n->fn->name:"-",			(e->n)?e->n->ln:0);		printf("=====>instead of\n");		printf("	do (or if)\n");		printf("	:: ...\n");		printf("	:: stmnt1 unless stmnt2\n");		printf("	od (of fi)\n");		printf("=====>use\n");		printf("	do (or if)\n");		printf("	:: ...\n");		printf("	:: stmnt1\n");		printf("	od (or fi) unless stmnt2\n");		printf("=====>or rewrite\n");	}}static voidput_seq(Sequence *s, int Tt0, int Tt1){	SeqList *h;	Element *e, *g;	int a, deadlink;	if (0) printf("put_seq %d\n", s->frst->seqno);	for (e = s->frst; e; e = e->nxt)	{		if (0) printf("	step %d\n", e->seqno);		if (e->status & DONE)		{			if (0) printf("		done before\n");			goto checklast;		}		e->status |= DONE;		if (e->n->ln)			putsrc(e);		if (e->n->ntyp == UNLESS)		{			if (0) printf("		an unless\n");			put_seq(e->sub->this, Tt0, Tt1);		} else if (e->sub)		{			if (0) printf("		has sub\n");			fprintf(tt, "\tT = trans[%d][%d] = ",				Pid, e->seqno);			fprintf(tt, "settr(%d,%d,0,0,0,\"",				e->Seqno, e->status&ATOM);			comment(tt, e->n, e->seqno);			if (e->status&CHECK2)				e->status |= I_GLOB;			fprintf(tt, "\", %d, %d, %d);",				(e->status&I_GLOB)?1:0, Tt0, Tt1);			blurb(tt, e);			for (h = e->sub; h; h = h->nxt)			{	putskip(h->this->frst->seqno);				g = huntstart(h->this->frst);				if (g->esc)					nested_unless(e, g);				a = g->seqno;				if (g->n->ntyp == 'c'				&&  g->n->lft->ntyp == CONST				&&  g->n->lft->val == 0		/* 0 or false */				&& !g->esc)				{	fprintf(tt, "#if 0\n\t/* dead link: */\n");					deadlink = 1;					if (verbose&32)					printf("spin: line %3d  %s, Warning: condition is always false\n",						g->n->ln, g->n->fn?g->n->fn->name:"");				} else					deadlink = 0;				if (0) printf("			settr %d %d\n", a, 0);				if (h->nxt)					fprintf(tt, "\tT = T->nxt\t= ");				else					fprintf(tt, "\t    T->nxt\t= ");				fprintf(tt, "settr(%d,%d,%d,0,0,\"",					e->Seqno, e->status&ATOM, a);				comment(tt, e->n, e->seqno);				if (g->status&CHECK2)					h->this->frst->status |= I_GLOB;				fprintf(tt, "\", %d, %d, %d);",					(h->this->frst->status&I_GLOB)?1:0,					Tt0, Tt1);				blurb(tt, e);				if (deadlink)					fprintf(tt, "#endif\n");			}			for (h = e->sub; h; h = h->nxt)				put_seq(h->this, Tt0, Tt1);		} else		{			if (0) printf("		[non]atomic %d\n", e->n->ntyp);			if (e->n->ntyp == ATOMIC			||  e->n->ntyp == D_STEP			||  e->n->ntyp == NON_ATOMIC)				put_sub(e, Tt0, Tt1);			else 			{				if (0) printf("			put_el %d\n", e->seqno);				put_el(e, Tt0, Tt1);			}		}checklast:	if (e == s->last)			break;	}	if (0) printf("put_seq done\n");}static voidpatch_atomic(Sequence *s)	/* catch goto's that break the chain */{	Element *f, *g;	SeqList *h;	for (f = s->frst; f ; f = f->nxt)	{		if (f->n && f->n->ntyp == GOTO)		{	g = get_lab(f->n,1);			cross_dsteps(f->n, g->n);			if ((f->status & (ATOM|L_ATOM))			&& !(g->status & (ATOM|L_ATOM)))			{	f->status &= ~ATOM;				f->status |= L_ATOM;			}			/* bridge atomics */			if ((f->status & L_ATOM)			&&  (g->status & (ATOM|L_ATOM)))			{	f->status &= ~L_ATOM;				f->status |= ATOM;			}		} else		for (h = f->sub; h; h = h->nxt)			patch_atomic(h->this);		if (f == s->extent)			break;	}}static voidmark_seq(Sequence *s){	Element *f;	SeqList *h;	for (f = s->frst; f; f = f->nxt)	{	f->status |= I_GLOB;		if (f->n->ntyp == ATOMIC		||  f->n->ntyp == NON_ATOMIC		||  f->n->ntyp == D_STEP)			mark_seq(f->n->sl->this);		for (h = f->sub; h; h = h->nxt)			mark_seq(h->this);		if (f == s->last)			return;	}}static Element *find_target(Element *e){	Element *f;	if (!e) return e;	if (t_cyc++ > 32)	{	fatal("cycle of goto jumps", (char *) 0);	}	switch (e->n->ntyp) {	case  GOTO:		f = get_lab(e->n,1);		cross_dsteps(e->n, f->n);		f = find_target(f);		break;	case BREAK:		if (e->nxt)		f = find_target(huntele(e->nxt, e->status, -1));		/* else fall through */	default:		f = e;		break;	}	return f;}Element *target(Element *e){	if (!e) return e;	lineno = e->n->ln;	Fname  = e->n->fn;	t_cyc = 0;	return find_target(e);}static intscan_seq(Sequence *s){	Element *f, *g;	SeqList *h;	for (f = s->frst; f; f = f->nxt)	{	if ((f->status&CHECK2)		||  has_global(f->n))			return 1;		if (f->n->ntyp == GOTO)	/* may reach other atomic */		{	g = target(f);			if (g			&& !(f->status & L_ATOM)			&& !(g->status & (ATOM|L_ATOM)))			{	fprintf(tt, "	/* goto mark-down, ");				fprintf(tt, "line %d - %d */\n",					f->n->ln, (g->n)?g->n->ln:0);				return 1; /* assume worst case */		}	}		for (h = f->sub; h; h = h->nxt)			if (scan_seq(h->this))				return 1;		if (f == s->last)			break;	}	return 0;}static intglob_args(Lextok *n){	int result = 0;	Lextok *v;	for (v = n->rgt; v; v = v->rgt)	{	if (v->lft->ntyp == CONST)			continue;		if (v->lft->ntyp == EVAL)			result += has_global(v->lft->lft);		else			result += has_global(v->lft);	}	return result;}inthas_global(Lextok *n){	Lextok *v; extern int runsafe;	if (!n) return 0;	if (AllGlobal) return 1;	/* global provided clause */	switch (n->ntyp) {	case ATOMIC:	case D_STEP:	case NON_ATOMIC:		return scan_seq(n->sl->this);	case '.':	case BREAK:	case GOTO:	case CONST:		return 0;	case   ELSE: return n->val; /* true if combined with chan refs */	case    's': return glob_args(n)!=0 || ((n->sym->xu&(XS|XX)) != XS);	case    'r': return glob_args(n)!=0 || ((n->sym->xu&(XR|XX)) != XR);	case    'R': return glob_args(n)!=0 || (((n->sym->xu)&(XR|XS|XX)) != (XR|XS));	case NEMPTY: return ((n->sym->xu&(XR|XX)) != XR);	case  NFULL: return ((n->sym->xu&(XS|XX)) != XS);	case   FULL: return ((n->sym->xu&(XR|XX)) != XR);	case  EMPTY: return ((n->sym->xu&(XS|XX)) != XS);	case  LEN:   return (((n->sym->xu)&(XR|XS|XX)) != (XR|XS));	case   NAME:		if (n->sym->context		|| (n->sym->hidden&64)		||  strcmp(n->sym->name, "_pid") == 0		||  strcmp(n->sym->name, "_") == 0)			return 0;		return 1;	case RUN: return 1-runsafe;	case C_CODE: case C_EXPR:		return glob_inline(n->sym->name);	case ENABLED: case PC_VAL: case NONPROGRESS:	case 'p': case 'q':	case TIMEOUT:		return 1;	/* 	@ was 1 (global) since 2.8.5		in 3.0 it is considered local and		conditionally safe, provided:			II is the youngest process			and nrprocs < MAXPROCS	*/	case '@': return 0;	case '!': case UMIN: case '~': case ASSERT:		return has_global(n->lft);	case '/': case '*': case '-': case '+':	case '%': case LT:  case GT: case '&': case '^':	case '|': case LE:  case GE:  case NE: case '?':	case EQ:  case OR:  case AND: case LSHIFT:	case RSHIFT: case 'c': case ASGN:		return has_global(n->lft) || has_global(n->rgt);	case PRINT:		for (v = n->lft; v; v = v->rgt)			if (has_global(v->lft)) return 1;		return 0;	case PRINTM:		return has_global(n->lft);	}	return 0;}static voidBailout(FILE *fd, char *str){	if (!GenCode)		fprintf(fd, "continue%s", str);	else if (IsGuard)		fprintf(fd, "%s%s", NextLab[Level], str);	else		fprintf(fd, "Uerror(\"block in step seq\")%s", str);}#define cat0(x)   	putstmnt(fd,now->lft,m); fprintf(fd, x); \			putstmnt(fd,now->rgt,m)#define cat1(x)		fprintf(fd,"("); cat0(x); fprintf(fd,")")#define cat2(x,y)  	fprintf(fd,x); putstmnt(fd,y,m)#define cat3(x,y,z)	fprintf(fd,x); putstmnt(fd,y,m); fprintf(fd,z)voidputstmnt(FILE *fd, Lextok *now, int m){	Lextok *v;	int i, j;	if (!now) { fprintf(fd, "0"); return; }	lineno = now->ln;	Fname  = now->fn;	switch (now->ntyp) {	case CONST:	fprintf(fd, "%d", now->val); break;	case '!':	cat3(" !(", now->lft, ")"); break;	case UMIN:	cat3(" -(", now->lft, ")"); break;	case '~':	cat3(" ~(", now->lft, ")"); break;	case '/':	cat1("/");  break;	case '*':	cat1("*");  break;	case '-':	cat1("-");  break;	case '+':	cat1("+");  break;	case '%':	cat1("%%"); break;	case '&':	cat1("&");  break;	case '^':	cat1("^");  break;	case '|':	cat1("|");  break;	case LT:	cat1("<");  break;	case GT:	cat1(">");  break;	case LE:	cat1("<="); break;	case GE:	cat1(">="); break;	case NE:	cat1("!="); break;	case EQ:	cat1("=="); break;	case OR:	cat1("||"); break;	case AND:	cat1("&&"); break;	case LSHIFT:	cat1("<<"); break;	case RSHIFT:	cat1(">>"); break;	case TIMEOUT:		if (separate == 2)			fprintf(fd, "((tau)&1)");		else			fprintf(fd, "((trpt->tau)&1)");		if (GenCode)		 printf("spin: line %3d, warning: 'timeout' in d_step sequence\n",			lineno);		/* is okay as a guard */		break;	case RUN:		if (claimproc		&&  strcmp(now->sym->name, claimproc) == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -