1 /* $Header: consarg.c,v 3.0.1.4 90/03/12 16:24:40 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
9 * Revision 3.0.1.4 90/03/12 16:24:40 lwall
10 * patch13: return (@array) did counter-intuitive things
12 * Revision 3.0.1.3 90/02/28 16:47:54 lwall
13 * patch9: the x operator is now up to 10 times faster
14 * patch9: @_ clobbered by ($foo,$bar) = split
16 * Revision 3.0.1.2 89/11/17 15:11:34 lwall
17 * patch5: defined $foo{'bar'} should not create element
19 * Revision 3.0.1.1 89/11/11 04:14:30 lwall
20 * patch2: '-' x 26 made warnings about undefined value
21 * patch2: eval with no args caused strangeness
22 * patch2: local(@foo) didn't work, but local(@foo,$bar) did
24 * Revision 3.0 89/10/18 15:10:30 lwall
31 static int nothing_in_common();
32 static int arg_common();
33 static int spat_common();
36 make_split(stab,arg,limarg)
43 if (arg->arg_type != O_MATCH) {
44 Newz(201,spat,1,SPAT);
45 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
46 curstash->tbl_spatroot = spat;
48 spat->spat_runtime = arg;
49 arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
54 if (limarg->arg_type == O_ITEM) {
55 Copy(limarg+1,arg+3,1,ARG);
56 limarg[1].arg_type = A_NULL;
60 arg[3].arg_type = A_EXPR;
61 arg[3].arg_ptr.arg_arg = limarg;
65 arg[3].arg_type = A_NULL;
66 arg->arg_type = O_SPLIT;
67 spat = arg[2].arg_ptr.arg_spat;
68 spat->spat_repl = stab2arg(A_STAB,aadd(stab));
69 if (spat->spat_short) { /* exact match can bypass regexec() */
70 if (!((spat->spat_flags & SPAT_SCANFIRST) &&
71 (spat->spat_flags & SPAT_ALL) )) {
72 str_free(spat->spat_short);
73 spat->spat_short = Nullstr;
80 mod_match(type,left,pat)
88 if ((pat->arg_type == O_MATCH ||
89 pat->arg_type == O_SUBST ||
90 pat->arg_type == O_TRANS ||
91 pat->arg_type == O_SPLIT
93 pat[1].arg_ptr.arg_stab == defstab ) {
94 switch (pat->arg_type) {
96 newarg = make_op(type == O_MATCH ? O_MATCH : O_NMATCH,
98 left,Nullarg,Nullarg);
101 newarg = l(make_op(type == O_MATCH ? O_SUBST : O_NSUBST,
103 left,Nullarg,Nullarg));
106 newarg = l(make_op(type == O_MATCH ? O_TRANS : O_NTRANS,
108 left,Nullarg,Nullarg));
111 newarg = make_op(type == O_MATCH ? O_SPLIT : O_SPLIT,
113 left,Nullarg,Nullarg);
116 if (pat->arg_len >= 2) {
117 newarg[2].arg_type = pat[2].arg_type;
118 newarg[2].arg_ptr = pat[2].arg_ptr;
119 newarg[2].arg_flags = pat[2].arg_flags;
120 if (pat->arg_len >= 3) {
121 newarg[3].arg_type = pat[3].arg_type;
122 newarg[3].arg_ptr = pat[3].arg_ptr;
123 newarg[3].arg_flags = pat[3].arg_flags;
129 Newz(202,spat,1,SPAT);
130 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
131 curstash->tbl_spatroot = spat;
133 spat->spat_runtime = pat;
134 newarg = make_op(type,2,left,Nullarg,Nullarg);
135 newarg[2].arg_type = A_SPAT | A_DONT;
136 newarg[2].arg_ptr.arg_spat = spat;
143 make_op(type,newlen,arg1,arg2,arg3)
153 extern ARG *arg4; /* should be normal arguments, really */
156 arg = op_new(newlen);
157 arg->arg_type = type;
158 doarg = opargs[type];
160 if (chld->arg_type == O_ITEM &&
161 (hoistable[chld[1].arg_type] || chld[1].arg_type == A_LVAL ||
162 (chld[1].arg_type == A_LEXPR &&
163 (chld[1].arg_ptr.arg_arg->arg_type == O_LIST ||
164 chld[1].arg_ptr.arg_arg->arg_type == O_ARRAY ||
165 chld[1].arg_ptr.arg_arg->arg_type == O_HASH ))))
167 arg[1].arg_type = chld[1].arg_type;
168 arg[1].arg_ptr = chld[1].arg_ptr;
169 arg[1].arg_flags |= chld[1].arg_flags;
170 arg[1].arg_len = chld[1].arg_len;
174 arg[1].arg_type = A_EXPR;
175 arg[1].arg_ptr.arg_arg = chld;
178 arg[1].arg_type |= A_DONT;
180 arg[1].arg_flags |= AF_ARYOK;
184 if (chld->arg_type == O_ITEM &&
185 (hoistable[chld[1].arg_type] ||
187 ((chld[1].arg_type == A_READ && !(arg[1].arg_type & A_DONT))
189 (chld[1].arg_type == A_INDREAD && !(arg[1].arg_type & A_DONT))
191 (chld[1].arg_type == A_GLOB && !(arg[1].arg_type & A_DONT))
193 arg[2].arg_type = chld[1].arg_type;
194 arg[2].arg_ptr = chld[1].arg_ptr;
195 arg[2].arg_len = chld[1].arg_len;
199 arg[2].arg_type = A_EXPR;
200 arg[2].arg_ptr.arg_arg = chld;
203 arg[2].arg_type |= A_DONT;
205 arg[2].arg_flags |= AF_ARYOK;
209 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
210 arg[3].arg_type = chld[1].arg_type;
211 arg[3].arg_ptr = chld[1].arg_ptr;
212 arg[3].arg_len = chld[1].arg_len;
216 arg[3].arg_type = A_EXPR;
217 arg[3].arg_ptr.arg_arg = chld;
220 arg[3].arg_type |= A_DONT;
222 arg[3].arg_flags |= AF_ARYOK;
224 if (newlen >= 4 && (chld = arg4)) {
225 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
226 arg[4].arg_type = chld[1].arg_type;
227 arg[4].arg_ptr = chld[1].arg_ptr;
228 arg[4].arg_len = chld[1].arg_len;
232 arg[4].arg_type = A_EXPR;
233 arg[4].arg_ptr.arg_arg = chld;
236 if (newlen >= 5 && (chld = arg5)) {
237 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
238 arg[5].arg_type = chld[1].arg_type;
239 arg[5].arg_ptr = chld[1].arg_ptr;
240 arg[5].arg_len = chld[1].arg_len;
244 arg[5].arg_type = A_EXPR;
245 arg[5].arg_ptr.arg_arg = chld;
250 fprintf(stderr,"%lx <= make_op(%s",arg,opname[arg->arg_type]);
252 fprintf(stderr,",%s=%lx",
253 argname[arg[1].arg_type&A_MASK],arg[1].arg_ptr.arg_arg);
255 fprintf(stderr,",%s=%lx",
256 argname[arg[2].arg_type&A_MASK],arg[2].arg_ptr.arg_arg);
258 fprintf(stderr,",%s=%lx",
259 argname[arg[3].arg_type&A_MASK],arg[3].arg_ptr.arg_arg);
261 fprintf(stderr,",%s=%lx",
262 argname[arg[4].arg_type&A_MASK],arg[4].arg_ptr.arg_arg);
264 fprintf(stderr,",%s=%lx",
265 argname[arg[5].arg_type&A_MASK],arg[5].arg_ptr.arg_arg);
266 fprintf(stderr,")\n");
269 evalstatic(arg); /* see if we can consolidate anything */
280 double value; /* must not be register */
283 unsigned long tmplong;
285 double exp(), log(), sqrt(), modf();
287 double sin(), cos(), atan2(), pow();
289 if (!arg || !arg->arg_len)
292 if ((arg[1].arg_type == A_SINGLE || arg->arg_type == O_AELEM) &&
293 (arg->arg_len == 1 || arg[2].arg_type == A_SINGLE) ) {
295 s1 = arg[1].arg_ptr.arg_str;
296 if (arg->arg_len > 1)
297 s2 = arg[2].arg_ptr.arg_str;
300 switch (arg->arg_type) {
302 i = (int)str_gnum(s2);
303 if (i < 32767 && i >= 0) {
304 arg->arg_type = O_ITEM;
306 arg[1].arg_type = A_ARYSTAB; /* $abc[123] is hoistable now */
308 arg[1].arg_ptr = arg[1].arg_ptr; /* get stab pointer */
314 str = Nullstr; /* can't be evaluated yet */
321 i = (int)str_gnum(s2);
324 STR_GROW(str, i * s1->str_cur + 1);
325 repeatcpy(str->str_ptr, tmps, s1->str_cur, i);
326 str->str_cur = i * s1->str_cur;
327 str->str_ptr[str->str_cur] = '\0';
330 value = str_gnum(s1);
331 str_numset(str,value * str_gnum(s2));
334 value = str_gnum(s2);
336 yyerror("Illegal division by constant zero");
338 str_numset(str,str_gnum(s1) / value);
341 tmplong = (long)str_gnum(s2);
343 yyerror("Illegal modulus of constant zero");
346 tmp2 = (long)str_gnum(s1);
349 str_numset(str,(double)(tmp2 % tmplong));
351 str_numset(str,(double)(tmplong - (-tmp2 % tmplong)));
357 value = str_gnum(s1);
358 str_numset(str,value + str_gnum(s2));
361 value = str_gnum(s1);
362 str_numset(str,value - str_gnum(s2));
365 value = str_gnum(s1);
366 i = (int)str_gnum(s2);
368 str_numset(str,(double)(((long)value) << i));
372 value = str_gnum(s1);
373 i = (int)str_gnum(s2);
375 str_numset(str,(double)(((long)value) >> i));
379 value = str_gnum(s1);
380 str_numset(str,(value < str_gnum(s2)) ? 1.0 : 0.0);
383 value = str_gnum(s1);
384 str_numset(str,(value > str_gnum(s2)) ? 1.0 : 0.0);
387 value = str_gnum(s1);
388 str_numset(str,(value <= str_gnum(s2)) ? 1.0 : 0.0);
391 value = str_gnum(s1);
392 str_numset(str,(value >= str_gnum(s2)) ? 1.0 : 0.0);
396 if ((!s1->str_nok && !looks_like_number(s1)) ||
397 (!s2->str_nok && !looks_like_number(s2)) )
398 warn("Possible use of == on string value");
400 value = str_gnum(s1);
401 str_numset(str,(value == str_gnum(s2)) ? 1.0 : 0.0);
404 value = str_gnum(s1);
405 str_numset(str,(value != str_gnum(s2)) ? 1.0 : 0.0);
408 value = str_gnum(s1);
410 str_numset(str,(double)(((long)value) & ((long)str_gnum(s2))));
414 value = str_gnum(s1);
416 str_numset(str,(double)(((long)value) ^ ((long)str_gnum(s2))));
420 value = str_gnum(s1);
422 str_numset(str,(double)(((long)value) | ((long)str_gnum(s2))));
438 if ((arg[3].arg_type & A_MASK) != A_SINGLE) {
446 str_sset(str,arg[3].arg_ptr.arg_str);
447 str_free(arg[3].arg_ptr.arg_str);
451 str_numset(str,(double)(-str_gnum(s1)));
454 str_numset(str,(double)(!str_true(s1)));
458 str_numset(str,(double)(~(long)str_gnum(s1)));
462 str_numset(str,sin(str_gnum(s1)));
465 str_numset(str,cos(str_gnum(s1)));
468 value = str_gnum(s1);
469 str_numset(str,atan2(value, str_gnum(s2)));
472 value = str_gnum(s1);
473 str_numset(str,pow(value, str_gnum(s2)));
476 str_numset(str, (double)str_len(s1));
479 str_numset(str,(double)(str_cmp(s1,s2) < 0));
482 str_numset(str,(double)(str_cmp(s1,s2) > 0));
485 str_numset(str,(double)(str_cmp(s1,s2) <= 0));
488 str_numset(str,(double)(str_cmp(s1,s2) >= 0));
491 str_numset(str,(double)(str_eq(s1,s2)));
494 str_numset(str,(double)(!str_eq(s1,s2)));
499 str_set(str,crypt(tmps,str_get(s2)));
502 "The crypt() function is unimplemented due to excessive paranoia.");
506 str_numset(str,exp(str_gnum(s1)));
509 str_numset(str,log(str_gnum(s1)));
512 str_numset(str,sqrt(str_gnum(s1)));
515 value = str_gnum(s1);
517 (void)modf(value,&value);
519 (void)modf(-value,&value);
522 str_numset(str,value);
526 str_numset(str,(double)(*str_get(s1)));
534 str_numset(str,(double)(zapc));
540 arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */
543 arg[1].arg_ptr.arg_str = str;
558 i = arg[1].arg_type & A_MASK;
560 arg->arg_flags |= AF_COMMON; /* assume something in common */
561 /* which forces us to copy things */
564 arg[1].arg_type = A_LARYLEN;
567 if (i == A_ARYSTAB) {
568 arg[1].arg_type = A_LARYSTAB;
572 /* see if it's an array reference */
574 if (i == A_EXPR || i == A_LEXPR) {
575 arg1 = arg[1].arg_ptr.arg_arg;
577 if (arg1->arg_type == O_LIST || arg1->arg_type == O_ITEM) {
579 if (arg->arg_len > 1) {
581 arg2 = arg[2].arg_ptr.arg_arg;
582 if (nothing_in_common(arg1,arg2))
583 arg->arg_flags &= ~AF_COMMON;
584 if (arg->arg_type == O_ASSIGN) {
585 if (arg1->arg_flags & AF_LOCAL)
586 arg->arg_flags |= AF_LOCAL;
587 arg[1].arg_flags |= AF_ARYOK;
588 arg[2].arg_flags |= AF_ARYOK;
591 else if (arg->arg_type != O_CHOP)
592 arg->arg_type = O_ASSIGN; /* possible local(); */
593 for (i = arg1->arg_len; i >= 1; i--) {
594 switch (arg1[i].arg_type) {
595 case A_STAR: case A_LSTAR:
596 arg1[i].arg_type = A_LSTAR;
598 case A_STAB: case A_LVAL:
599 arg1[i].arg_type = A_LVAL;
601 case A_ARYLEN: case A_LARYLEN:
602 arg1[i].arg_type = A_LARYLEN;
604 case A_ARYSTAB: case A_LARYSTAB:
605 arg1[i].arg_type = A_LARYSTAB;
607 case A_EXPR: case A_LEXPR:
608 arg1[i].arg_type = A_LEXPR;
609 switch(arg1[i].arg_ptr.arg_arg->arg_type) {
610 case O_ARRAY: case O_LARRAY:
611 arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;
614 case O_AELEM: case O_LAELEM:
615 arg1[i].arg_ptr.arg_arg->arg_type = O_LAELEM;
617 case O_HASH: case O_LHASH:
618 arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;
621 case O_HELEM: case O_LHELEM:
622 arg1[i].arg_ptr.arg_arg->arg_type = O_LHELEM;
624 case O_ASLICE: case O_LASLICE:
625 arg1[i].arg_ptr.arg_arg->arg_type = O_LASLICE;
627 case O_HSLICE: case O_LHSLICE:
628 arg1[i].arg_ptr.arg_arg->arg_type = O_LHSLICE;
636 (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue",
637 argname[arg1[i].arg_type&A_MASK]);
641 if (arg->arg_len > 1) {
642 if (arg2->arg_type == O_SPLIT && !arg2[3].arg_type && !arghog) {
643 arg2[3].arg_type = A_SINGLE;
644 arg2[3].arg_ptr.arg_str =
645 str_nmake((double)arg1->arg_len + 1); /* limit split len*/
649 else if (arg1->arg_type == O_AELEM || arg1->arg_type == O_LAELEM)
650 if (arg->arg_type == O_DEFINED)
651 arg1->arg_type = O_AELEM;
653 arg1->arg_type = O_LAELEM;
654 else if (arg1->arg_type == O_ARRAY || arg1->arg_type == O_LARRAY) {
655 arg1->arg_type = O_LARRAY;
656 if (arg->arg_len > 1) {
658 arg2 = arg[2].arg_ptr.arg_arg;
659 if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/
660 spat = arg2[2].arg_ptr.arg_spat;
661 if (!(spat->spat_flags & SPAT_ONCE) &&
662 nothing_in_common(arg1,spat->spat_repl)) {
663 spat->spat_repl[1].arg_ptr.arg_stab =
664 arg1[1].arg_ptr.arg_stab;
665 spat->spat_flags |= SPAT_ONCE;
666 arg_free(arg1); /* recursive */
667 free_arg(arg); /* non-recursive */
668 return arg2; /* split has builtin assign */
671 else if (nothing_in_common(arg1,arg2))
672 arg->arg_flags &= ~AF_COMMON;
673 if (arg->arg_type == O_ASSIGN) {
674 arg[1].arg_flags |= AF_ARYOK;
675 arg[2].arg_flags |= AF_ARYOK;
678 else if (arg->arg_type == O_ASSIGN)
679 arg[1].arg_flags |= AF_ARYOK;
681 else if (arg1->arg_type == O_HELEM || arg1->arg_type == O_LHELEM)
682 if (arg->arg_type == O_DEFINED)
683 arg1->arg_type = O_HELEM; /* avoid creating one */
685 arg1->arg_type = O_LHELEM;
686 else if (arg1->arg_type == O_HASH || arg1->arg_type == O_LHASH) {
687 arg1->arg_type = O_LHASH;
688 if (arg->arg_len > 1) {
690 arg2 = arg[2].arg_ptr.arg_arg;
691 if (nothing_in_common(arg1,arg2))
692 arg->arg_flags &= ~AF_COMMON;
693 if (arg->arg_type == O_ASSIGN) {
694 arg[1].arg_flags |= AF_ARYOK;
695 arg[2].arg_flags |= AF_ARYOK;
698 else if (arg->arg_type == O_ASSIGN)
699 arg[1].arg_flags |= AF_ARYOK;
701 else if (arg1->arg_type == O_ASLICE) {
702 arg1->arg_type = O_LASLICE;
703 if (arg->arg_type == O_ASSIGN) {
704 arg[1].arg_flags |= AF_ARYOK;
705 arg[2].arg_flags |= AF_ARYOK;
708 else if (arg1->arg_type == O_HSLICE) {
709 arg1->arg_type = O_LHSLICE;
710 if (arg->arg_type == O_ASSIGN) {
711 arg[1].arg_flags |= AF_ARYOK;
712 arg[2].arg_flags |= AF_ARYOK;
715 else if ((arg->arg_type == O_DEFINED || arg->arg_type == O_UNDEF) &&
716 (arg1->arg_type == (perldb ? O_DBSUBR : O_SUBR)) ) {
717 arg[1].arg_type |= A_DONT;
719 else if (arg1->arg_type == O_SUBSTR || arg1->arg_type == O_VEC) {
721 Renewc(arg1->arg_ptr.arg_str, 1, struct lstring, STR);
722 /* grow string struct to hold an lstring struct */
724 else if (arg1->arg_type == O_ASSIGN) {
725 if (arg->arg_type == O_CHOP)
726 arg[1].arg_flags &= ~AF_ARYOK; /* grandfather chop idiom */
729 (void)sprintf(tokenbuf,
730 "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);
733 arg[1].arg_type = A_LEXPR | (arg[1].arg_type & A_DONT);
734 if (arg->arg_type == O_ASSIGN && (arg1[1].arg_flags & AF_ARYOK)) {
735 arg[1].arg_flags |= AF_ARYOK;
736 if (arg->arg_len > 1)
737 arg[2].arg_flags |= AF_ARYOK;
741 fprintf(stderr,"lval LEXPR\n");
745 if (i == A_STAR || i == A_LSTAR) {
746 arg[1].arg_type = A_LSTAR | (arg[1].arg_type & A_DONT);
750 /* not an array reference, should be a register name */
752 if (i != A_STAB && i != A_LVAL) {
753 (void)sprintf(tokenbuf,
754 "Illegal item (%s) as lvalue",argname[arg[1].arg_type&A_MASK]);
757 arg[1].arg_type = A_LVAL | (arg[1].arg_type & A_DONT);
760 fprintf(stderr,"lval LVAL\n");
770 if (type == O_DEFINED || type == O_UNDEF) {
771 if (arg->arg_type != O_ITEM)
773 if (arg->arg_type == O_ITEM) {
774 type = arg[1].arg_type & A_MASK;
775 if (type == A_EXPR || type == A_LEXPR)
776 arg[1].arg_type = A_LEXPR|A_DONT;
787 if (arg[i].arg_type != A_EXPR) { /* dehoist */
788 tmparg = make_op(O_ITEM,1,Nullarg,Nullarg,Nullarg);
790 arg[i].arg_ptr.arg_arg = tmparg;
791 arg[i].arg_type = A_EXPR;
796 addflags(i,flags,arg)
799 arg[i].arg_flags |= flags;
807 if (arg->arg_type == O_ARRAY || arg->arg_type == O_HASH)
808 return make_op(O_ITEM,1,arg,Nullarg,Nullarg);
812 /* maybe do a join on multiple array dimensions */
818 if (arg && arg->arg_type == O_COMMA) {
820 arg = make_op(O_JOIN, 2,
821 stab2arg(A_STAB,stabent(";",TRUE)),
834 register ARG *nxtnode;
840 arg->arg_type = O_LIST;
842 if (arg->arg_type != O_COMMA) {
843 if (arg->arg_type != O_ARRAY)
844 arg->arg_flags |= AF_LISTISH; /* see listish() below */
847 for (i = 2, node = arg; ; i++) {
848 if (node->arg_len < 2)
850 if (node[1].arg_type != A_EXPR)
852 node = node[1].arg_ptr.arg_arg;
853 if (node->arg_type != O_COMMA)
859 tmpstr = arg->arg_ptr.arg_str;
861 *arg = *node; /* copy everything except the STR */
863 (void)bcopy((char *)node, (char *)arg, sizeof(ARG));
865 arg->arg_ptr.arg_str = tmpstr;
870 (void)bcopy((char *)(node+2), (char *)(arg+j), sizeof(ARG));
872 arg[j].arg_flags |= AF_ARYOK;
873 --j; /* Bug in Xenix compiler */
878 (void)bcopy((char *)(node+1), (char *)(arg+1), sizeof(ARG));
883 nxtnode = node[1].arg_ptr.arg_arg;
888 arg[1].arg_flags |= AF_ARYOK;
889 arg[2].arg_flags |= AF_ARYOK;
890 arg->arg_type = O_LIST;
895 /* turn a single item into a list */
901 if (arg->arg_flags & AF_LISTISH)
902 arg = make_op(O_LIST,1,arg,Nullarg,Nullarg);
907 maybelistish(optype, arg)
913 if (optype == O_RETURN && arg->arg_type == O_ITEM &&
914 arg[1].arg_type == A_EXPR && (tmparg = arg[1].arg_ptr.arg_arg) &&
915 ((tmparg->arg_flags & AF_LISTISH) || (tmparg->arg_type == O_ARRAY) )) {
916 tmparg = listish(tmparg);
920 else if (optype == O_PRTF ||
921 (arg->arg_type == O_ASLICE || arg->arg_type == O_HSLICE ||
922 arg->arg_type == O_F_OR_R) )
927 /* mark list of local variables */
933 arg->arg_flags |= AF_LOCAL;
942 if (arg->arg_len == 0)
943 arg[1].arg_type = A_NULL;
945 arg[2].arg_ptr.arg_hash = curstash;
946 arg[2].arg_type = A_NULL;
954 if (arg->arg_type == O_CONCAT && arg[2].arg_type == A_READ) {
955 arg->arg_type = O_RCAT;
956 arg[2].arg_type = arg[2].arg_ptr.arg_arg[1].arg_type;
957 arg[2].arg_ptr = arg[2].arg_ptr.arg_arg[1].arg_ptr;
958 free_arg(arg[2].arg_ptr.arg_arg);
971 arg->arg_type = O_ITEM;
972 arg[1].arg_type = atype;
973 arg[1].arg_ptr.arg_stab = stab;
984 arg->arg_type = O_ITEM;
985 arg[1].arg_type = A_SINGLE;
986 arg[1].arg_ptr.arg_str = str_make(cval,0);
997 Newz(203,arg, numargs + 1, ARG);
998 arg->arg_ptr.arg_str = Str_new(21,0);
999 arg->arg_len = numargs;
1007 str_free(arg->arg_ptr.arg_str);
1012 make_match(type,expr,spat)
1019 arg = make_op(type,2,expr,Nullarg,Nullarg);
1021 arg[2].arg_type = A_SPAT|A_DONT;
1022 arg[2].arg_ptr.arg_spat = spat;
1025 fprintf(stderr,"make_match SPAT=%lx\n",(long)spat);
1028 if (type == O_SUBST || type == O_NSUBST) {
1029 if (arg[1].arg_type != A_STAB) {
1030 yyerror("Illegal lvalue");
1032 arg[1].arg_type = A_LVAL;
1044 arg->arg_type = O_ITEM;
1045 arg[1].arg_type = A_CMD;
1046 arg[1].arg_ptr.arg_cmd = cmd;
1050 /* Check two expressions to see if there is any identifier in common */
1053 nothing_in_common(arg1,arg2)
1057 static int thisexpr = 0; /* I don't care if this wraps */
1060 if (arg_common(arg1,thisexpr,1))
1061 return 0; /* hit eval or do {} */
1062 if (arg_common(arg2,thisexpr,0))
1063 return 0; /* hit identifier again */
1067 /* Recursively descend an expression and mark any identifier or check
1068 * it to see if it was marked already.
1072 arg_common(arg,exprnum,marking)
1081 for (i = arg->arg_len; i >= 1; i--) {
1082 switch (arg[i].arg_type & A_MASK) {
1087 if (arg_common(arg[i].arg_ptr.arg_arg,exprnum,marking))
1091 return 1; /* assume hanky panky */
1099 stab_lastexpr(arg[i].arg_ptr.arg_stab) = exprnum;
1100 else if (stab_lastexpr(arg[i].arg_ptr.arg_stab) == exprnum)
1106 register char *s = arg[i].arg_ptr.arg_str->str_ptr;
1107 register char *send = s + arg[i].arg_ptr.arg_str->str_cur;
1108 register STAB *stab;
1111 if (*s == '$' && s[1]) {
1112 s = scanreg(s,send,tokenbuf);
1113 stab = stabent(tokenbuf,TRUE);
1115 stab_lastexpr(stab) = exprnum;
1116 else if (stab_lastexpr(stab) == exprnum)
1120 else if (*s == '\\' && s[1])
1127 if (spat_common(arg[i].arg_ptr.arg_spat,exprnum,marking))
1138 switch (arg->arg_type) {
1141 if ((arg[1].arg_type & A_MASK) == A_STAB)
1142 (void)aadd(arg[1].arg_ptr.arg_stab);
1146 if ((arg[1].arg_type & A_MASK) == A_STAB)
1147 (void)hadd(arg[1].arg_ptr.arg_stab);
1158 spat_common(spat,exprnum,marking)
1159 register SPAT *spat;
1163 if (spat->spat_runtime)
1164 if (arg_common(spat->spat_runtime,exprnum,marking))
1166 if (spat->spat_repl) {
1167 if (arg_common(spat->spat_repl,exprnum,marking))