📄 eval.c
字号:
rslen = old_rslen;#ifdef DEBUGGING tmps = "READ";#endif break; }#ifdef DEBUGGING if (debug & 8) deb("%d.%s = '%s'\n",anum,tmps,str_peek(st[sp]));#endif if (anum < 8) arglast[anum] = sp; } st += arglast[0];#ifdef SMALLSWITCHES if (optype < O_CHOWN)#endif switch (optype) { case O_RCAT: STABSET(str); break; case O_ITEM: if (gimme == G_ARRAY) goto array_return; /* FALL THROUGH */ case O_SCALAR: STR_SSET(str,st[1]); STABSET(str); break; case O_ITEM2: if (gimme == G_ARRAY) goto array_return; --anum; STR_SSET(str,st[arglast[anum]-arglast[0]]); STABSET(str); break; case O_ITEM3: if (gimme == G_ARRAY) goto array_return; --anum; STR_SSET(str,st[arglast[anum]-arglast[0]]); STABSET(str); break; case O_CONCAT: STR_SSET(str,st[1]); str_scat(str,st[2]); STABSET(str); break; case O_REPEAT: if (gimme == G_ARRAY && arg[1].arg_flags & AF_ARYOK) { sp = do_repeatary(arglast); goto array_return; } STR_SSET(str,st[1]); anum = (int)str_gnum(st[2]); if (anum >= 1) { tmpstr = Str_new(50, 0); tmps = str_get(str); str_nset(tmpstr,tmps,str->str_cur); tmps = str_get(tmpstr); /* force to be string */ STR_GROW(str, (anum * str->str_cur) + 1); repeatcpy(str->str_ptr, tmps, tmpstr->str_cur, anum); str->str_cur *= anum; str->str_ptr[str->str_cur] = '\0'; str->str_nok = 0; str_free(tmpstr); } else { if (dowarn && st[2]->str_pok && !looks_like_number(st[2])) warn("Right operand of x is not numeric"); str_sset(str,&str_no); } STABSET(str); break; case O_MATCH: sp = do_match(str,arg, gimme,arglast); if (gimme == G_ARRAY) goto array_return; STABSET(str); break; case O_NMATCH: sp = do_match(str,arg, G_SCALAR,arglast); str_sset(str, str_true(str) ? &str_no : &str_yes); STABSET(str); break; case O_SUBST: sp = do_subst(str,arg,arglast[0]); goto array_return; case O_NSUBST: sp = do_subst(str,arg,arglast[0]); str = arg->arg_ptr.arg_str; str_set(str, str_true(str) ? No : Yes); goto array_return; case O_ASSIGN: if (arg[1].arg_flags & AF_ARYOK) { if (arg->arg_len == 1) { arg->arg_type = O_LOCAL; goto local; } else { arg->arg_type = O_AASSIGN; goto aassign; } } else { arg->arg_type = O_SASSIGN; goto sassign; } case O_LOCAL: local: arglast[2] = arglast[1]; /* push a null array */ /* FALL THROUGH */ case O_AASSIGN: aassign: sp = do_assign(arg, gimme,arglast); goto array_return; case O_SASSIGN: sassign:#ifdef TAINT if (tainted && !st[2]->str_tainted) tainted = 0;#endif STR_SSET(str, st[2]); STABSET(str); break; case O_CHOP: st -= arglast[0]; str = arg->arg_ptr.arg_str; for (sp = arglast[0] + 1; sp <= arglast[1]; sp++) do_chop(str,st[sp]); st += arglast[0]; break; case O_DEFINED: if (arg[1].arg_type & A_DONT) { sp = do_defined(str,arg, gimme,arglast); goto array_return; } else if (str->str_pok || str->str_nok) goto say_yes; goto say_no; case O_UNDEF: if (arg[1].arg_type & A_DONT) { sp = do_undef(str,arg, gimme,arglast); goto array_return; } else if (str != stab_val(defstab)) { if (str->str_len) { if (str->str_state == SS_INCR) Str_Grow(str,0); Safefree(str->str_ptr); str->str_ptr = Nullch; str->str_len = 0; } str->str_pok = str->str_nok = 0; STABSET(str); } goto say_undef; case O_STUDY: sp = do_study(str,arg, gimme,arglast); goto array_return; case O_POW: value = str_gnum(st[1]); value = pow(value,str_gnum(st[2])); goto donumset; case O_MULTIPLY: value = str_gnum(st[1]); value *= str_gnum(st[2]); goto donumset; case O_DIVIDE: if ((value = str_gnum(st[2])) == 0.0) fatal("Illegal division by zero");#ifdef SLOPPYDIVIDE /* insure that 20./5. == 4. */ { double x; int k; x = str_gnum(st[1]); if ((double)(int)x == x && (double)(int)value == value && (k = (int)x/(int)value)*(int)value == (int)x) { value = k; } else { value = x/value; } }#else value = str_gnum(st[1]) / value;#endif goto donumset; case O_MODULO: tmpulong = (unsigned long) str_gnum(st[2]); if (tmpulong == 0L) fatal("Illegal modulus zero");#ifndef lint value = str_gnum(st[1]); if (value >= 0.0) value = (double)(((unsigned long)value) % tmpulong); else { tmplong = (long)value; value = (double)(tmpulong - ((-tmplong - 1) % tmpulong)) - 1; }#endif goto donumset; case O_ADD: value = str_gnum(st[1]); value += str_gnum(st[2]); goto donumset; case O_SUBTRACT: value = str_gnum(st[1]); value -= str_gnum(st[2]); goto donumset; case O_LEFT_SHIFT: value = str_gnum(st[1]); anum = (int)str_gnum(st[2]);#ifndef lint value = (double)(U_L(value) << anum);#endif goto donumset; case O_RIGHT_SHIFT: value = str_gnum(st[1]); anum = (int)str_gnum(st[2]);#ifndef lint value = (double)(U_L(value) >> anum);#endif goto donumset; case O_LT: value = str_gnum(st[1]); value = (value < str_gnum(st[2])) ? 1.0 : 0.0; goto donumset; case O_GT: value = str_gnum(st[1]); value = (value > str_gnum(st[2])) ? 1.0 : 0.0; goto donumset; case O_LE: value = str_gnum(st[1]); value = (value <= str_gnum(st[2])) ? 1.0 : 0.0; goto donumset; case O_GE: value = str_gnum(st[1]); value = (value >= str_gnum(st[2])) ? 1.0 : 0.0; goto donumset; case O_EQ: if (dowarn) { if ((!st[1]->str_nok && !looks_like_number(st[1])) || (!st[2]->str_nok && !looks_like_number(st[2])) ) warn("Possible use of == on string value"); } value = str_gnum(st[1]); value = (value == str_gnum(st[2])) ? 1.0 : 0.0; goto donumset; case O_NE: value = str_gnum(st[1]); value = (value != str_gnum(st[2])) ? 1.0 : 0.0; goto donumset; case O_NCMP: value = str_gnum(st[1]); value -= str_gnum(st[2]); if (value > 0.0) value = 1.0; else if (value < 0.0) value = -1.0; goto donumset; case O_BIT_AND: if (!sawvec || st[1]->str_nok || st[2]->str_nok) { value = str_gnum(st[1]);#ifndef lint value = (double)(U_L(value) & U_L(str_gnum(st[2])));#endif goto donumset; } else do_vop(optype,str,st[1],st[2]); break; case O_XOR: if (!sawvec || st[1]->str_nok || st[2]->str_nok) { value = str_gnum(st[1]);#ifndef lint value = (double)(U_L(value) ^ U_L(str_gnum(st[2])));#endif goto donumset; } else do_vop(optype,str,st[1],st[2]); break; case O_BIT_OR: if (!sawvec || st[1]->str_nok || st[2]->str_nok) { value = str_gnum(st[1]);#ifndef lint value = (double)(U_L(value) | U_L(str_gnum(st[2])));#endif goto donumset; } else do_vop(optype,str,st[1],st[2]); break;/* use register in evaluating str_true() */ case O_AND: if (str_true(st[1])) { anum = 2; optype = O_ITEM2; argflags = arg[anum].arg_flags; if (gimme == G_ARRAY) argflags |= AF_ARYOK; argtype = arg[anum].arg_type & A_MASK; argptr = arg[anum].arg_ptr; maxarg = anum = 1; sp = arglast[0]; st -= sp; goto re_eval; } else { if (assigning) { str_sset(str, st[1]); STABSET(str); } else str = st[1]; break; } case O_OR: if (str_true(st[1])) { if (assigning) { str_sset(str, st[1]); STABSET(str); } else str = st[1]; break; } else { anum = 2; optype = O_ITEM2; argflags = arg[anum].arg_flags; if (gimme == G_ARRAY) argflags |= AF_ARYOK; argtype = arg[anum].arg_type & A_MASK; argptr = arg[anum].arg_ptr; maxarg = anum = 1; sp = arglast[0]; st -= sp; goto re_eval; } case O_COND_EXPR: anum = (str_true(st[1]) ? 2 : 3); optype = (anum == 2 ? O_ITEM2 : O_ITEM3); argflags = arg[anum].arg_flags; if (gimme == G_ARRAY) argflags |= AF_ARYOK; argtype = arg[anum].arg_type & A_MASK; argptr = arg[anum].arg_ptr; maxarg = anum = 1; sp = arglast[0]; st -= sp; goto re_eval; case O_COMMA: if (gimme == G_ARRAY) goto array_return; str = st[2]; break; case O_NEGATE: value = -str_gnum(st[1]); goto donumset; case O_NOT:#ifdef NOTNOT { char xxx = str_true(st[1]); value = (double) !xxx; }#else value = (double) !str_true(st[1]);#endif goto donumset; case O_COMPLEMENT: if (!sawvec || st[1]->str_nok) {#ifndef lint value = (double) ~U_L(str_gnum(st[1]));#endif goto donumset; } else { STR_SSET(str,st[1]); tmps = str_get(str); for (anum = str->str_cur; anum; anum--, tmps++) *tmps = ~*tmps; } break; case O_SELECT: stab_efullname(str,defoutstab); if (maxarg > 0) { if ((arg[1].arg_type & A_MASK) == A_WORD) defoutstab = arg[1].arg_ptr.arg_stab; else defoutstab = stabent(str_get(st[1]),TRUE); if (!stab_io(defoutstab)) stab_io(defoutstab) = stio_new(); curoutstab = defoutstab; } STABSET(str); break; case O_WRITE: if (maxarg == 0) stab = defoutstab; else if ((arg[1].arg_type & A_MASK) == A_WORD) { if (!(stab = arg[1].arg_ptr.arg_stab)) stab = defoutstab; } else stab = stabent(str_get(st[1]),TRUE); if (!stab_io(stab)) { str_set(str, No); STABSET(str); break; } curoutstab = stab; fp = stab_io(stab)->ofp; debarg = arg; if (stab_io(stab)->fmt_stab) form = stab_form(stab_io(stab)->fmt_stab); else form = stab_form(stab); if (!form || !fp) { if (dowarn) { if (form) warn("No format for filehandle"); else { if (stab_io(stab)->ifp) warn("Filehandle only opened for input"); else warn("Write on closed filehandle"); } } str_set(str, No); STABSET(str); break; } format(&outrec,form,sp); do_write(&outrec,stab,sp); if (stab_io(stab)->flags & IOF_FLUSH) (void)fflush(fp); str_set(str, Yes); STABSET(str); break; case O_DBMOPEN:#ifdef SOME_DBM anum = arg[1].arg_type & A_MASK; if (anum == A_WORD || anum == A_STAB) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); if (st[3]->str_nok || st[3]->str_pok) anum = (int)str_gnum(st[3]); else anum = -1; value = (double)hdbmopen(stab_hash(stab),str_get(st[2]),anum); goto donumset;#else fatal("No dbm or ndbm on this machine");#endif case O_DBMCLOSE:#ifdef SOME_DBM anum = arg[1].arg_type & A_MASK; if (anum == A_WORD || anum == A_STAB) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); hdbmclose(stab_hash(stab)); goto say_yes;#else fatal("No dbm or ndbm on this machine");#endif case O_OPEN: if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); tmps = str_get(st[2]); if (do_open(stab,tmps,st[2]->str_cur)) { value = (double)forkprocess; stab_io(stab)->lines = 0; goto donumset; } else if (forkprocess == 0) /* we are a new child */ goto say_zero; else goto say_undef; /* break; */ case O_TRANS: value = (double) do_trans(str,arg); str = arg->arg_ptr.arg_str; goto donumset; case O_NTRANS: str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No); str = arg->arg_ptr.arg_str; break; case O_CLOSE: if (maxarg == 0) stab = defoutstab; else if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); str_set(str, do_close(stab,TRUE) ? Yes : No ); STABSET(str); break; case O_EACH: sp = do_each(str,stab_hash(arg[1].arg_ptr.arg_stab), gimme,arglast); goto array_return; case O_VALUES: case O_KEYS: sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype, gimme,arglast); goto array_return; case O_LARRAY: str->str_nok = str->str_pok = 0; str->str_u.str_stab = arg[1].arg_ptr.arg_stab; str->str_state = SS_ARY; break; case O_ARRAY: ary = stab_array(arg[1].arg_ptr.arg_stab); maxarg = ary->ary_fill + 1; if (gimme == G_ARRAY) { /* array wanted */ sp = arglast[0]; st -= sp; if (maxarg > 0 && sp + maxarg > stack->ary_max) { astore(stack,sp + maxarg, Nullstr); st = stack->ary_array; } st += sp; Copy(ary->ary_array, &st[1], maxarg, STR*); sp += maxarg; goto array_return; } else { value = (double)maxarg; goto donumset; } case O_AELEM: anum = ((int)str_gnum(st[2])) - arybase; str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE); break; case O_DELETE: tmpstab = arg[1].arg_ptr.arg_stab; tmps = str_get(st[2]); str = hdelete(stab_hash(tmpstab),tmps,st[2]->str_cur); if (tmpstab == envstab) my_setenv(tmps,Nullch);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -