📄 consarg.c
字号:
{ int zapc; char *zaps; zaps = str_get(s1); zapc = (int) *zaps; str_numset(str,(double)(zapc)); }#endif break; } arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */ str_free(s1); arg[1].arg_ptr.arg_str = str; if (s2) { str_free(s2); arg[2].arg_ptr.arg_str = Nullstr; arg[2].arg_type = A_NULL; } str = Nullstr; return arg;}ARG *l(arg)register ARG *arg;{ register int i; register ARG *arg1; register ARG *arg2; SPAT *spat; int arghog = 0; i = arg[1].arg_type & A_MASK; arg->arg_flags |= AF_COMMON; /* assume something in common */ /* which forces us to copy things */ if (i == A_ARYLEN) { arg[1].arg_type = A_LARYLEN; return arg; } if (i == A_ARYSTAB) { arg[1].arg_type = A_LARYSTAB; return arg; } /* see if it's an array reference */ if (i == A_EXPR || i == A_LEXPR) { arg1 = arg[1].arg_ptr.arg_arg; if (arg1->arg_type == O_LIST || arg1->arg_type == O_ITEM) { /* assign to list */ if (arg->arg_len > 1) { dehoist(arg,2); arg2 = arg[2].arg_ptr.arg_arg; if (nothing_in_common(arg1,arg2)) arg->arg_flags &= ~AF_COMMON; if (arg->arg_type == O_ASSIGN) { if (arg1->arg_flags & AF_LOCAL) arg->arg_flags |= AF_LOCAL; arg[1].arg_flags |= AF_ARYOK; arg[2].arg_flags |= AF_ARYOK; } } else if (arg->arg_type != O_CHOP) arg->arg_type = O_ASSIGN; /* possible local(); */ for (i = arg1->arg_len; i >= 1; i--) { switch (arg1[i].arg_type) { case A_STAR: case A_LSTAR: arg1[i].arg_type = A_LSTAR; break; case A_STAB: case A_LVAL: arg1[i].arg_type = A_LVAL; break; case A_ARYLEN: case A_LARYLEN: arg1[i].arg_type = A_LARYLEN; break; case A_ARYSTAB: case A_LARYSTAB: arg1[i].arg_type = A_LARYSTAB; break; case A_EXPR: case A_LEXPR: arg1[i].arg_type = A_LEXPR; switch(arg1[i].arg_ptr.arg_arg->arg_type) { case O_ARRAY: case O_LARRAY: arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY; arghog = 1; break; case O_AELEM: case O_LAELEM: arg1[i].arg_ptr.arg_arg->arg_type = O_LAELEM; break; case O_HASH: case O_LHASH: arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH; arghog = 1; break; case O_HELEM: case O_LHELEM: arg1[i].arg_ptr.arg_arg->arg_type = O_LHELEM; break; case O_ASLICE: case O_LASLICE: arg1[i].arg_ptr.arg_arg->arg_type = O_LASLICE; break; case O_HSLICE: case O_LHSLICE: arg1[i].arg_ptr.arg_arg->arg_type = O_LHSLICE; break; case O_SUBSTR: case O_VEC: (void)l(arg1[i].arg_ptr.arg_arg); Renewc(arg1[i].arg_ptr.arg_arg->arg_ptr.arg_str, 1, struct lstring, STR); /* grow string struct to hold an lstring struct */ break; default: goto ill_item; } break; default: ill_item: (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue", argname[arg1[i].arg_type&A_MASK]); yyerror(tokenbuf); } } if (arg->arg_len > 1) { if (arg2->arg_type == O_SPLIT && !arg2[3].arg_type && !arghog) { arg2[3].arg_type = A_SINGLE; arg2[3].arg_ptr.arg_str = str_nmake((double)arg1->arg_len + 1); /* limit split len*/ } } } else if (arg1->arg_type == O_AELEM || arg1->arg_type == O_LAELEM) if (arg->arg_type == O_DEFINED) arg1->arg_type = O_AELEM; else arg1->arg_type = O_LAELEM; else if (arg1->arg_type == O_ARRAY || arg1->arg_type == O_LARRAY) { arg1->arg_type = O_LARRAY; if (arg->arg_len > 1) { dehoist(arg,2); arg2 = arg[2].arg_ptr.arg_arg; if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/ spat = arg2[2].arg_ptr.arg_spat; if (!(spat->spat_flags & SPAT_ONCE) && nothing_in_common(arg1,spat->spat_repl)) { spat->spat_repl[1].arg_ptr.arg_stab = arg1[1].arg_ptr.arg_stab; arg1[1].arg_ptr.arg_stab = Nullstab; spat->spat_flags |= SPAT_ONCE; arg_free(arg1); /* recursive */ arg[1].arg_ptr.arg_arg = Nullarg; free_arg(arg); /* non-recursive */ return arg2; /* split has builtin assign */ } } else if (nothing_in_common(arg1,arg2)) arg->arg_flags &= ~AF_COMMON; if (arg->arg_type == O_ASSIGN) { arg[1].arg_flags |= AF_ARYOK; arg[2].arg_flags |= AF_ARYOK; } } else if (arg->arg_type == O_ASSIGN) arg[1].arg_flags |= AF_ARYOK; } else if (arg1->arg_type == O_HELEM || arg1->arg_type == O_LHELEM) if (arg->arg_type == O_DEFINED) arg1->arg_type = O_HELEM; /* avoid creating one */ else arg1->arg_type = O_LHELEM; else if (arg1->arg_type == O_HASH || arg1->arg_type == O_LHASH) { arg1->arg_type = O_LHASH; if (arg->arg_len > 1) { dehoist(arg,2); arg2 = arg[2].arg_ptr.arg_arg; if (nothing_in_common(arg1,arg2)) arg->arg_flags &= ~AF_COMMON; if (arg->arg_type == O_ASSIGN) { arg[1].arg_flags |= AF_ARYOK; arg[2].arg_flags |= AF_ARYOK; } } else if (arg->arg_type == O_ASSIGN) arg[1].arg_flags |= AF_ARYOK; } else if (arg1->arg_type == O_ASLICE) { arg1->arg_type = O_LASLICE; if (arg->arg_type == O_ASSIGN) { dehoist(arg,2); arg[1].arg_flags |= AF_ARYOK; arg[2].arg_flags |= AF_ARYOK; } } else if (arg1->arg_type == O_HSLICE) { arg1->arg_type = O_LHSLICE; if (arg->arg_type == O_ASSIGN) { dehoist(arg,2); arg[1].arg_flags |= AF_ARYOK; arg[2].arg_flags |= AF_ARYOK; } } else if ((arg->arg_type == O_DEFINED || arg->arg_type == O_UNDEF) && (arg1->arg_type == (perldb ? O_DBSUBR : O_SUBR)) ) { arg[1].arg_type |= A_DONT; } else if (arg1->arg_type == O_SUBSTR || arg1->arg_type == O_VEC) { (void)l(arg1); Renewc(arg1->arg_ptr.arg_str, 1, struct lstring, STR); /* grow string struct to hold an lstring struct */ } else if (arg1->arg_type == O_ASSIGN) /*SUPPRESS 530*/ ; else { (void)sprintf(tokenbuf, "Illegal expression (%s) as lvalue",opname[arg1->arg_type]); yyerror(tokenbuf); return arg; } arg[1].arg_type = A_LEXPR | (arg[1].arg_type & A_DONT); if (arg->arg_type == O_ASSIGN && (arg1[1].arg_flags & AF_ARYOK)) { arg[1].arg_flags |= AF_ARYOK; if (arg->arg_len > 1) arg[2].arg_flags |= AF_ARYOK; }#ifdef DEBUGGING if (debug & 16) fprintf(stderr,"lval LEXPR\n");#endif return arg; } if (i == A_STAR || i == A_LSTAR) { arg[1].arg_type = A_LSTAR | (arg[1].arg_type & A_DONT); return arg; } /* not an array reference, should be a register name */ if (i != A_STAB && i != A_LVAL) { (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue",argname[arg[1].arg_type&A_MASK]); yyerror(tokenbuf); return arg; } arg[1].arg_type = A_LVAL | (arg[1].arg_type & A_DONT);#ifdef DEBUGGING if (debug & 16) fprintf(stderr,"lval LVAL\n");#endif return arg;}ARG *fixl(type,arg)int type;ARG *arg;{ if (type == O_DEFINED || type == O_UNDEF) { if (arg->arg_type != O_ITEM) arg = hide_ary(arg); if (arg->arg_type == O_ITEM) { type = arg[1].arg_type & A_MASK; if (type == A_EXPR || type == A_LEXPR) arg[1].arg_type = A_LEXPR|A_DONT; } } return arg;}voiddehoist(arg,i)ARG *arg;{ ARG *tmparg; if (arg[i].arg_type != A_EXPR) { /* dehoist */ tmparg = make_op(O_ITEM,1,Nullarg,Nullarg,Nullarg); tmparg[1] = arg[i]; arg[i].arg_ptr.arg_arg = tmparg; arg[i].arg_type = A_EXPR; }}ARG *addflags(i,flags,arg)register ARG *arg;{ arg[i].arg_flags |= flags; return arg;}ARG *hide_ary(arg)ARG *arg;{ if (arg->arg_type == O_ARRAY || arg->arg_type == O_HASH) return make_op(O_ITEM,1,arg,Nullarg,Nullarg); return arg;}/* maybe do a join on multiple array dimensions */ARG *jmaybe(arg)register ARG *arg;{ if (arg && arg->arg_type == O_COMMA) { arg = listish(arg); arg = make_op(O_JOIN, 2, stab2arg(A_STAB,stabent(";",TRUE)), make_list(arg), Nullarg); } return arg;}ARG *make_list(arg)register ARG *arg;{ register int i; register ARG *node; register ARG *nxtnode; register int j; STR *tmpstr; if (!arg) { arg = op_new(0); arg->arg_type = O_LIST; } if (arg->arg_type != O_COMMA) { if (arg->arg_type != O_ARRAY) arg->arg_flags |= AF_LISTISH; /* see listish() below */ arg->arg_flags |= AF_LISTISH; /* see listish() below */ return arg; } for (i = 2, node = arg; ; i++) { if (node->arg_len < 2) break; if (node[1].arg_type != A_EXPR) break; node = node[1].arg_ptr.arg_arg; if (node->arg_type != O_COMMA) break; } if (i > 2) { node = arg; arg = op_new(i); tmpstr = arg->arg_ptr.arg_str; StructCopy(node, arg, ARG); /* copy everything except the STR */ arg->arg_ptr.arg_str = tmpstr; for (j = i; ; ) { StructCopy(node+2, arg+j, ARG); arg[j].arg_flags |= AF_ARYOK; --j; /* Bug in Xenix compiler */ if (j < 2) { StructCopy(node+1, arg+1, ARG); free_arg(node); break; } nxtnode = node[1].arg_ptr.arg_arg; free_arg(node); node = nxtnode; } } arg[1].arg_flags |= AF_ARYOK; arg[2].arg_flags |= AF_ARYOK; arg->arg_type = O_LIST; arg->arg_len = i; str_free(arg->arg_ptr.arg_str); arg->arg_ptr.arg_str = Nullstr; return arg;}/* turn a single item into a list */ARG *listish(arg)ARG *arg;{ if (arg && arg->arg_flags & AF_LISTISH) arg = make_op(O_LIST,1,arg,Nullarg,Nullarg); return arg;}ARG *maybelistish(optype, arg)int optype;ARG *arg;{ ARG *tmparg = arg; if (optype == O_RETURN && arg->arg_type == O_ITEM && arg[1].arg_type == A_EXPR && (tmparg = arg[1].arg_ptr.arg_arg) && ((tmparg->arg_flags & AF_LISTISH) || (tmparg->arg_type == O_ARRAY) )) { tmparg = listish(tmparg); free_arg(arg); arg = tmparg; } else if (optype == O_PRTF || (arg->arg_type == O_ASLICE || arg->arg_type == O_HSLICE || arg->arg_type == O_F_OR_R) ) arg = listish(arg); return arg;}/* mark list of local variables */ARG *localize(arg)ARG *arg;{ arg->arg_flags |= AF_LOCAL; return arg;}ARG *rcatmaybe(arg)ARG *arg;{ ARG *arg2; if (arg->arg_type == O_CONCAT && 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) { arg->arg_type = O_RCAT; arg[2].arg_type = arg2[1].arg_type; arg[2].arg_ptr = arg2[1].arg_ptr; free_arg(arg2); } } return arg;}ARG *stab2arg(atype,stab)int atype;register STAB *stab;{ register ARG *arg; arg = op_new(1); arg->arg_type = O_ITEM; arg[1].arg_type = atype; arg[1].arg_ptr.arg_stab = stab; return arg;}ARG *cval_to_arg(cval)register char *cval;{ register ARG *arg; arg = op_new(1); arg->arg_type = O_ITEM; arg[1].arg_type = A_SINGLE; arg[1].arg_ptr.arg_str = str_make(cval,0); Safefree(cval); return arg;}ARG *op_new(numargs)int numargs;{ register ARG *arg; Newz(203,arg, numargs + 1, ARG); arg->arg_ptr.arg_str = Str_new(21,0); arg->arg_len = numargs; return arg;}voidfree_arg(arg)ARG *arg;{ str_free(arg->arg_ptr.arg_str); Safefree(arg);}ARG *make_match(type,expr,spat)int type;ARG *expr;SPAT *spat;{ register ARG *arg; arg = make_op(type,2,expr,Nullarg,Nullarg); arg[2].arg_type = A_SPAT|A_DONT; arg[2].arg_ptr.arg_spat = spat;#ifdef DEBUGGING if (debug & 16) fprintf(stderr,"make_match SPAT=%lx\n",(long)spat);#endif if (type == O_SUBST || type == O_NSUBST) { if (arg[1].arg_type != A_STAB) { yyerror("Illegal lvalue"); } arg[1].arg_type = A_LVAL; } return arg;}ARG *cmd_to_arg(cmd)CMD *cmd;{ register ARG *arg; arg = op_new(1); arg->arg_type = O_ITEM; arg[1].arg_type = A_CMD; arg[1].arg_ptr.arg_cmd = cmd; return arg;}/* Check two expressions to see if there is any identifier in common */static intnothing_in_common(arg1,arg2)ARG *arg1;ARG *arg2;{ static int thisexpr = 0; /* I don't care if this wraps */ thisexpr++; if (arg_common(arg1,thisexpr,1)) return 0; /* hit eval or do {} */ stab_lastexpr(defstab) = thisexpr; /* pretend to hit @_ */ if (arg_common(arg2,thisexpr,0)) return 0; /* hit identifier again */ return 1;}/* Recursively descend an expression and mark any identifier or check * it to see if it was marked already. */static intarg_common(arg,exprnum,marking)register ARG *arg;int exprnum;int marking;{ register int i; if (!arg) return 0; for (i = arg->arg_len; i >= 1; i--) { switch (arg[i].arg_type & A_MASK) { case A_NULL: break; case A_LEXPR: case A_EXPR: if (arg_common(arg[i].arg_ptr.arg_arg,exprnum,marking)) return 1; break; case A_CMD: return 1; /* assume hanky panky */ case A_STAR: case A_LSTAR: case A_STAB: case A_LVAL: case A_ARYLEN: case A_LARYLEN: if (marking) stab_lastexpr(arg[i].arg_ptr.arg_stab) = exprnum; else if (stab_lastexpr(arg[i].arg_ptr.arg_stab) == exprnum) return 1; break; case A_DOUBLE: case A_BACKTICK: { register char *s = arg[i].arg_ptr.arg_str->str_ptr; register char *send = s + arg[i].arg_ptr.arg_str->str_cur; register STAB *stab; while (*s) { if (*s == '$' && s[1]) { s = scanident(s,send,tokenbuf); stab = stabent(tokenbuf,TRUE); if (marking) stab_lastexpr(stab) = exprnum; else if (stab_lastexpr(stab) == exprnum) return 1; continue; } else if (*s == '\\' && s[1]) s++; s++; } } break; case A_SPAT: if (spat_common(arg[i].arg_ptr.arg_spat,exprnum,marking)) return 1; break; case A_READ: case A_INDREAD: case A_GLOB: case A_WORD: case A_SINGLE: break; } } switch (arg->arg_type) { case O_ARRAY: case O_LARRAY: if ((arg[1].arg_type & A_MASK) == A_STAB) (void)aadd(arg[1].arg_ptr.arg_stab); break; case O_HASH: case O_LHASH: if ((arg[1].arg_type & A_MASK) == A_STAB) (void)hadd(arg[1].arg_ptr.arg_stab); break; case O_EVAL: case O_SUBR: case O_DBSUBR: return 1; } return 0;}static intspat_common(spat,exprnum,marking)register SPAT *spat;int exprnum;int marking;{ if (spat->spat_runtime) if (arg_common(spat->spat_runtime,exprnum,marking)) return 1; if (spat->spat_repl) { if (arg_common(spat->spat_repl,exprnum,marking)) return 1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -