1 /* $Header: consarg.c,v 4.0 91/03/20 01:06:15 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 4.0 91/03/20 01:06:15 lwall
16 static int nothing_in_common();
17 static int arg_common();
18 static int spat_common();
21 make_split(stab,arg,limarg)
28 if (arg->arg_type != O_MATCH) {
29 Newz(201,spat,1,SPAT);
30 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
31 curstash->tbl_spatroot = spat;
33 spat->spat_runtime = arg;
34 arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
39 if (limarg->arg_type == O_ITEM) {
40 Copy(limarg+1,arg+3,1,ARG);
41 limarg[1].arg_type = A_NULL;
46 arg[3].arg_type = A_EXPR;
47 arg[3].arg_ptr.arg_arg = limarg;
51 arg[3].arg_type = A_NULL;
52 arg->arg_type = O_SPLIT;
53 spat = arg[2].arg_ptr.arg_spat;
54 spat->spat_repl = stab2arg(A_STAB,aadd(stab));
55 if (spat->spat_short) { /* exact match can bypass regexec() */
56 if (!((spat->spat_flags & SPAT_SCANFIRST) &&
57 (spat->spat_flags & SPAT_ALL) )) {
58 str_free(spat->spat_short);
59 spat->spat_short = Nullstr;
66 mod_match(type,left,pat)
77 if ((pat->arg_type == O_MATCH ||
78 pat->arg_type == O_SUBST ||
79 pat->arg_type == O_TRANS ||
80 pat->arg_type == O_SPLIT
82 pat[1].arg_ptr.arg_stab == defstab ) {
83 switch (pat->arg_type) {
85 newarg = make_op(type == O_MATCH ? O_MATCH : O_NMATCH,
87 left,Nullarg,Nullarg);
90 newarg = l(make_op(type == O_MATCH ? O_SUBST : O_NSUBST,
92 left,Nullarg,Nullarg));
95 newarg = l(make_op(type == O_MATCH ? O_TRANS : O_NTRANS,
97 left,Nullarg,Nullarg));
100 newarg = make_op(type == O_MATCH ? O_SPLIT : O_SPLIT,
102 left,Nullarg,Nullarg);
105 if (pat->arg_len >= 2) {
106 newarg[2].arg_type = pat[2].arg_type;
107 newarg[2].arg_ptr = pat[2].arg_ptr;
108 newarg[2].arg_len = pat[2].arg_len;
109 newarg[2].arg_flags = pat[2].arg_flags;
110 if (pat->arg_len >= 3) {
111 newarg[3].arg_type = pat[3].arg_type;
112 newarg[3].arg_ptr = pat[3].arg_ptr;
113 newarg[3].arg_len = pat[3].arg_len;
114 newarg[3].arg_flags = pat[3].arg_flags;
120 Newz(202,spat,1,SPAT);
121 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
122 curstash->tbl_spatroot = spat;
124 spat->spat_runtime = pat;
125 newarg = make_op(type,2,left,Nullarg,Nullarg);
126 newarg[2].arg_type = A_SPAT | A_DONT;
127 newarg[2].arg_ptr.arg_spat = spat;
134 make_op(type,newlen,arg1,arg2,arg3)
143 register unsigned doarg;
145 extern ARG *arg4; /* should be normal arguments, really */
148 arg = op_new(newlen);
149 arg->arg_type = type;
151 if (chld->arg_type == O_ITEM &&
152 (hoistable[ i = (chld[1].arg_type&A_MASK)] || i == A_LVAL ||
154 (chld[1].arg_ptr.arg_arg->arg_type == O_LIST ||
155 chld[1].arg_ptr.arg_arg->arg_type == O_ARRAY ||
156 chld[1].arg_ptr.arg_arg->arg_type == O_HASH ))))
158 arg[1].arg_type = chld[1].arg_type;
159 arg[1].arg_ptr = chld[1].arg_ptr;
160 arg[1].arg_flags |= chld[1].arg_flags;
161 arg[1].arg_len = chld[1].arg_len;
165 arg[1].arg_type = A_EXPR;
166 arg[1].arg_ptr.arg_arg = chld;
170 if (chld->arg_type == O_ITEM &&
171 (hoistable[chld[1].arg_type&A_MASK] ||
173 ((chld[1].arg_type == A_READ && !(arg[1].arg_type & A_DONT))
175 (chld[1].arg_type == A_INDREAD && !(arg[1].arg_type & A_DONT))
177 (chld[1].arg_type == A_GLOB && !(arg[1].arg_type & A_DONT))
179 arg[2].arg_type = chld[1].arg_type;
180 arg[2].arg_ptr = chld[1].arg_ptr;
181 arg[2].arg_len = chld[1].arg_len;
185 arg[2].arg_type = A_EXPR;
186 arg[2].arg_ptr.arg_arg = chld;
190 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type&A_MASK]) {
191 arg[3].arg_type = chld[1].arg_type;
192 arg[3].arg_ptr = chld[1].arg_ptr;
193 arg[3].arg_len = chld[1].arg_len;
197 arg[3].arg_type = A_EXPR;
198 arg[3].arg_ptr.arg_arg = chld;
201 if (newlen >= 4 && (chld = arg4)) {
202 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type&A_MASK]) {
203 arg[4].arg_type = chld[1].arg_type;
204 arg[4].arg_ptr = chld[1].arg_ptr;
205 arg[4].arg_len = chld[1].arg_len;
209 arg[4].arg_type = A_EXPR;
210 arg[4].arg_ptr.arg_arg = chld;
213 if (newlen >= 5 && (chld = arg5)) {
214 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type&A_MASK]) {
215 arg[5].arg_type = chld[1].arg_type;
216 arg[5].arg_ptr = chld[1].arg_ptr;
217 arg[5].arg_len = chld[1].arg_len;
221 arg[5].arg_type = A_EXPR;
222 arg[5].arg_ptr.arg_arg = chld;
225 doarg = opargs[type];
226 for (i = 1; i <= newlen; ++i) {
228 arg[i].arg_type |= A_DONT;
230 arg[i].arg_flags |= AF_ARYOK;
235 fprintf(stderr,"%lx <= make_op(%s",arg,opname[arg->arg_type]);
237 fprintf(stderr,",%s=%lx",
238 argname[arg[1].arg_type&A_MASK],arg[1].arg_ptr.arg_arg);
240 fprintf(stderr,",%s=%lx",
241 argname[arg[2].arg_type&A_MASK],arg[2].arg_ptr.arg_arg);
243 fprintf(stderr,",%s=%lx",
244 argname[arg[3].arg_type&A_MASK],arg[3].arg_ptr.arg_arg);
246 fprintf(stderr,",%s=%lx",
247 argname[arg[4].arg_type&A_MASK],arg[4].arg_ptr.arg_arg);
249 fprintf(stderr,",%s=%lx",
250 argname[arg[5].arg_type&A_MASK],arg[5].arg_ptr.arg_arg);
251 fprintf(stderr,")\n");
254 evalstatic(arg); /* see if we can consolidate anything */
265 double value; /* must not be register */
268 unsigned long tmplong;
270 double exp(), log(), sqrt(), modf();
272 double sin(), cos(), atan2(), pow();
274 if (!arg || !arg->arg_len)
277 if ((arg[1].arg_type == A_SINGLE || arg->arg_type == O_AELEM) &&
278 (arg->arg_len == 1 || arg[2].arg_type == A_SINGLE) ) {
280 s1 = arg[1].arg_ptr.arg_str;
281 if (arg->arg_len > 1)
282 s2 = arg[2].arg_ptr.arg_str;
285 switch (arg->arg_type) {
287 i = (int)str_gnum(s2);
288 if (i < 32767 && i >= 0) {
289 arg->arg_type = O_ITEM;
291 arg[1].arg_type = A_ARYSTAB; /* $abc[123] is hoistable now */
294 arg[2].arg_type = A_NULL;
295 arg[2].arg_ptr.arg_str = Nullstr;
300 str = Nullstr; /* can't be evaluated yet */
307 i = (int)str_gnum(s2);
310 STR_GROW(str, i * s1->str_cur + 1);
311 repeatcpy(str->str_ptr, tmps, s1->str_cur, i);
312 str->str_cur = i * s1->str_cur;
313 str->str_ptr[str->str_cur] = '\0';
316 value = str_gnum(s1);
317 str_numset(str,value * str_gnum(s2));
320 value = str_gnum(s2);
322 yyerror("Illegal division by constant zero");
325 /* insure that 20./5. == 4. */
330 if ((double)(int)x == x &&
331 (double)(int)value == value &&
332 (k = (int)x/(int)value)*(int)value == (int)x) {
337 str_numset(str,value);
340 str_numset(str,str_gnum(s1) / value);
344 tmplong = (unsigned long)str_gnum(s2);
346 yyerror("Illegal modulus of constant zero");
349 tmp2 = (long)str_gnum(s1);
352 str_numset(str,(double)(tmp2 % tmplong));
354 str_numset(str,(double)((tmplong-((-tmp2 - 1) % tmplong)) - 1));
360 value = str_gnum(s1);
361 str_numset(str,value + str_gnum(s2));
364 value = str_gnum(s1);
365 str_numset(str,value - str_gnum(s2));
368 value = str_gnum(s1);
369 i = (int)str_gnum(s2);
371 str_numset(str,(double)(((long)value) << i));
375 value = str_gnum(s1);
376 i = (int)str_gnum(s2);
378 str_numset(str,(double)(((long)value) >> i));
382 value = str_gnum(s1);
383 str_numset(str,(value < str_gnum(s2)) ? 1.0 : 0.0);
386 value = str_gnum(s1);
387 str_numset(str,(value > str_gnum(s2)) ? 1.0 : 0.0);
390 value = str_gnum(s1);
391 str_numset(str,(value <= str_gnum(s2)) ? 1.0 : 0.0);
394 value = str_gnum(s1);
395 str_numset(str,(value >= str_gnum(s2)) ? 1.0 : 0.0);
399 if ((!s1->str_nok && !looks_like_number(s1)) ||
400 (!s2->str_nok && !looks_like_number(s2)) )
401 warn("Possible use of == on string value");
403 value = str_gnum(s1);
404 str_numset(str,(value == str_gnum(s2)) ? 1.0 : 0.0);
407 value = str_gnum(s1);
408 str_numset(str,(value != str_gnum(s2)) ? 1.0 : 0.0);
411 value = str_gnum(s1);
412 value -= str_gnum(s2);
415 else if (value < 0.0)
417 str_numset(str,value);
420 value = str_gnum(s1);
422 str_numset(str,(double)(U_L(value) & U_L(str_gnum(s2))));
426 value = str_gnum(s1);
428 str_numset(str,(double)(U_L(value) ^ U_L(str_gnum(s2))));
432 value = str_gnum(s1);
434 str_numset(str,(double)(U_L(value) | U_L(str_gnum(s2))));
450 if ((arg[3].arg_type & A_MASK) != A_SINGLE) {
458 str_sset(str,arg[3].arg_ptr.arg_str);
459 str_free(arg[3].arg_ptr.arg_str);
460 arg[3].arg_ptr.arg_str = Nullstr;
464 str_numset(str,(double)(-str_gnum(s1)));
467 str_numset(str,(double)(!str_true(s1)));
471 str_numset(str,(double)(~U_L(str_gnum(s1))));
475 str_numset(str,sin(str_gnum(s1)));
478 str_numset(str,cos(str_gnum(s1)));
481 value = str_gnum(s1);
482 str_numset(str,atan2(value, str_gnum(s2)));
485 value = str_gnum(s1);
486 str_numset(str,pow(value, str_gnum(s2)));
489 str_numset(str, (double)str_len(s1));
492 str_numset(str,(double)(str_cmp(s1,s2) < 0));
495 str_numset(str,(double)(str_cmp(s1,s2) > 0));
498 str_numset(str,(double)(str_cmp(s1,s2) <= 0));
501 str_numset(str,(double)(str_cmp(s1,s2) >= 0));
504 str_numset(str,(double)(str_eq(s1,s2)));
507 str_numset(str,(double)(!str_eq(s1,s2)));
510 str_numset(str,(double)(str_cmp(s1,s2)));
515 str_set(str,crypt(tmps,str_get(s2)));
518 "The crypt() function is unimplemented due to excessive paranoia.");
522 str_numset(str,exp(str_gnum(s1)));
525 str_numset(str,log(str_gnum(s1)));
528 str_numset(str,sqrt(str_gnum(s1)));
531 value = str_gnum(s1);
533 (void)modf(value,&value);
535 (void)modf(-value,&value);
538 str_numset(str,value);
542 str_numset(str,(double)(*str_get(s1)));
550 str_numset(str,(double)(zapc));
556 arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */
559 arg[1].arg_ptr.arg_str = str;
560 arg[2].arg_ptr.arg_str = Nullstr;
561 arg[2].arg_type = A_NULL;
576 i = arg[1].arg_type & A_MASK;
578 arg->arg_flags |= AF_COMMON; /* assume something in common */
579 /* which forces us to copy things */
582 arg[1].arg_type = A_LARYLEN;
585 if (i == A_ARYSTAB) {
586 arg[1].arg_type = A_LARYSTAB;
590 /* see if it's an array reference */
592 if (i == A_EXPR || i == A_LEXPR) {
593 arg1 = arg[1].arg_ptr.arg_arg;
595 if (arg1->arg_type == O_LIST || arg1->arg_type == O_ITEM) {
597 if (arg->arg_len > 1) {
599 arg2 = arg[2].arg_ptr.arg_arg;
600 if (nothing_in_common(arg1,arg2))
601 arg->arg_flags &= ~AF_COMMON;
602 if (arg->arg_type == O_ASSIGN) {
603 if (arg1->arg_flags & AF_LOCAL)
604 arg->arg_flags |= AF_LOCAL;
605 arg[1].arg_flags |= AF_ARYOK;
606 arg[2].arg_flags |= AF_ARYOK;
609 else if (arg->arg_type != O_CHOP)
610 arg->arg_type = O_ASSIGN; /* possible local(); */
611 for (i = arg1->arg_len; i >= 1; i--) {
612 switch (arg1[i].arg_type) {
613 case A_STAR: case A_LSTAR:
614 arg1[i].arg_type = A_LSTAR;
616 case A_STAB: case A_LVAL:
617 arg1[i].arg_type = A_LVAL;
619 case A_ARYLEN: case A_LARYLEN:
620 arg1[i].arg_type = A_LARYLEN;
622 case A_ARYSTAB: case A_LARYSTAB:
623 arg1[i].arg_type = A_LARYSTAB;
625 case A_EXPR: case A_LEXPR:
626 arg1[i].arg_type = A_LEXPR;
627 switch(arg1[i].arg_ptr.arg_arg->arg_type) {
628 case O_ARRAY: case O_LARRAY:
629 arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;
632 case O_AELEM: case O_LAELEM:
633 arg1[i].arg_ptr.arg_arg->arg_type = O_LAELEM;
635 case O_HASH: case O_LHASH:
636 arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;
639 case O_HELEM: case O_LHELEM:
640 arg1[i].arg_ptr.arg_arg->arg_type = O_LHELEM;
642 case O_ASLICE: case O_LASLICE:
643 arg1[i].arg_ptr.arg_arg->arg_type = O_LASLICE;
645 case O_HSLICE: case O_LHSLICE:
646 arg1[i].arg_ptr.arg_arg->arg_type = O_LHSLICE;
654 (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue",
655 argname[arg1[i].arg_type&A_MASK]);
659 if (arg->arg_len > 1) {
660 if (arg2->arg_type == O_SPLIT && !arg2[3].arg_type && !arghog) {
661 arg2[3].arg_type = A_SINGLE;
662 arg2[3].arg_ptr.arg_str =
663 str_nmake((double)arg1->arg_len + 1); /* limit split len*/
667 else if (arg1->arg_type == O_AELEM || arg1->arg_type == O_LAELEM)
668 if (arg->arg_type == O_DEFINED)
669 arg1->arg_type = O_AELEM;
671 arg1->arg_type = O_LAELEM;
672 else if (arg1->arg_type == O_ARRAY || arg1->arg_type == O_LARRAY) {
673 arg1->arg_type = O_LARRAY;
674 if (arg->arg_len > 1) {
676 arg2 = arg[2].arg_ptr.arg_arg;
677 if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/
678 spat = arg2[2].arg_ptr.arg_spat;
679 if (!(spat->spat_flags & SPAT_ONCE) &&
680 nothing_in_common(arg1,spat->spat_repl)) {
681 spat->spat_repl[1].arg_ptr.arg_stab =
682 arg1[1].arg_ptr.arg_stab;
683 arg1[1].arg_ptr.arg_stab = Nullstab;
684 spat->spat_flags |= SPAT_ONCE;
685 arg_free(arg1); /* recursive */
686 arg[1].arg_ptr.arg_arg = Nullarg;
687 free_arg(arg); /* non-recursive */
688 return arg2; /* split has builtin assign */
691 else 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_HELEM || arg1->arg_type == O_LHELEM)
702 if (arg->arg_type == O_DEFINED)
703 arg1->arg_type = O_HELEM; /* avoid creating one */
705 arg1->arg_type = O_LHELEM;
706 else if (arg1->arg_type == O_HASH || arg1->arg_type == O_LHASH) {
707 arg1->arg_type = O_LHASH;
708 if (arg->arg_len > 1) {
710 arg2 = arg[2].arg_ptr.arg_arg;
711 if (nothing_in_common(arg1,arg2))
712 arg->arg_flags &= ~AF_COMMON;
713 if (arg->arg_type == O_ASSIGN) {
714 arg[1].arg_flags |= AF_ARYOK;
715 arg[2].arg_flags |= AF_ARYOK;
718 else if (arg->arg_type == O_ASSIGN)
719 arg[1].arg_flags |= AF_ARYOK;
721 else if (arg1->arg_type == O_ASLICE) {
722 arg1->arg_type = O_LASLICE;
723 if (arg->arg_type == O_ASSIGN) {
725 arg[1].arg_flags |= AF_ARYOK;
726 arg[2].arg_flags |= AF_ARYOK;
729 else if (arg1->arg_type == O_HSLICE) {
730 arg1->arg_type = O_LHSLICE;
731 if (arg->arg_type == O_ASSIGN) {
733 arg[1].arg_flags |= AF_ARYOK;
734 arg[2].arg_flags |= AF_ARYOK;
737 else if ((arg->arg_type == O_DEFINED || arg->arg_type == O_UNDEF) &&
738 (arg1->arg_type == (perldb ? O_DBSUBR : O_SUBR)) ) {
739 arg[1].arg_type |= A_DONT;
741 else if (arg1->arg_type == O_SUBSTR || arg1->arg_type == O_VEC) {
743 Renewc(arg1->arg_ptr.arg_str, 1, struct lstring, STR);
744 /* grow string struct to hold an lstring struct */
746 else if (arg1->arg_type == O_ASSIGN) {
747 /* if (arg->arg_type == O_CHOP)
748 arg[1].arg_flags &= ~AF_ARYOK; /* grandfather chop idiom */
751 (void)sprintf(tokenbuf,
752 "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);
755 arg[1].arg_type = A_LEXPR | (arg[1].arg_type & A_DONT);
756 if (arg->arg_type == O_ASSIGN && (arg1[1].arg_flags & AF_ARYOK)) {
757 arg[1].arg_flags |= AF_ARYOK;
758 if (arg->arg_len > 1)
759 arg[2].arg_flags |= AF_ARYOK;
763 fprintf(stderr,"lval LEXPR\n");
767 if (i == A_STAR || i == A_LSTAR) {
768 arg[1].arg_type = A_LSTAR | (arg[1].arg_type & A_DONT);
772 /* not an array reference, should be a register name */
774 if (i != A_STAB && i != A_LVAL) {
775 (void)sprintf(tokenbuf,
776 "Illegal item (%s) as lvalue",argname[arg[1].arg_type&A_MASK]);
779 arg[1].arg_type = A_LVAL | (arg[1].arg_type & A_DONT);
782 fprintf(stderr,"lval LVAL\n");
792 if (type == O_DEFINED || type == O_UNDEF) {
793 if (arg->arg_type != O_ITEM)
795 if (arg->arg_type == O_ITEM) {
796 type = arg[1].arg_type & A_MASK;
797 if (type == A_EXPR || type == A_LEXPR)
798 arg[1].arg_type = A_LEXPR|A_DONT;
809 if (arg[i].arg_type != A_EXPR) { /* dehoist */
810 tmparg = make_op(O_ITEM,1,Nullarg,Nullarg,Nullarg);
812 arg[i].arg_ptr.arg_arg = tmparg;
813 arg[i].arg_type = A_EXPR;
818 addflags(i,flags,arg)
821 arg[i].arg_flags |= flags;
829 if (arg->arg_type == O_ARRAY || arg->arg_type == O_HASH)
830 return make_op(O_ITEM,1,arg,Nullarg,Nullarg);
834 /* maybe do a join on multiple array dimensions */
840 if (arg && arg->arg_type == O_COMMA) {
842 arg = make_op(O_JOIN, 2,
843 stab2arg(A_STAB,stabent(";",TRUE)),
856 register ARG *nxtnode;
862 arg->arg_type = O_LIST;
864 if (arg->arg_type != O_COMMA) {
865 if (arg->arg_type != O_ARRAY)
866 arg->arg_flags |= AF_LISTISH; /* see listish() below */
867 arg->arg_flags |= AF_LISTISH; /* see listish() below */
870 for (i = 2, node = arg; ; i++) {
871 if (node->arg_len < 2)
873 if (node[1].arg_type != A_EXPR)
875 node = node[1].arg_ptr.arg_arg;
876 if (node->arg_type != O_COMMA)
882 tmpstr = arg->arg_ptr.arg_str;
884 *arg = *node; /* copy everything except the STR */
886 (void)bcopy((char *)node, (char *)arg, sizeof(ARG));
888 arg->arg_ptr.arg_str = tmpstr;
893 (void)bcopy((char *)(node+2), (char *)(arg+j), sizeof(ARG));
895 arg[j].arg_flags |= AF_ARYOK;
896 --j; /* Bug in Xenix compiler */
901 (void)bcopy((char *)(node+1), (char *)(arg+1), sizeof(ARG));
906 nxtnode = node[1].arg_ptr.arg_arg;
911 arg[1].arg_flags |= AF_ARYOK;
912 arg[2].arg_flags |= AF_ARYOK;
913 arg->arg_type = O_LIST;
918 /* turn a single item into a list */
924 if (arg->arg_flags & AF_LISTISH)
925 arg = make_op(O_LIST,1,arg,Nullarg,Nullarg);
930 maybelistish(optype, arg)
936 if (optype == O_RETURN && arg->arg_type == O_ITEM &&
937 arg[1].arg_type == A_EXPR && (tmparg = arg[1].arg_ptr.arg_arg) &&
938 ((tmparg->arg_flags & AF_LISTISH) || (tmparg->arg_type == O_ARRAY) )) {
939 tmparg = listish(tmparg);
943 else if (optype == O_PRTF ||
944 (arg->arg_type == O_ASLICE || arg->arg_type == O_HSLICE ||
945 arg->arg_type == O_F_OR_R) )
950 /* mark list of local variables */
956 arg->arg_flags |= AF_LOCAL;
966 if (arg->arg_type == O_CONCAT && arg[2].arg_type == A_EXPR) {
967 arg2 = arg[2].arg_ptr.arg_arg;
968 if (arg2->arg_type == O_ITEM && arg2[1].arg_type == A_READ) {
969 arg->arg_type = O_RCAT;
970 arg[2].arg_type = arg2[1].arg_type;
971 arg[2].arg_ptr = arg2[1].arg_ptr;
986 arg->arg_type = O_ITEM;
987 arg[1].arg_type = atype;
988 arg[1].arg_ptr.arg_stab = stab;
999 arg->arg_type = O_ITEM;
1000 arg[1].arg_type = A_SINGLE;
1001 arg[1].arg_ptr.arg_str = str_make(cval,0);
1012 Newz(203,arg, numargs + 1, ARG);
1013 arg->arg_ptr.arg_str = Str_new(21,0);
1014 arg->arg_len = numargs;
1022 str_free(arg->arg_ptr.arg_str);
1027 make_match(type,expr,spat)
1034 arg = make_op(type,2,expr,Nullarg,Nullarg);
1036 arg[2].arg_type = A_SPAT|A_DONT;
1037 arg[2].arg_ptr.arg_spat = spat;
1040 fprintf(stderr,"make_match SPAT=%lx\n",(long)spat);
1043 if (type == O_SUBST || type == O_NSUBST) {
1044 if (arg[1].arg_type != A_STAB) {
1045 yyerror("Illegal lvalue");
1047 arg[1].arg_type = A_LVAL;
1059 arg->arg_type = O_ITEM;
1060 arg[1].arg_type = A_CMD;
1061 arg[1].arg_ptr.arg_cmd = cmd;
1065 /* Check two expressions to see if there is any identifier in common */
1068 nothing_in_common(arg1,arg2)
1072 static int thisexpr = 0; /* I don't care if this wraps */
1075 if (arg_common(arg1,thisexpr,1))
1076 return 0; /* hit eval or do {} */
1077 stab_lastexpr(defstab) = thisexpr; /* pretend to hit @_ */
1078 if (arg_common(arg2,thisexpr,0))
1079 return 0; /* hit identifier again */
1083 /* Recursively descend an expression and mark any identifier or check
1084 * it to see if it was marked already.
1088 arg_common(arg,exprnum,marking)
1097 for (i = arg->arg_len; i >= 1; i--) {
1098 switch (arg[i].arg_type & A_MASK) {
1103 if (arg_common(arg[i].arg_ptr.arg_arg,exprnum,marking))
1107 return 1; /* assume hanky panky */
1115 stab_lastexpr(arg[i].arg_ptr.arg_stab) = exprnum;
1116 else if (stab_lastexpr(arg[i].arg_ptr.arg_stab) == exprnum)
1122 register char *s = arg[i].arg_ptr.arg_str->str_ptr;
1123 register char *send = s + arg[i].arg_ptr.arg_str->str_cur;
1124 register STAB *stab;
1127 if (*s == '$' && s[1]) {
1128 s = scanident(s,send,tokenbuf);
1129 stab = stabent(tokenbuf,TRUE);
1131 stab_lastexpr(stab) = exprnum;
1132 else if (stab_lastexpr(stab) == exprnum)
1136 else if (*s == '\\' && s[1])
1143 if (spat_common(arg[i].arg_ptr.arg_spat,exprnum,marking))
1154 switch (arg->arg_type) {
1157 if ((arg[1].arg_type & A_MASK) == A_STAB)
1158 (void)aadd(arg[1].arg_ptr.arg_stab);
1162 if ((arg[1].arg_type & A_MASK) == A_STAB)
1163 (void)hadd(arg[1].arg_ptr.arg_stab);
1174 spat_common(spat,exprnum,marking)
1175 register SPAT *spat;
1179 if (spat->spat_runtime)
1180 if (arg_common(spat->spat_runtime,exprnum,marking))
1182 if (spat->spat_repl) {
1183 if (arg_common(spat->spat_repl,exprnum,marking))