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

📄 tree.c

📁 window下的c编译器。
💻 C
字号:
#include "c.h"

static int where = STMT;
static int nid = 1;		/* identifies trees & nodes in debugging output */
static struct nodeid {
	int printed;
	Tree node;
} ids[500];			/* if ids[i].node == p, then p's id is i */

static void printtree1 ARGS((Tree, int, int));

Tree tree(int op,Type type,Tree left,Tree right) {
	Tree p;

	NEW0(p, where);
	p->op = op;
	p->type = type;
	p->kids[0] = left;
	p->kids[1] = right;
	return p;
}

Tree texpr(Tree (*f)(int), int tok,int a)
{
	int save = where;
	Tree p;

	where = a;
	p = (*f)(tok);
	where = save;
	return p;
}
/* right - return (RIGHT, root(p), q) or just p/q if q/p==0;
   if ty==NULL, use q->type, or q->type/p->type */
Tree right(Tree p,Tree q)
{
	assert(p || q);
	if (p && q)
		return tree(RIGHT, q->type, root(p), q);
	else if (p)
		return p;
	else
		return q;
}

Tree root(Tree p)
{
	if (p == NULL)
		return p;
	switch (generic(p->op)) {
	case COND: {
		Tree q = p->kids[1];
		assert(q && q->op == RIGHT);
		if (p->u.sym && q->kids[0] && generic(q->kids[0]->op) == ASGN)
			q->kids[0] = root(q->kids[0]->kids[1]);
		else
			q->kids[0] = root(q->kids[0]);
		if (p->u.sym && q->kids[1] && generic(q->kids[1]->op) == ASGN)
			q->kids[1] = root(q->kids[1]->kids[1]);
		else
			q->kids[1] = root(q->kids[1]);
		p->u.sym = 0;
		if (q->kids[0] == 0 && q->kids[1] == 0)
			p = root(p->kids[0]);
		}
		break;
	case AND: case OR:
		if ((p->kids[1] = root(p->kids[1])) == 0)
			p = root(p->kids[0]);
		break;
	case NOT:
		return root(p->kids[0]);
	case RIGHT:
		if (p->kids[1] == 0)
			return root(p->kids[0]);
		if (p->kids[0] && p->kids[0]->op == CALL+B
		&&  p->kids[1] && p->kids[1]->op == INDIR+B)
			/* avoid premature release of the CALL+B temporary */
			return p->kids[0];
		if (p->kids[0] && p->kids[0]->op == RIGHT
		&&  p->kids[1] == p->kids[0]->kids[0])
			/* de-construct e++ construction */
			return p->kids[0]->kids[1];
		/* fall thru */
	case EQ:  case NE:  case GT:   case GE:  case LE:  case LT:
	case ADD: case SUB: case MUL:  case DIV: case MOD:
	case LSH: case RSH: case BAND: case BOR: case BXOR:
		p = tree(RIGHT, p->type, root(p->kids[0]), root(p->kids[1]));
		return p->kids[0] || p->kids[1] ? p : 0;
	case INDIR:
		if (p->type->size == 0 && unqual(p->type) != voidtype)
			warning(StrTab[52], p->type);// <reference to `%t' elided\n>
		if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
			warning(StrTab[53], p->type);// <reference to `volatile %t' elided\n>
		/* fall thru */
	case CVI: case CVF:  case CVD:   case CVU: case CVC: case CVS: case CVP:
	case NEG: case BCOM: case FIELD:
		return root(p->kids[0]);
	case ADDRL: case ADDRG: case ADDRF: case CNST:
		return 0;
	case ARG: case ASGN: case CALL: case JUMP: case LABEL:
		break;
	default: assert(0);
	}
	return p;
}

char *opname(int op)
{
#if 1
	static char *opnames[] = {
	"",
	"CNST",
	"ARG",
	"ASGN",
	"INDIR",
	"CVC",
	"CVD",
	"CVF",
	"CVI",
	"CVP",
	"CVS",
	"CVU",
	"NEG",
	"CALL",
	"LOAD",
	"RET",
	"ADDRG",
	"ADDRF",
	"ADDRL",
	"ADD",
	"SUB",
	"LSH",
	"MOD",
	"RSH",
	"BAND",
	"BCOM",
	"BOR",
	"BXOR",
	"DIV",
	"MUL",
	"EQ",
	"GE",
	"GT",
	"LE",
	"LT",
	"NE",
	"JUMP",
	"LABEL",
	"AND",
	"NOT",
	"OR",
	"COND",
	"RIGHT",
	"FIELD"
	}, typenames[] = " FDCSIUPVB";
#else
	static char *opnames[] = {
	"",
	"CONSTANT_",
	"ARGUMENT_",
	"ASIGN_",
	"FETCH_",
	"CHAR_TO_",
	"DOUBLE_TO_",
	"FLOAT_TO_",
	"INT_TO_",
	"POINTER_TO_",
	"SHORT_TO_",
	"UNS_TO_",
	"NEG_",
	"CALL_",
	"LOAD_",
	"RET_",
	"ADDR_GLOBAL_",
	"ADDR_PARAMETER_",
	"ADDR_LOCAL_",
	"ADD_",
	"SUB_",
	"LSH_",
	"MOD_",
	"RSH_",
	"BIT_AND_",
	"BIT_COMPLEMENT_",
	"BIT_OR_",
	"BIT_XOR_",
	"DIV_",
	"MUL_",
	"JEQ",
	"JGE",
	"JGT",
	"JLE",
	"JLT",
	"JNE",
	"JUMP",
	"LABEL",
	"AND",
	"NOT",
	"OR",
	"COND",
	"RIGHT",
	"FIELD"
	}, typenames[] = " FDCSIUPVB";
#endif
	char *name;

	if (opindex(op) > 0 && opindex(op) < NELEMS(opnames))
		name = opnames[opindex(op)];
	else
		name = stringd(opindex(op));
	if (op >= AND && op <= FIELD)
		return name;
	else if (optype(op) > 0 && optype(op) < sizeof (typenames) - 1)
		return stringf("%s%c", name, typenames[optype(op)]);
	else
		return stringf("%s+%d", name, optype(op));
}

int nodeid(Tree p)
{
	int i = 1;

	ids[nid].node = p;
	while (ids[i].node != p)
		i++;
	if (i == nid)
		ids[nid++].printed = 0;
	return i;
}

/* printed - return pointer to ids[id].printed */
int *printed(int id)
{
	if (id)
		return &ids[id].printed;
	nid = 1;
	return 0;
}

/* printtree - print tree p on fd */
void printtree(Tree p,int fd)
{
	(void)printed(0);
	printtree1(p, fd, 1);
}

/* printtree1 - recursively print tree p */
static void printtree1(Tree p,int fd,int lev)
{
	int i;
	static char blanks[] = "                                         ";

	if (p == 0 || *printed(i = nodeid(p)))
		return;
	fprint(fd, "#%d%s%s", i, &"   "[i < 10 ? 0 : i < 100 ? 1 : 2],
		&blanks[sizeof blanks - lev]);
	fprint(fd, "%s %t", opname(p->op), p->type);
	*printed(i) = 1;
	for (i = 0; i < NELEMS(p->kids); i++)
		if (p->kids[i])
			fprint(fd, " #%d", nodeid(p->kids[i]));
	if (p->op == FIELD && p->u.field)
		fprint(fd, " %s %d..%d", p->u.field->name,
			fieldsize(p->u.field) + fieldright(p->u.field), fieldright(p->u.field));
	else if (generic(p->op) == CNST)
		fprint(fd, " %s", vtoa(p->type, p->u.v));
	else if (p->u.sym)
		fprint(fd, " %s", p->u.sym->name);
	if (p->node)
		fprint(fd, " node=0x%x", p->node);
	fprint(fd, "\n");
	for (i = 0; i < NELEMS(p->kids); i++)
		printtree1(p->kids[i], fd, lev + 1);
}

⌨️ 快捷键说明

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