1 /* $RCSfile: consarg.c,v $$Revision: 4.0.1.2 $$Date: 91/06/07 10:33:12 $
3 * Copyright (c) 1991, Larry Wall
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
9 * Revision 4.0.1.2 91/06/07 10:33:12 lwall
10 * patch4: new copyright notice
11 * patch4: length($`), length($&), length($') now optimized to avoid string copy
13 * Revision 4.0.1.1 91/04/11 17:38:34 lwall
14 * patch1: fixed "Bad free" error
16 * Revision 4.0 91/03/20 01:06:15 lwall
23 static int nothing_in_common();
24 static int arg_common();
25 static int spat_common();
28 make_split(stab,arg,limarg)
35 if (arg->arg_type != O_MATCH) {
36 Newz(201,spat,1,SPAT);
37 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
38 curstash->tbl_spatroot = spat;
40 spat->spat_runtime = arg;
41 arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
46 if (limarg->arg_type == O_ITEM) {
47 Copy(limarg+1,arg+3,1,ARG);
48 limarg[1].arg_type = A_NULL;
53 arg[3].arg_type = A_EXPR;
54 arg[3].arg_ptr.arg_arg = limarg;
58 arg[3].arg_type = A_NULL;
59 arg->arg_type = O_SPLIT;
60 spat = arg[2].arg_ptr.arg_spat;
61 spat->spat_repl = stab2arg(A_STAB,aadd(stab));
62 if (spat->spat_short) { /* exact match can bypass regexec() */
63 if (!((spat->spat_flags & SPAT_SCANFIRST) &&
64 (spat->spat_flags & SPAT_ALL) )) {
65 str_free(spat->spat_short);
66 spat->spat_short = Nullstr;
73 mod_match(type,left,pat)
84 if ((pat->arg_type == O_MATCH ||
85 pat->arg_type == O_SUBST ||
86 pat->arg_type == O_TRANS ||
87 pat->arg_type == O_SPLIT
89 pat[1].arg_ptr.arg_stab == defstab ) {
90 switch (pat->arg_type) {
92 newarg = make_op(type == O_MATCH ? O_MATCH : O_NMATCH,
94 left,Nullarg,Nullarg);
97 newarg = l(make_op(type == O_MATCH ? O_SUBST : O_NSUBST,
99 left,Nullarg,Nullarg));
102 newarg = l(make_op(type == O_MATCH ? O_TRANS : O_NTRANS,
104 left,Nullarg,Nullarg));
107 newarg = make_op(type == O_MATCH ? O_SPLIT : O_SPLIT,
109 left,Nullarg,Nullarg);
112 if (pat->arg_len >= 2) {
113 newarg[2].arg_type = pat[2].arg_type;
114 newarg[2].arg_ptr = pat[2].arg_ptr;
115 newarg[2].arg_len = pat[2].arg_len;
116 newarg[2].arg_flags = pat[2].arg_flags;
117 if (pat->arg_len >= 3) {
118 newarg[3].arg_type = pat[3].arg_type;
119 newarg[3].arg_ptr = pat[3].arg_ptr;
120 newarg[3].arg_len = pat[3].arg_len;
121 newarg[3].arg_flags = pat[3].arg_flags;
127 Newz(202,spat,1,SPAT);
128 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
129 curstash->tbl_spatroot = spat;
131 spat->spat_runtime = pat;
132 newarg = make_op(type,2,left,Nullarg,Nullarg);
133 newarg[2].arg_type = A_SPAT | A_DONT;
134 newarg[2].arg_ptr.arg_spat = spat;
141 make_op(type,newlen,arg1,arg2,arg3)
150 register unsigned doarg;
152 extern ARG *arg4; /* should be normal arguments, really */
155 arg = op_new(newlen);
156 arg->arg_type = type;
158 if (chld->arg_type == O_ITEM &&
159 (hoistable[ i = (chld[1].arg_type&A_MASK)] || i == A_LVAL ||
161 (chld[1].arg_ptr.arg_arg->arg_type == O_LIST ||
162 chld[1].arg_ptr.arg_arg->arg_type == O_ARRAY ||
163 chld[1].arg_ptr.arg_arg->arg_type == O_HASH ))))
165 arg[1].arg_type = chld[1].arg_type;
166 arg[1].arg_ptr = chld[1].arg_ptr;
167 arg[1].arg_flags |= chld[1].arg_flags;
168 arg[1].arg_len = chld[1].arg_len;
172 arg[1].arg_type = A_EXPR;
173 arg[1].arg_ptr.arg_arg = chld;
177 if (chld->arg_type == O_ITEM &&
178 (hoistable[chld[1].arg_type&A_MASK] ||
180 ((chld[1].arg_type == A_READ && !(arg[1].arg_type & A_DONT))
182 (chld[1].arg_type == A_INDREAD && !(arg[1].arg_type & A_DONT))
184 (chld[1].arg_type == A_GLOB && !(arg[1].arg_type & A_DONT))
186 arg[2].arg_type = chld[1].arg_type;
187 arg[2].arg_ptr = chld[1].arg_ptr;
188 arg[2].arg_len = chld[1].arg_len;
192 arg[2].arg_type = A_EXPR;
193 arg[2].arg_ptr.arg_arg = chld;
197 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type&A_MASK]) {
198 arg[3].arg_type = chld[1].arg_type;
199 arg[3].arg_ptr = chld[1].arg_ptr;
200 arg[3].arg_len = chld[1].arg_len;
204 arg[3].arg_type = A_EXPR;
205 arg[3].arg_ptr.arg_arg = chld;
208 if (newlen >= 4 && (chld = arg4)) {
209 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type&A_MASK]) {
210 arg[4].arg_type = chld[1].arg_type;
211 arg[4].arg_ptr = chld[1].arg_ptr;
212 arg[4].arg_len = chld[1].arg_len;
216 arg[4].arg_type = A_EXPR;
217 arg[4].arg_ptr.arg_arg = chld;
220 if (newlen >= 5 && (chld = arg5)) {
221 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type&A_MASK]) {
222 arg[5].arg_type = chld[1].arg_type;
223 arg[5].arg_ptr = chld[1].arg_ptr;
224 arg[5].arg_len = chld[1].arg_len;
228 arg[5].arg_type = A_EXPR;
229 arg[5].arg_ptr.arg_arg = chld;
232 doarg = opargs[type];
233 for (i = 1; i <= newlen; ++i) {
235 arg[i].arg_type |= A_DONT;
237 arg[i].arg_flags |= AF_ARYOK;
242 fprintf(stderr,"%lx <= make_op(%s",arg,opname[arg->arg_type]);
244 fprintf(stderr,",%s=%lx",
245 argname[arg[1].arg_type&A_MASK],arg[1].arg_ptr.arg_arg);
247 fprintf(stderr,",%s=%lx",
248 argname[arg[2].arg_type&A_MASK],arg[2].arg_ptr.arg_arg);
250 fprintf(stderr,",%s=%lx",
251 argname[arg[3].arg_type&A_MASK],arg[3].arg_ptr.arg_arg);
253 fprintf(stderr,",%s=%lx",
254 argname[arg[4].arg_type&A_MASK],arg[4].arg_ptr.arg_arg);
256 fprintf(stderr,",%s=%lx",
257 argname[arg[5].arg_type&A_MASK],arg[5].arg_ptr.arg_arg);
258 fprintf(stderr,")\n");
261 arg = evalstatic(arg); /* see if we can consolidate anything */
269 static STR *str = Nullstr;
272 double value; /* must not be register */
275 unsigned long tmplong;
277 double exp(), log(), sqrt(), modf();
279 double sin(), cos(), atan2(), pow();
281 if (!arg || !arg->arg_len)
287 if (arg[1].arg_type == A_SINGLE)
288 s1 = arg[1].arg_ptr.arg_str;
291 if (arg->arg_len >= 2 && arg[2].arg_type == A_SINGLE)
292 s2 = arg[2].arg_ptr.arg_str;
296 #define CHECK1 if (!s1) return arg
297 #define CHECK2 if (!s2) return arg
298 #define CHECK12 if (!s1 || !s2) return arg
300 switch (arg->arg_type) {
305 i = (int)str_gnum(s2);
306 if (i < 32767 && i >= 0) {
307 arg->arg_type = O_ITEM;
309 arg[1].arg_type = A_ARYSTAB; /* $abc[123] is hoistable now */
322 i = (int)str_gnum(s2);
325 STR_GROW(str, i * s1->str_cur + 1);
326 repeatcpy(str->str_ptr, tmps, s1->str_cur, i);
327 str->str_cur = i * s1->str_cur;
328 str->str_ptr[str->str_cur] = '\0';
332 value = str_gnum(s1);
333 str_numset(str,value * str_gnum(s2));
337 value = str_gnum(s2);
339 yyerror("Illegal division by constant zero");
342 /* insure that 20./5. == 4. */
347 if ((double)(int)x == x &&
348 (double)(int)value == value &&
349 (k = (int)x/(int)value)*(int)value == (int)x) {
354 str_numset(str,value);
357 str_numset(str,str_gnum(s1) / value);
362 tmplong = (unsigned long)str_gnum(s2);
364 yyerror("Illegal modulus of constant zero");
367 tmp2 = (long)str_gnum(s1);
370 str_numset(str,(double)(tmp2 % tmplong));
372 str_numset(str,(double)((tmplong-((-tmp2 - 1) % tmplong)) - 1));
379 value = str_gnum(s1);
380 str_numset(str,value + str_gnum(s2));
384 value = str_gnum(s1);
385 str_numset(str,value - str_gnum(s2));
389 value = str_gnum(s1);
390 i = (int)str_gnum(s2);
392 str_numset(str,(double)(((long)value) << i));
397 value = str_gnum(s1);
398 i = (int)str_gnum(s2);
400 str_numset(str,(double)(((long)value) >> i));
405 value = str_gnum(s1);
406 str_numset(str,(value < str_gnum(s2)) ? 1.0 : 0.0);
410 value = str_gnum(s1);
411 str_numset(str,(value > str_gnum(s2)) ? 1.0 : 0.0);
415 value = str_gnum(s1);
416 str_numset(str,(value <= str_gnum(s2)) ? 1.0 : 0.0);
420 value = str_gnum(s1);
421 str_numset(str,(value >= str_gnum(s2)) ? 1.0 : 0.0);
426 if ((!s1->str_nok && !looks_like_number(s1)) ||
427 (!s2->str_nok && !looks_like_number(s2)) )
428 warn("Possible use of == on string value");
430 value = str_gnum(s1);
431 str_numset(str,(value == str_gnum(s2)) ? 1.0 : 0.0);
435 value = str_gnum(s1);
436 str_numset(str,(value != str_gnum(s2)) ? 1.0 : 0.0);
440 value = str_gnum(s1);
441 value -= str_gnum(s2);
444 else if (value < 0.0)
446 str_numset(str,value);
450 value = str_gnum(s1);
452 str_numset(str,(double)(U_L(value) & U_L(str_gnum(s2))));
457 value = str_gnum(s1);
459 str_numset(str,(double)(U_L(value) ^ U_L(str_gnum(s2))));
464 value = str_gnum(s1);
466 str_numset(str,(double)(U_L(value) | U_L(str_gnum(s2))));
485 if ((arg[3].arg_type & A_MASK) != A_SINGLE)
490 str_sset(str,arg[3].arg_ptr.arg_str);
491 str_free(arg[3].arg_ptr.arg_str);
496 str_numset(str,(double)(-str_gnum(s1)));
500 str_numset(str,(double)(!str_true(s1)));
505 str_numset(str,(double)(~U_L(str_gnum(s1))));
510 str_numset(str,sin(str_gnum(s1)));
514 str_numset(str,cos(str_gnum(s1)));
518 value = str_gnum(s1);
519 str_numset(str,atan2(value, str_gnum(s2)));
523 value = str_gnum(s1);
524 str_numset(str,pow(value, str_gnum(s2)));
527 if (arg[1].arg_type == A_STAB) {
528 arg->arg_type = O_ITEM;
529 arg[1].arg_type = A_LENSTAB;
533 str_numset(str, (double)str_len(s1));
537 str_numset(str,(double)(str_cmp(s1,s2) < 0));
541 str_numset(str,(double)(str_cmp(s1,s2) > 0));
545 str_numset(str,(double)(str_cmp(s1,s2) <= 0));
549 str_numset(str,(double)(str_cmp(s1,s2) >= 0));
553 str_numset(str,(double)(str_eq(s1,s2)));
557 str_numset(str,(double)(!str_eq(s1,s2)));
561 str_numset(str,(double)(str_cmp(s1,s2)));
567 str_set(str,crypt(tmps,str_get(s2)));
570 "The crypt() function is unimplemented due to excessive paranoia.");
575 str_numset(str,exp(str_gnum(s1)));
579 str_numset(str,log(str_gnum(s1)));
583 str_numset(str,sqrt(str_gnum(s1)));
587 value = str_gnum(s1);
589 (void)modf(value,&value);
591 (void)modf(-value,&value);
594 str_numset(str,value);
599 str_numset(str,(double)(*str_get(s1)));
607 str_numset(str,(double)(zapc));
612 arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */
614 arg[1].arg_ptr.arg_str = str;
617 arg[2].arg_ptr.arg_str = Nullstr;
618 arg[2].arg_type = A_NULL;
635 i = arg[1].arg_type & A_MASK;
637 arg->arg_flags |= AF_COMMON; /* assume something in common */
638 /* which forces us to copy things */
641 arg[1].arg_type = A_LARYLEN;
644 if (i == A_ARYSTAB) {
645 arg[1].arg_type = A_LARYSTAB;
649 /* see if it's an array reference */
651 if (i == A_EXPR || i == A_LEXPR) {
652 arg1 = arg[1].arg_ptr.arg_arg;
654 if (arg1->arg_type == O_LIST || arg1->arg_type == O_ITEM) {
656 if (arg->arg_len > 1) {
658 arg2 = arg[2].arg_ptr.arg_arg;
659 if (nothing_in_common(arg1,arg2))
660 arg->arg_flags &= ~AF_COMMON;
661 if (arg->arg_type == O_ASSIGN) {
662 if (arg1->arg_flags & AF_LOCAL)
663 arg->arg_flags |= AF_LOCAL;
664 arg[1].arg_flags |= AF_ARYOK;
665 arg[2].arg_flags |= AF_ARYOK;
668 else if (arg->arg_type != O_CHOP)
669 arg->arg_type = O_ASSIGN; /* possible local(); */
670 for (i = arg1->arg_len; i >= 1; i--) {
671 switch (arg1[i].arg_type) {
672 case A_STAR: case A_LSTAR:
673 arg1[i].arg_type = A_LSTAR;
675 case A_STAB: case A_LVAL:
676 arg1[i].arg_type = A_LVAL;
678 case A_ARYLEN: case A_LARYLEN:
679 arg1[i].arg_type = A_LARYLEN;
681 case A_ARYSTAB: case A_LARYSTAB:
682 arg1[i].arg_type = A_LARYSTAB;
684 case A_EXPR: case A_LEXPR:
685 arg1[i].arg_type = A_LEXPR;
686 switch(arg1[i].arg_ptr.arg_arg->arg_type) {
687 case O_ARRAY: case O_LARRAY:
688 arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;
691 case O_AELEM: case O_LAELEM:
692 arg1[i].arg_ptr.arg_arg->arg_type = O_LAELEM;
694 case O_HASH: case O_LHASH:
695 arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;
698 case O_HELEM: case O_LHELEM:
699 arg1[i].arg_ptr.arg_arg->arg_type = O_LHELEM;
701 case O_ASLICE: case O_LASLICE:
702 arg1[i].arg_ptr.arg_arg->arg_type = O_LASLICE;
704 case O_HSLICE: case O_LHSLICE:
705 arg1[i].arg_ptr.arg_arg->arg_type = O_LHSLICE;
713 (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue",
714 argname[arg1[i].arg_type&A_MASK]);
718 if (arg->arg_len > 1) {
719 if (arg2->arg_type == O_SPLIT && !arg2[3].arg_type && !arghog) {
720 arg2[3].arg_type = A_SINGLE;
721 arg2[3].arg_ptr.arg_str =
722 str_nmake((double)arg1->arg_len + 1); /* limit split len*/
726 else if (arg1->arg_type == O_AELEM || arg1->arg_type == O_LAELEM)
727 if (arg->arg_type == O_DEFINED)
728 arg1->arg_type = O_AELEM;
730 arg1->arg_type = O_LAELEM;
731 else if (arg1->arg_type == O_ARRAY || arg1->arg_type == O_LARRAY) {
732 arg1->arg_type = O_LARRAY;
733 if (arg->arg_len > 1) {
735 arg2 = arg[2].arg_ptr.arg_arg;
736 if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/
737 spat = arg2[2].arg_ptr.arg_spat;
738 if (!(spat->spat_flags & SPAT_ONCE) &&
739 nothing_in_common(arg1,spat->spat_repl)) {
740 spat->spat_repl[1].arg_ptr.arg_stab =
741 arg1[1].arg_ptr.arg_stab;
742 arg1[1].arg_ptr.arg_stab = Nullstab;
743 spat->spat_flags |= SPAT_ONCE;
744 arg_free(arg1); /* recursive */
745 arg[1].arg_ptr.arg_arg = Nullarg;
746 free_arg(arg); /* non-recursive */
747 return arg2; /* split has builtin assign */
750 else if (nothing_in_common(arg1,arg2))
751 arg->arg_flags &= ~AF_COMMON;
752 if (arg->arg_type == O_ASSIGN) {
753 arg[1].arg_flags |= AF_ARYOK;
754 arg[2].arg_flags |= AF_ARYOK;
757 else if (arg->arg_type == O_ASSIGN)
758 arg[1].arg_flags |= AF_ARYOK;
760 else if (arg1->arg_type == O_HELEM || arg1->arg_type == O_LHELEM)
761 if (arg->arg_type == O_DEFINED)
762 arg1->arg_type = O_HELEM; /* avoid creating one */
764 arg1->arg_type = O_LHELEM;
765 else if (arg1->arg_type == O_HASH || arg1->arg_type == O_LHASH) {
766 arg1->arg_type = O_LHASH;
767 if (arg->arg_len > 1) {
769 arg2 = arg[2].arg_ptr.arg_arg;
770 if (nothing_in_common(arg1,arg2))
771 arg->arg_flags &= ~AF_COMMON;
772 if (arg->arg_type == O_ASSIGN) {
773 arg[1].arg_flags |= AF_ARYOK;
774 arg[2].arg_flags |= AF_ARYOK;
777 else if (arg->arg_type == O_ASSIGN)
778 arg[1].arg_flags |= AF_ARYOK;
780 else if (arg1->arg_type == O_ASLICE) {
781 arg1->arg_type = O_LASLICE;
782 if (arg->arg_type == O_ASSIGN) {
784 arg[1].arg_flags |= AF_ARYOK;
785 arg[2].arg_flags |= AF_ARYOK;
788 else if (arg1->arg_type == O_HSLICE) {
789 arg1->arg_type = O_LHSLICE;
790 if (arg->arg_type == O_ASSIGN) {
792 arg[1].arg_flags |= AF_ARYOK;
793 arg[2].arg_flags |= AF_ARYOK;
796 else if ((arg->arg_type == O_DEFINED || arg->arg_type == O_UNDEF) &&
797 (arg1->arg_type == (perldb ? O_DBSUBR : O_SUBR)) ) {
798 arg[1].arg_type |= A_DONT;
800 else if (arg1->arg_type == O_SUBSTR || arg1->arg_type == O_VEC) {
802 Renewc(arg1->arg_ptr.arg_str, 1, struct lstring, STR);
803 /* grow string struct to hold an lstring struct */
805 else if (arg1->arg_type == O_ASSIGN) {
806 /* if (arg->arg_type == O_CHOP)
807 arg[1].arg_flags &= ~AF_ARYOK; /* grandfather chop idiom */
810 (void)sprintf(tokenbuf,
811 "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);
814 arg[1].arg_type = A_LEXPR | (arg[1].arg_type & A_DONT);
815 if (arg->arg_type == O_ASSIGN && (arg1[1].arg_flags & AF_ARYOK)) {
816 arg[1].arg_flags |= AF_ARYOK;
817 if (arg->arg_len > 1)
818 arg[2].arg_flags |= AF_ARYOK;
822 fprintf(stderr,"lval LEXPR\n");
826 if (i == A_STAR || i == A_LSTAR) {
827 arg[1].arg_type = A_LSTAR | (arg[1].arg_type & A_DONT);
831 /* not an array reference, should be a register name */
833 if (i != A_STAB && i != A_LVAL) {
834 (void)sprintf(tokenbuf,
835 "Illegal item (%s) as lvalue",argname[arg[1].arg_type&A_MASK]);
838 arg[1].arg_type = A_LVAL | (arg[1].arg_type & A_DONT);
841 fprintf(stderr,"lval LVAL\n");
851 if (type == O_DEFINED || type == O_UNDEF) {
852 if (arg->arg_type != O_ITEM)
854 if (arg->arg_type == O_ITEM) {
855 type = arg[1].arg_type & A_MASK;
856 if (type == A_EXPR || type == A_LEXPR)
857 arg[1].arg_type = A_LEXPR|A_DONT;
868 if (arg[i].arg_type != A_EXPR) { /* dehoist */
869 tmparg = make_op(O_ITEM,1,Nullarg,Nullarg,Nullarg);
871 arg[i].arg_ptr.arg_arg = tmparg;
872 arg[i].arg_type = A_EXPR;
877 addflags(i,flags,arg)
880 arg[i].arg_flags |= flags;
888 if (arg->arg_type == O_ARRAY || arg->arg_type == O_HASH)
889 return make_op(O_ITEM,1,arg,Nullarg,Nullarg);
893 /* maybe do a join on multiple array dimensions */
899 if (arg && arg->arg_type == O_COMMA) {
901 arg = make_op(O_JOIN, 2,
902 stab2arg(A_STAB,stabent(";",TRUE)),
915 register ARG *nxtnode;
921 arg->arg_type = O_LIST;
923 if (arg->arg_type != O_COMMA) {
924 if (arg->arg_type != O_ARRAY)
925 arg->arg_flags |= AF_LISTISH; /* see listish() below */
926 arg->arg_flags |= AF_LISTISH; /* see listish() below */
929 for (i = 2, node = arg; ; i++) {
930 if (node->arg_len < 2)
932 if (node[1].arg_type != A_EXPR)
934 node = node[1].arg_ptr.arg_arg;
935 if (node->arg_type != O_COMMA)
941 tmpstr = arg->arg_ptr.arg_str;
943 *arg = *node; /* copy everything except the STR */
945 (void)bcopy((char *)node, (char *)arg, sizeof(ARG));
947 arg->arg_ptr.arg_str = tmpstr;
952 (void)bcopy((char *)(node+2), (char *)(arg+j), sizeof(ARG));
954 arg[j].arg_flags |= AF_ARYOK;
955 --j; /* Bug in Xenix compiler */
960 (void)bcopy((char *)(node+1), (char *)(arg+1), sizeof(ARG));
965 nxtnode = node[1].arg_ptr.arg_arg;
970 arg[1].arg_flags |= AF_ARYOK;
971 arg[2].arg_flags |= AF_ARYOK;
972 arg->arg_type = O_LIST;
977 /* turn a single item into a list */
983 if (arg->arg_flags & AF_LISTISH)
984 arg = make_op(O_LIST,1,arg,Nullarg,Nullarg);
989 maybelistish(optype, arg)
995 if (optype == O_RETURN && arg->arg_type == O_ITEM &&
996 arg[1].arg_type == A_EXPR && (tmparg = arg[1].arg_ptr.arg_arg) &&
997 ((tmparg->arg_flags & AF_LISTISH) || (tmparg->arg_type == O_ARRAY) )) {
998 tmparg = listish(tmparg);
1002 else if (optype == O_PRTF ||
1003 (arg->arg_type == O_ASLICE || arg->arg_type == O_HSLICE ||
1004 arg->arg_type == O_F_OR_R) )
1009 /* mark list of local variables */
1015 arg->arg_flags |= AF_LOCAL;
1025 if (arg->arg_type == O_CONCAT && arg[2].arg_type == A_EXPR) {
1026 arg2 = arg[2].arg_ptr.arg_arg;
1027 if (arg2->arg_type == O_ITEM && arg2[1].arg_type == A_READ) {
1028 arg->arg_type = O_RCAT;
1029 arg[2].arg_type = arg2[1].arg_type;
1030 arg[2].arg_ptr = arg2[1].arg_ptr;
1038 stab2arg(atype,stab)
1040 register STAB *stab;
1045 arg->arg_type = O_ITEM;
1046 arg[1].arg_type = atype;
1047 arg[1].arg_ptr.arg_stab = stab;
1053 register char *cval;
1058 arg->arg_type = O_ITEM;
1059 arg[1].arg_type = A_SINGLE;
1060 arg[1].arg_ptr.arg_str = str_make(cval,0);
1071 Newz(203,arg, numargs + 1, ARG);
1072 arg->arg_ptr.arg_str = Str_new(21,0);
1073 arg->arg_len = numargs;
1081 str_free(arg->arg_ptr.arg_str);
1086 make_match(type,expr,spat)
1093 arg = make_op(type,2,expr,Nullarg,Nullarg);
1095 arg[2].arg_type = A_SPAT|A_DONT;
1096 arg[2].arg_ptr.arg_spat = spat;
1099 fprintf(stderr,"make_match SPAT=%lx\n",(long)spat);
1102 if (type == O_SUBST || type == O_NSUBST) {
1103 if (arg[1].arg_type != A_STAB) {
1104 yyerror("Illegal lvalue");
1106 arg[1].arg_type = A_LVAL;
1118 arg->arg_type = O_ITEM;
1119 arg[1].arg_type = A_CMD;
1120 arg[1].arg_ptr.arg_cmd = cmd;
1124 /* Check two expressions to see if there is any identifier in common */
1127 nothing_in_common(arg1,arg2)
1131 static int thisexpr = 0; /* I don't care if this wraps */
1134 if (arg_common(arg1,thisexpr,1))
1135 return 0; /* hit eval or do {} */
1136 stab_lastexpr(defstab) = thisexpr; /* pretend to hit @_ */
1137 if (arg_common(arg2,thisexpr,0))
1138 return 0; /* hit identifier again */
1142 /* Recursively descend an expression and mark any identifier or check
1143 * it to see if it was marked already.
1147 arg_common(arg,exprnum,marking)
1156 for (i = arg->arg_len; i >= 1; i--) {
1157 switch (arg[i].arg_type & A_MASK) {
1162 if (arg_common(arg[i].arg_ptr.arg_arg,exprnum,marking))
1166 return 1; /* assume hanky panky */
1174 stab_lastexpr(arg[i].arg_ptr.arg_stab) = exprnum;
1175 else if (stab_lastexpr(arg[i].arg_ptr.arg_stab) == exprnum)
1181 register char *s = arg[i].arg_ptr.arg_str->str_ptr;
1182 register char *send = s + arg[i].arg_ptr.arg_str->str_cur;
1183 register STAB *stab;
1186 if (*s == '$' && s[1]) {
1187 s = scanident(s,send,tokenbuf);
1188 stab = stabent(tokenbuf,TRUE);
1190 stab_lastexpr(stab) = exprnum;
1191 else if (stab_lastexpr(stab) == exprnum)
1195 else if (*s == '\\' && s[1])
1202 if (spat_common(arg[i].arg_ptr.arg_spat,exprnum,marking))
1213 switch (arg->arg_type) {
1216 if ((arg[1].arg_type & A_MASK) == A_STAB)
1217 (void)aadd(arg[1].arg_ptr.arg_stab);
1221 if ((arg[1].arg_type & A_MASK) == A_STAB)
1222 (void)hadd(arg[1].arg_ptr.arg_stab);
1233 spat_common(spat,exprnum,marking)
1234 register SPAT *spat;
1238 if (spat->spat_runtime)
1239 if (arg_common(spat->spat_runtime,exprnum,marking))
1241 if (spat->spat_repl) {
1242 if (arg_common(spat->spat_repl,exprnum,marking))