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

📄 cons.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -