📄 cons.c
字号:
cmdline = NOLINE; } cmd->c_filestab = curcmd->c_filestab; cmd->c_stash = curstash; if (perldb) cmd = dodb(cmd); return cmd;}CMD *make_ccmd(type,debuggable,arg,cblock)int type;int debuggable;ARG *arg;struct compcmd cblock;{ register CMD *cmd; Newz(108,cmd, 1, CMD); cmd->c_type = type; cmd->c_expr = arg; cmd->ucmd.ccmd.cc_true = cblock.comp_true; cmd->ucmd.ccmd.cc_alt = cblock.comp_alt; if (arg) cmd->c_flags |= CF_COND; if (cmdline == NOLINE) cmd->c_line = curcmd->c_line; else { cmd->c_line = cmdline; cmdline = NOLINE; } cmd->c_filestab = curcmd->c_filestab; cmd->c_stash = curstash; if (perldb && debuggable) cmd = dodb(cmd); return cmd;}CMD *make_icmd(type,arg,cblock)int type;ARG *arg;struct compcmd cblock;{ register CMD *cmd; register CMD *alt; register CMD *cur; register CMD *head; struct compcmd ncblock; Newz(109,cmd, 1, CMD); head = cmd; cmd->c_type = type; cmd->c_expr = arg; cmd->ucmd.ccmd.cc_true = cblock.comp_true; cmd->ucmd.ccmd.cc_alt = cblock.comp_alt; if (arg) cmd->c_flags |= CF_COND; if (cmdline == NOLINE) cmd->c_line = curcmd->c_line; else { cmd->c_line = cmdline; cmdline = NOLINE; } cmd->c_filestab = curcmd->c_filestab; cmd->c_stash = curstash; cur = cmd; alt = cblock.comp_alt; while (alt && alt->c_type == C_ELSIF) { cur = alt; alt = alt->ucmd.ccmd.cc_alt; } if (alt) { /* a real life ELSE at the end? */ ncblock.comp_true = alt; ncblock.comp_alt = Nullcmd; alt = append_line(cur,make_ccmd(C_ELSE,1,Nullarg,ncblock)); cur->ucmd.ccmd.cc_alt = alt; } else alt = cur; /* no ELSE, so cur is proxy ELSE */ cur = cmd; while (cmd) { /* now point everyone at the ELSE */ cur = cmd; cmd = cur->ucmd.ccmd.cc_alt; cur->c_head = head; if (cur->c_type == C_ELSIF) cur->c_type = C_IF; if (cur->c_type == C_IF) cur->ucmd.ccmd.cc_alt = alt; if (cur == alt) break; cur->c_next = cmd; } if (perldb) cur = dodb(cur); return cur;}voidopt_arg(cmd,fliporflop,acmd)register CMD *cmd;int fliporflop;int acmd;{ register ARG *arg; int opt = CFT_EVAL; int sure = 0; ARG *arg2; int context = 0; /* 0 = normal, 1 = before &&, 2 = before || */ int flp = fliporflop; if (!cmd) return; if (!(arg = cmd->c_expr)) { cmd->c_flags &= ~CF_COND; return; } /* Can we turn && and || into if and unless? */ if (acmd && !cmd->ucmd.acmd.ac_expr && !(cmd->c_flags & CF_TERM) && (arg->arg_type == O_AND || arg->arg_type == O_OR) ) { dehoist(arg,1); arg[2].arg_type &= A_MASK; /* don't suppress eval */ dehoist(arg,2); cmd->ucmd.acmd.ac_expr = arg[2].arg_ptr.arg_arg; cmd->c_expr = arg[1].arg_ptr.arg_arg; if (arg->arg_type == O_OR) cmd->c_flags ^= CF_INVERT; /* || is like unless */ arg->arg_len = 0; free_arg(arg); arg = cmd->c_expr; } /* Turn "if (!expr)" into "unless (expr)" */ if (!(cmd->c_flags & CF_TERM)) { /* unless return value wanted */ while (arg->arg_type == O_NOT) { dehoist(arg,1); cmd->c_flags ^= CF_INVERT; /* flip sense of cmd */ cmd->c_expr = arg[1].arg_ptr.arg_arg; /* hoist the rest of expr */ free_arg(arg); arg = cmd->c_expr; /* here we go again */ } } if (!arg->arg_len) { /* sanity check */ cmd->c_flags |= opt; return; } /* for "cond .. cond" we set up for the initial check */ if (arg->arg_type == O_FLIP) context |= 4; /* for "cond && expr" and "cond || expr" we can ignore expr, sort of */ morecontext: if (arg->arg_type == O_AND) context |= 1; else if (arg->arg_type == O_OR) context |= 2; if (context && (arg[flp].arg_type & A_MASK) == A_EXPR) { arg = arg[flp].arg_ptr.arg_arg; flp = 1; if (arg->arg_type == O_AND || arg->arg_type == O_OR) goto morecontext; } if ((context & 3) == 3) return; if (arg[flp].arg_flags & (AF_PRE|AF_POST)) { cmd->c_flags |= opt; if (acmd && !cmd->ucmd.acmd.ac_expr && !(cmd->c_flags & CF_TERM) && cmd->c_expr->arg_type == O_ITEM) { arg[flp].arg_flags &= ~AF_POST; /* prefer ++$foo to $foo++ */ arg[flp].arg_flags |= AF_PRE; /* if value not wanted */ } return; /* side effect, can't optimize */ } if (arg->arg_type == O_ITEM || arg->arg_type == O_FLIP || arg->arg_type == O_AND || arg->arg_type == O_OR) { if ((arg[flp].arg_type & A_MASK) == A_SINGLE) { opt = (str_true(arg[flp].arg_ptr.arg_str) ? CFT_TRUE : CFT_FALSE); cmd->c_short = str_smake(arg[flp].arg_ptr.arg_str); goto literal; } else if ((arg[flp].arg_type & A_MASK) == A_STAB || (arg[flp].arg_type & A_MASK) == A_LVAL) { cmd->c_stab = arg[flp].arg_ptr.arg_stab; if (!context) arg[flp].arg_ptr.arg_stab = Nullstab; opt = CFT_REG; literal: if (!context) { /* no && or ||? */ arg_free(arg); cmd->c_expr = Nullarg; } if (!(context & 1)) cmd->c_flags |= CF_EQSURE; if (!(context & 2)) cmd->c_flags |= CF_NESURE; } } else if (arg->arg_type == O_MATCH || arg->arg_type == O_SUBST || arg->arg_type == O_NMATCH || arg->arg_type == O_NSUBST) { if ((arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) && (arg[2].arg_type & A_MASK) == A_SPAT && arg[2].arg_ptr.arg_spat->spat_short && (arg->arg_type == O_SUBST || arg->arg_type == O_NSUBST || (arg[2].arg_ptr.arg_spat->spat_flags & SPAT_GLOBAL) == 0 )) { cmd->c_stab = arg[1].arg_ptr.arg_stab; cmd->c_short = str_smake(arg[2].arg_ptr.arg_spat->spat_short); cmd->c_slen = arg[2].arg_ptr.arg_spat->spat_slen; if (arg[2].arg_ptr.arg_spat->spat_flags & SPAT_ALL && !(arg[2].arg_ptr.arg_spat->spat_flags & SPAT_ONCE) && (arg->arg_type == O_MATCH || arg->arg_type == O_NMATCH) ) sure |= CF_EQSURE; /* (SUBST must be forced even */ /* if we know it will work.) */ if (arg->arg_type != O_SUBST) { str_free(arg[2].arg_ptr.arg_spat->spat_short); arg[2].arg_ptr.arg_spat->spat_short = Nullstr; arg[2].arg_ptr.arg_spat->spat_slen = 0; /* only one chk */ } sure |= CF_NESURE; /* normally only sure if it fails */ if (arg->arg_type == O_NMATCH || arg->arg_type == O_NSUBST) cmd->c_flags |= CF_FIRSTNEG; if (context & 1) { /* only sure if thing is false */ if (cmd->c_flags & CF_FIRSTNEG) sure &= ~CF_NESURE; else sure &= ~CF_EQSURE; } else if (context & 2) { /* only sure if thing is true */ if (cmd->c_flags & CF_FIRSTNEG) sure &= ~CF_EQSURE; else sure &= ~CF_NESURE; } if (sure & (CF_EQSURE|CF_NESURE)) { /* if we know anything*/ if (arg[2].arg_ptr.arg_spat->spat_flags & SPAT_SCANFIRST) opt = CFT_SCAN; else opt = CFT_ANCHOR; if (sure == (CF_EQSURE|CF_NESURE) /* really sure? */ && arg->arg_type == O_MATCH && context & 4 && fliporflop == 1) { spat_free(arg[2].arg_ptr.arg_spat); arg[2].arg_ptr.arg_spat = Nullspat; /* don't do twice */ } else cmd->c_spat = arg[2].arg_ptr.arg_spat; cmd->c_flags |= sure; } } } else if (arg->arg_type == O_SEQ || arg->arg_type == O_SNE || arg->arg_type == O_SLT || arg->arg_type == O_SGT) { if (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) { if (arg[2].arg_type == A_SINGLE) { /*SUPPRESS 594*/ char *junk = str_get(arg[2].arg_ptr.arg_str); cmd->c_stab = arg[1].arg_ptr.arg_stab; cmd->c_short = str_smake(arg[2].arg_ptr.arg_str); cmd->c_slen = cmd->c_short->str_cur+1; switch (arg->arg_type) { case O_SLT: case O_SGT: sure |= CF_EQSURE; cmd->c_flags |= CF_FIRSTNEG; break; case O_SNE: cmd->c_flags |= CF_FIRSTNEG; /* FALL THROUGH */ case O_SEQ: sure |= CF_NESURE|CF_EQSURE; break; } if (context & 1) { /* only sure if thing is false */ if (cmd->c_flags & CF_FIRSTNEG) sure &= ~CF_NESURE; else sure &= ~CF_EQSURE; } else if (context & 2) { /* only sure if thing is true */ if (cmd->c_flags & CF_FIRSTNEG) sure &= ~CF_EQSURE; else sure &= ~CF_NESURE; } if (sure & (CF_EQSURE|CF_NESURE)) { opt = CFT_STROP; cmd->c_flags |= sure; } } } } else if (arg->arg_type == O_EQ || arg->arg_type == O_NE || arg->arg_type == O_LE || arg->arg_type == O_GE || arg->arg_type == O_LT || arg->arg_type == O_GT) { if (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) { if (arg[2].arg_type == A_SINGLE) { cmd->c_stab = arg[1].arg_ptr.arg_stab; if (dowarn) { STR *str = arg[2].arg_ptr.arg_str; if ((!str->str_nok && !looks_like_number(str))) warn("Possible use of == on string value"); } cmd->c_short = str_nmake(str_gnum(arg[2].arg_ptr.arg_str)); cmd->c_slen = arg->arg_type; sure |= CF_NESURE|CF_EQSURE; if (context & 1) { /* only sure if thing is false */ sure &= ~CF_EQSURE; } else if (context & 2) { /* only sure if thing is true */ sure &= ~CF_NESURE; } if (sure & (CF_EQSURE|CF_NESURE)) { opt = CFT_NUMOP; cmd->c_flags |= sure; } } } } else if (arg->arg_type == O_ASSIGN && (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) && arg[1].arg_ptr.arg_stab == defstab && arg[2].arg_type == A_EXPR ) { arg2 = arg[2].arg_ptr.arg_arg; if (arg2->arg_type == O_ITEM && arg2[1].arg_type == A_READ) { opt = CFT_GETS; cmd->c_stab = arg2[1].arg_ptr.arg_stab; if (!(stab_io(arg2[1].arg_ptr.arg_stab)->flags & IOF_ARGV)) { free_arg(arg2); arg[2].arg_ptr.arg_arg = Nullarg; free_arg(arg); cmd->c_expr = Nullarg; } } } else if (arg->arg_type == O_CHOP && (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) ) { opt = CFT_CHOP; cmd->c_stab = arg[1].arg_ptr.arg_stab; free_arg(arg); cmd->c_expr = Nullarg; } if (context & 4) opt |= CF_FLIP; cmd->c_flags |= opt; if (cmd->c_flags & CF_FLIP) { if (fliporflop == 1) { arg = cmd->c_expr; /* get back to O_FLIP arg */ New(110,arg[3].arg_ptr.arg_cmd, 1, CMD); Copy(cmd, arg[3].arg_ptr.arg_cmd, 1, CMD); New(111,arg[4].arg_ptr.arg_cmd,1,CMD); Copy(cmd, arg[4].arg_ptr.arg_cmd, 1, CMD); opt_arg(arg[4].arg_ptr.arg_cmd,2,acmd); arg->arg_len = 2; /* this is a lie */ } else { if ((opt & CF_OPTIMIZE) == CFT_EVAL) cmd->c_flags = (cmd->c_flags & ~CF_OPTIMIZE) | CFT_UNFLIP; } }}CMD *add_label(lbl,cmd)char *lbl;register CMD *cmd;{ if (cmd) cmd->c_label = lbl; return cmd;}CMD *addcond(cmd, arg)register CMD *cmd;register ARG *arg;{ cmd->c_expr = arg; cmd->c_flags |= CF_COND; return cmd;}CMD *addloop(cmd, arg)register CMD *cmd;register ARG *arg;{ void while_io(); cmd->c_expr = arg; cmd->c_flags |= CF_COND|CF_LOOP; if (!(cmd->c_flags & CF_INVERT)) while_io(cmd); /* add $_ =, if necessary */ if (cmd->c_type == C_BLOCK) cmd->c_flags &= ~CF_COND; else { arg = cmd->ucmd.acmd.ac_expr; if (arg && arg->arg_type == O_ITEM && arg[1].arg_type == A_CMD) cmd->c_flags &= ~CF_COND; /* "do {} while" happens at least once */ if (arg && (arg->arg_flags & AF_DEPR) && (arg->arg_type == O_SUBR || arg->arg_type == O_DBSUBR) ) cmd->c_flags &= ~CF_COND; /* likewise for "do subr() while" */ } return cmd;}CMD *invert(cmd)CMD *cmd;{ register CMD *targ = cmd; if (targ->c_head) targ = targ->c_head; if (targ->c_flags & CF_DBSUB) targ = targ->c_next; targ->c_flags ^= CF_INVERT; return cmd;}voidcpy7bit(d,s,l)register char *d;register char *s;register int l;{ while (l--) *d++ = *s++ & 127; *d = '\0';}intyyerror(s)char *s;{ char tmpbuf[258]; char tmp2buf[258]; char *tname = tmpbuf; if (bufptr > oldoldbufptr && bufptr - oldoldbufptr < 200 && oldoldbufptr != oldbufptr && oldbufptr != bufptr) { while (isSPACE(*oldoldbufptr)) oldoldbufptr++; cpy7bit(tmp2buf, oldoldbufptr, bufptr - oldoldbufptr); sprintf(tname,"next 2 tokens \"%s\"",tmp2buf); } else if (bufptr > oldbufptr && bufptr - oldbufptr < 200 && oldbufptr != bufptr) { while (isSPACE(*oldbufptr)) oldbufptr++; cpy7bit(tmp2buf, oldbufptr, bufptr - oldbufptr); sprintf(tname,"next token \"%s\"",tmp2buf); } else if (yychar > 256) tname = "next token ???"; else if (!yychar) (void)strcpy(tname,"at EOF"); else if (yychar < 32) (void)sprintf(tname,"next char ^%c",yychar+64); else if (yychar == 127) (void)strcpy(tname,"at EOF"); else (void)sprintf(tname,"next char %c",yychar); (void)sprintf(buf, "%s in file %s at line %d, %s\n", s,stab_val(curcmd->c_filestab)->str_ptr,curcmd->c_line,tname); if (curcmd->c_line == multi_end && multi_start < multi_end) sprintf(buf+strlen(buf), " (Might be a runaway multi-line %c%c string starting on line %d)\n", multi_open,multi_close,multi_start); if (in_eval) str_cat(stab_val(stabent("@",TRUE)),buf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -