📄 tree.c
字号:
if(p->nodetype == t_vquad) { beginerrmsg(); fprintf(stderr, "can not take address of \""); prtree(stderr, p); fprintf(stderr, "\""); enderrmsg(); /* NOTREACHED */ } else { beginerrmsg(); fprintf(stderr, "expected variable, found \""); prtree(stderr, p); fprintf(stderr, "\""); tfree(p); enderrmsg(); /* NOTREACHED */ } } return r;}/* * Create a "concrete" version of a node. * This is necessary when the type of the node contains * an unresolved type reference. */public Node concrete(p)Node p;{ findtype(p->nodetype); return build(O_INDIR, p);}/* * Create a command list from a single command. */public Cmdlist buildcmdlist(cmd)Command cmd;{ Cmdlist cmdlist; cmdlist = list_alloc(); cmdlist_append(cmd, cmdlist); return cmdlist;}/* * Print out a command. */public printcmd(f, cmd)File f;Command cmd;{ register Integer i; register Command c; register Node p; switch (cmd->op) { case O_PRINTIFCHANGED: case O_PRINTSRCPOS: case O_PRINTENTRY: case O_STOPIFCHANGED: case O_TRACEON: case O_PRINTF: break; case O_STEPV: if (cmd->value.step.skipcalls) { fprintf(f, "nextv"); } else { fprintf(f, "stepv"); } break; case O_STEP: if (cmd->value.step.skipcalls) { fprintf(f, "next"); } else { fprintf(f, "step"); } if (not cmd->value.step.source) { fprintf(f, "i"); } break; default: fprintf(f, "%s", opinfo[ord(cmd->op)].opstring); if (nargs(cmd->op) != 0) { fprintf(f, " "); } break; } switch (cmd->op) { case O_PRINTCALL: case O_PRINTRTN: case O_PROCRTN: fprintf(f, "%s", symname(cmd->value.sym)); break; case O_PRINTSRCPOS: p = cmd->value.arg[0]; if (p != nil and p->op != O_QLINE) { printf("trace "); prtree(f, p); } break; case O_CHFILE: case O_EDIT: case O_SOURCE: case O_RECORD: fprintf(f, "%s", cmd->value.scon); break; case O_CATCH: case O_IGNORE: case O_TRACEOFF: fprintf(f, "%d", cmd->value.lcon); break; case O_ADDEVENT: case O_ONCE: case O_IF: fprintf(f, " "); prtree(f, cmd->value.event.cond); fprintf(f, " { "); foreach (Command, c, cmd->value.event.actions) printcmd(f, c); if (not list_islast()) { fprintf(f, ";"); } endfor fprintf(f, " }", opinfo[ord(cmd->op)].opstring); break; case O_PRINTENTRY: case O_TRACEON: print_tracestop(f, cmd); break; case O_PRINTF: if (cmd->value.arg[1] != nil) { switch (language_suffix(cmd->value.printform.lang)[1]) { default: case 'c': fprintf (f, "printf "); break; case 'p': fprintf (f, "writeln "); break; case 'f': fprintf (f, "write "); break; } } prtree(f, cmd->value.arg[0]); break; case O_EXAMINE: prtree(f, cmd->value.examine.beginaddr); if (cmd->value.examine.endaddr != nil) { fprintf(f, ","); prtree(f, cmd->value.examine.endaddr); } fprintf(f, "/"); if (cmd->value.examine.count > 1) { fprintf(f, "%d", cmd->value.examine.count); } fprintf("%s", cmd->value.examine.mode); break; default: if (nargs(cmd->op) != 0) { i = 0; for (;;) { prtree(f, cmd->value.arg[i]); ++i; if (i >= nargs(cmd->op)) break; fprintf(f, " "); } } break; }}/* * Print out a trace/stop command name. */#define fprintI(f, b) { if (b) fprintf(f, "i"); }private print_tracestop(f, cmd)File f;Command cmd;{ register Command c, ifcmd, stopcmd; Boolean done; done = false; ifcmd = list_element(Command, list_head(cmd->value.trace.actions)); checkref(ifcmd); if (ifcmd->op == O_IF) { stopcmd = list_element(Command, list_head(ifcmd->value.event.actions)); checkref(stopcmd); if (stopcmd->op == O_STOPX) { fprintf(f, "stop"); fprintI(f, cmd->value.trace.inst); fprintf(f, " if "); prtree(f, ifcmd->value.event.cond); done = true; } } else if (ifcmd->op == O_STOPIFCHANGED) { fprintf(f, "stop"); fprintI(f, cmd->value.trace.inst); fprintf(f, " "); prtree(f, ifcmd->value.arg[0]); done = true; } if (not done) { fprintf(f, "%s ", cmd->value.trace.inst ? "tracei" : "trace"); foreach (Command, c, cmd->value.trace.actions) printcmd(f, c); if (not list_islast()) { fprintf(f, ";"); } endfor }}/* * Print out a tree. */public prtree(f, p)File f;register Node p;{ register Node q; Operator op; if (p != nil) { op = p->op; if (ord(op) > ord(O_LASTOP)) { panic("bad op %d in prtree", p->op); } switch (op) { case O_NAME: fprintf(f, "%s", ident(p->value.name)); break; case O_SYM: case O_VREG: printname(f, p->value.sym); break; case O_QLINE: if (nlhdr.nfiles > 1) { prtree(f, p->value.arg[0]); fprintf(f, ":"); } prtree(f, p->value.arg[1]); break; case O_LCON: fprintf(f, "%d", p->value.lcon); break; case O_CCON: fprintf(f, "'%c'", p->value.lcon); break; case O_FCON: fprintf(f, "%g", p->value.fcon); break; case O_SCON: fprintf(f, "\"%s\"", p->value.scon); break; case O_INDEX: prtree(f, p->value.arg[0]); fprintf(f, "["); prtree(f, p->value.arg[1]); fprintf(f, "]"); break; case O_COMMA: prtree(f, p->value.arg[0]); if (p->value.arg[1] != nil) { fprintf(f, ", "); prtree(f, p->value.arg[1]); } break; case O_RVAL: case O_ITOF: prtree(f, p->value.arg[0]); break; case O_CALL: prtree(f, p->value.arg[0]); if (p->value.arg[1]!= nil) { fprintf(f, "("); prtree(f, p->value.arg[1]); fprintf(f, ")"); } break; case O_INDIR: prtree(f, p->value.arg[0]); fprintf(f, "^"); break; case O_DOT: prtree(f, p->value.arg[0]); fprintf(f, ".%s", symname(p->value.arg[1]->value.sym)); break; case O_TYPERENAME: prtree(f, p->value.arg[1]); fprintf(f, "("); prtree(f, p->value.arg[0]); fprintf(f, ")"); break; default: switch (degree(op)) { case BINARY: prtree(f, p->value.arg[0]); fprintf(f, "%s", opinfo[ord(op)].opstring); prtree(f, p->value.arg[1]); break; case UNARY: fprintf(f, "%s", opinfo[ord(op)].opstring); prtree(f, p->value.arg[0]); break; default: if (opinfo[ord(op)].opstring == nil) { fprintf(f, "[op %d]", ord(op)); } else { fprintf(f, "%s", opinfo[ord(op)].opstring); } break; } break; } }}/* * Free storage associated with a tree. */public tfree(p)Node p;{ Integer i; if (p == nil) { return; } switch (p->op) { case O_QLINE: dispose(p->value.arg[0]->value.scon); dispose(p->value.arg[0]); tfree(p->value.arg[1]); break; case O_SCON: unmkstring(p->nodetype); dispose(p->nodetype); dispose(p->value.scon); break; default: for (i = 0; i < nargs(p->op); i++) { tfree(p->value.arg[i]); } break; } dispose(p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -