1 /* $RCSfile: consarg.c,v $$Revision: 4.0.1.4 $$Date: 92/06/08 12:26:27 $
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.4 92/06/08 12:26:27 lwall
10 * patch20: new warning for use of x with non-numeric right operand
11 * patch20: modulus with highest bit in left operand set didn't always work
12 * patch20: illegal lvalue message could be followed by core dump
13 * patch20: deleted some minor memory leaks
15 * Revision 4.0.1.3 91/11/05 16:21:16 lwall
16 * patch11: random cleanup
17 * patch11: added eval {}
18 * patch11: added sort {} LIST
19 * patch11: "foo" x -1 dumped core
20 * patch11: substr() and vec() weren't allowed in an lvalue list
22 * Revision 4.0.1.2 91/06/07 10:33:12 lwall
23 * patch4: new copyright notice
24 * patch4: length($`), length($&), length($') now optimized to avoid string copy
26 * Revision 4.0.1.1 91/04/11 17:38:34 lwall
27 * patch1: fixed "Bad free" error
29 * Revision 4.0 91/03/20 01:06:15 lwall
36 static int nothing_in_common();
37 static int arg_common();
38 static int spat_common();
41 make_split(stab,arg,limarg)
48 if (arg->arg_type != O_MATCH) {
49 Newz(201,spat,1,SPAT);
50 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
51 curstash->tbl_spatroot = spat;
53 spat->spat_runtime = arg;
54 arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
59 if (limarg->arg_type == O_ITEM) {
60 Copy(limarg+1,arg+3,1,ARG);
61 limarg[1].arg_type = A_NULL;
67 arg[3].arg_type = A_EXPR;
68 arg[3].arg_ptr.arg_arg = limarg;
74 arg[3].arg_type = A_NULL;
75 arg[3].arg_ptr.arg_arg = Nullarg;
77 arg->arg_type = O_SPLIT;
78 spat = arg[2].arg_ptr.arg_spat;
79 spat->spat_repl = stab2arg(A_STAB,aadd(stab));
80 if (spat->spat_short) { /* exact match can bypass regexec() */
81 if (!((spat->spat_flags & SPAT_SCANFIRST) &&
82 (spat->spat_flags & SPAT_ALL) )) {
83 str_free(spat->spat_short);
84 spat->spat_short = Nullstr;
91 mod_match(type,left,pat)
102 if ((pat->arg_type == O_MATCH ||
103 pat->arg_type == O_SUBST ||
104 pat->arg_type == O_TRANS ||
105 pat->arg_type == O_SPLIT
107 pat[1].arg_ptr.arg_stab == defstab ) {
108 switch (pat->arg_type) {
110 newarg = make_op(type == O_MATCH ? O_MATCH : O_NMATCH,
112 left,Nullarg,Nullarg);
115 newarg = l(make_op(type == O_MATCH ? O_SUBST : O_NSUBST,
117 left,Nullarg,Nullarg));
120 newarg = l(make_op(type == O_MATCH ? O_TRANS : O_NTRANS,
122 left,Nullarg,Nullarg));
125 newarg = make_op(type == O_MATCH ? O_SPLIT : O_SPLIT,
127 left,Nullarg,Nullarg);
130 if (pat->arg_len >= 2) {
131 newarg[2].arg_type = pat[2].arg_type;
132 newarg[2].arg_ptr = pat[2].arg_ptr;
133 newarg[2].arg_len = pat[2].arg_len;
134 newarg[2].arg_flags = pat[2].arg_flags;
135 if (pat->arg_len >= 3) {
136 newarg[3].arg_type = pat[3].arg_type;
137 newarg[3].arg_ptr = pat[3].arg_ptr;
138 newarg[3].arg_len = pat[3].arg_len;
139 newarg[3].arg_flags = pat[3].arg_flags;
145 Newz(202,spat,1,SPAT);
146 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
147 curstash->tbl_spatroot = spat;
149 spat->spat_runtime = pat;
150 newarg = make_op(type,2,left,Nullarg,Nullarg);
151 newarg[2].arg_type = A_SPAT | A_DONT;
152 newarg[2].arg_ptr.arg_spat = spat;
159 make_op(type,newlen,arg1,arg2,arg3)
168 register unsigned doarg;
170 extern ARG *arg4; /* should be normal arguments, really */
173 arg = op_new(newlen);
174 arg->arg_type = type;
177 if (chld->arg_type == O_ITEM &&
178 (hoistable[ i = (chld[1].arg_type&A_MASK)] || i == A_LVAL ||
180 (chld[1].arg_ptr.arg_arg->arg_type == O_LIST ||
181 chld[1].arg_ptr.arg_arg->arg_type == O_ARRAY ||
182 chld[1].arg_ptr.arg_arg->arg_type == O_HASH ))))
184 arg[1].arg_type = chld[1].arg_type;
185 arg[1].arg_ptr = chld[1].arg_ptr;
186 arg[1].arg_flags |= chld[1].arg_flags;
187 arg[1].arg_len = chld[1].arg_len;
191 arg[1].arg_type = A_EXPR;
192 arg[1].arg_ptr.arg_arg = chld;
197 if (chld->arg_type == O_ITEM &&
198 (hoistable[chld[1].arg_type&A_MASK] ||
200 ((chld[1].arg_type == A_READ && !(arg[1].arg_type & A_DONT))
202 (chld[1].arg_type == A_INDREAD && !(arg[1].arg_type & A_DONT))
204 (chld[1].arg_type == A_GLOB && !(arg[1].arg_type & A_DONT))
206 arg[2].arg_type = chld[1].arg_type;
207 arg[2].arg_ptr = chld[1].arg_ptr;
208 arg[2].arg_len = chld[1].arg_len;
212 arg[2].arg_type = A_EXPR;
213 arg[2].arg_ptr.arg_arg = chld;
218 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type&A_MASK]) {
219 arg[3].arg_type = chld[1].arg_type;
220 arg[3].arg_ptr = chld[1].arg_ptr;
221 arg[3].arg_len = chld[1].arg_len;
225 arg[3].arg_type = A_EXPR;
226 arg[3].arg_ptr.arg_arg = chld;
229 if (newlen >= 4 && (chld = arg4)) {
230 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type&A_MASK]) {
231 arg[4].arg_type = chld[1].arg_type;
232 arg[4].arg_ptr = chld[1].arg_ptr;
233 arg[4].arg_len = chld[1].arg_len;
237 arg[4].arg_type = A_EXPR;
238 arg[4].arg_ptr.arg_arg = chld;
241 if (newlen >= 5 && (chld = arg5)) {
242 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type&A_MASK]) {
243 arg[5].arg_type = chld[1].arg_type;
244 arg[5].arg_ptr = chld[1].arg_ptr;
245 arg[5].arg_len = chld[1].arg_len;
249 arg[5].arg_type = A_EXPR;
250 arg[5].arg_ptr.arg_arg = chld;
253 doarg = opargs[type];
254 for (i = 1; i <= newlen; ++i) {
256 arg[i].arg_type |= A_DONT;
258 arg[i].arg_flags |= AF_ARYOK;
263 fprintf(stderr,"%lx <= make_op(%s",arg,opname[arg->arg_type]);
265 fprintf(stderr,",%s=%lx",
266 argname[arg[1].arg_type&A_MASK],arg[1].arg_ptr.arg_arg);
268 fprintf(stderr,",%s=%lx",
269 argname[arg[2].arg_type&A_MASK],arg[2].arg_ptr.arg_arg);
271 fprintf(stderr,",%s=%lx",
272 argname[arg[3].arg_type&A_MASK],arg[3].arg_ptr.arg_arg);
274 fprintf(stderr,",%s=%lx",
275 argname[arg[4].arg_type&A_MASK],arg[4].arg_ptr.arg_arg);
277 fprintf(stderr,",%s=%lx",
278 argname[arg[5].arg_type&A_MASK],arg[5].arg_ptr.arg_arg);
279 fprintf(stderr,")\n");
282 arg = evalstatic(arg); /* see if we can consolidate anything */
290 static STR *str = Nullstr;
293 double value; /* must not be register */
296 unsigned long tmplong;
298 double exp(), log(), sqrt(), modf();
300 double sin(), cos(), atan2(), pow();
302 if (!arg || !arg->arg_len)
308 if (arg[1].arg_type == A_SINGLE)
309 s1 = arg[1].arg_ptr.arg_str;
312 if (arg->arg_len >= 2 && arg[2].arg_type == A_SINGLE)
313 s2 = arg[2].arg_ptr.arg_str;
317 #define CHECK1 if (!s1) return arg
318 #define CHECK2 if (!s2) return arg
319 #define CHECK12 if (!s1 || !s2) return arg
321 switch (arg->arg_type) {
325 if (arg[1].arg_type == A_CMD)
326 arg[1].arg_type |= A_DONT;
329 if (arg[1].arg_type == A_CMD) {
330 arg->arg_type = O_TRY;
331 arg[1].arg_type |= A_DONT;
335 arg->arg_type = O_EVALONCE;
339 i = (int)str_gnum(s2);
340 if (i < 32767 && i >= 0) {
341 arg->arg_type = O_ITEM;
343 arg[1].arg_type = A_ARYSTAB; /* $abc[123] is hoistable now */
356 if (dowarn && !s2->str_nok && !looks_like_number(s2))
357 warn("Right operand of x is not numeric");
359 i = (int)str_gnum(s2);
363 STR_GROW(str, i * s1->str_cur + 1);
364 repeatcpy(str->str_ptr, tmps, s1->str_cur, i);
365 str->str_cur = i * s1->str_cur;
366 str->str_ptr[str->str_cur] = '\0';
371 value = str_gnum(s1);
372 str_numset(str,value * str_gnum(s2));
376 value = str_gnum(s2);
378 yyerror("Illegal division by constant zero");
381 /* insure that 20./5. == 4. */
386 if ((double)(int)x == x &&
387 (double)(int)value == value &&
388 (k = (int)x/(int)value)*(int)value == (int)x) {
393 str_numset(str,value);
396 str_numset(str,str_gnum(s1) / value);
401 tmplong = (unsigned long)str_gnum(s2);
403 yyerror("Illegal modulus of constant zero");
406 value = str_gnum(s1);
409 str_numset(str,(double)(((unsigned long)value) % tmplong));
412 str_numset(str,(double)((tmplong-((-tmp2 - 1) % tmplong)) - 1));
420 value = str_gnum(s1);
421 str_numset(str,value + str_gnum(s2));
425 value = str_gnum(s1);
426 str_numset(str,value - str_gnum(s2));
430 value = str_gnum(s1);
431 i = (int)str_gnum(s2);
433 str_numset(str,(double)(((long)value) << i));
438 value = str_gnum(s1);
439 i = (int)str_gnum(s2);
441 str_numset(str,(double)(((long)value) >> i));
446 value = str_gnum(s1);
447 str_numset(str,(value < str_gnum(s2)) ? 1.0 : 0.0);
451 value = str_gnum(s1);
452 str_numset(str,(value > str_gnum(s2)) ? 1.0 : 0.0);
456 value = str_gnum(s1);
457 str_numset(str,(value <= str_gnum(s2)) ? 1.0 : 0.0);
461 value = str_gnum(s1);
462 str_numset(str,(value >= str_gnum(s2)) ? 1.0 : 0.0);
467 if ((!s1->str_nok && !looks_like_number(s1)) ||
468 (!s2->str_nok && !looks_like_number(s2)) )
469 warn("Possible use of == on string value");
471 value = str_gnum(s1);
472 str_numset(str,(value == str_gnum(s2)) ? 1.0 : 0.0);
476 value = str_gnum(s1);
477 str_numset(str,(value != str_gnum(s2)) ? 1.0 : 0.0);
481 value = str_gnum(s1);
482 value -= str_gnum(s2);
485 else if (value < 0.0)
487 str_numset(str,value);
491 value = str_gnum(s1);
493 str_numset(str,(double)(U_L(value) & U_L(str_gnum(s2))));
498 value = str_gnum(s1);
500 str_numset(str,(double)(U_L(value) ^ U_L(str_gnum(s2))));
505 value = str_gnum(s1);
507 str_numset(str,(double)(U_L(value) | U_L(str_gnum(s2))));
526 if ((arg[3].arg_type & A_MASK) != A_SINGLE)
531 str_sset(str,arg[3].arg_ptr.arg_str);
532 str_free(arg[3].arg_ptr.arg_str);
537 str_numset(str,(double)(-str_gnum(s1)));
542 { char xxx = str_true(s1); str_numset(str,(double)!xxx); }
544 str_numset(str,(double)(!str_true(s1)));
550 str_numset(str,(double)(~U_L(str_gnum(s1))));
555 str_numset(str,sin(str_gnum(s1)));
559 str_numset(str,cos(str_gnum(s1)));
563 value = str_gnum(s1);
564 str_numset(str,atan2(value, str_gnum(s2)));
568 value = str_gnum(s1);
569 str_numset(str,pow(value, str_gnum(s2)));
572 if (arg[1].arg_type == A_STAB) {
573 arg->arg_type = O_ITEM;
574 arg[1].arg_type = A_LENSTAB;
578 str_numset(str, (double)str_len(s1));
582 str_numset(str,(double)(str_cmp(s1,s2) < 0));
586 str_numset(str,(double)(str_cmp(s1,s2) > 0));
590 str_numset(str,(double)(str_cmp(s1,s2) <= 0));
594 str_numset(str,(double)(str_cmp(s1,s2) >= 0));
598 str_numset(str,(double)(str_eq(s1,s2)));
602 str_numset(str,(double)(!str_eq(s1,s2)));
606 str_numset(str,(double)(str_cmp(s1,s2)));
612 str_set(str,crypt(tmps,str_get(s2)));
615 "The crypt() function is unimplemented due to excessive paranoia.");
620 str_numset(str,exp(str_gnum(s1)));
624 str_numset(str,log(str_gnum(s1)));
628 str_numset(str,sqrt(str_gnum(s1)));
632 value = str_gnum(s1);
634 (void)modf(value,&value);
636 (void)modf(-value,&value);
639 str_numset(str,value);
644 str_numset(str,(double)(*str_get(s1)));
652 str_numset(str,(double)(zapc));
657 arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */
659 arg[1].arg_ptr.arg_str = str;
662 arg[2].arg_ptr.arg_str = Nullstr;
663 arg[2].arg_type = A_NULL;
680 i = arg[1].arg_type & A_MASK;
682 arg->arg_flags |= AF_COMMON; /* assume something in common */
683 /* which forces us to copy things */
686 arg[1].arg_type = A_LARYLEN;
689 if (i == A_ARYSTAB) {
690 arg[1].arg_type = A_LARYSTAB;
694 /* see if it's an array reference */
696 if (i == A_EXPR || i == A_LEXPR) {
697 arg1 = arg[1].arg_ptr.arg_arg;
699 if (arg1->arg_type == O_LIST || arg1->arg_type == O_ITEM) {
701 if (arg->arg_len > 1) {
703 arg2 = arg[2].arg_ptr.arg_arg;
704 if (nothing_in_common(arg1,arg2))
705 arg->arg_flags &= ~AF_COMMON;
706 if (arg->arg_type == O_ASSIGN) {
707 if (arg1->arg_flags & AF_LOCAL)
708 arg->arg_flags |= AF_LOCAL;
709 arg[1].arg_flags |= AF_ARYOK;
710 arg[2].arg_flags |= AF_ARYOK;
713 else if (arg->arg_type != O_CHOP)
714 arg->arg_type = O_ASSIGN; /* possible local(); */
715 for (i = arg1->arg_len; i >= 1; i--) {
716 switch (arg1[i].arg_type) {
717 case A_STAR: case A_LSTAR:
718 arg1[i].arg_type = A_LSTAR;
720 case A_STAB: case A_LVAL:
721 arg1[i].arg_type = A_LVAL;
723 case A_ARYLEN: case A_LARYLEN:
724 arg1[i].arg_type = A_LARYLEN;
726 case A_ARYSTAB: case A_LARYSTAB:
727 arg1[i].arg_type = A_LARYSTAB;
729 case A_EXPR: case A_LEXPR:
730 arg1[i].arg_type = A_LEXPR;
731 switch(arg1[i].arg_ptr.arg_arg->arg_type) {
732 case O_ARRAY: case O_LARRAY:
733 arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;
736 case O_AELEM: case O_LAELEM:
737 arg1[i].arg_ptr.arg_arg->arg_type = O_LAELEM;
739 case O_HASH: case O_LHASH:
740 arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;
743 case O_HELEM: case O_LHELEM:
744 arg1[i].arg_ptr.arg_arg->arg_type = O_LHELEM;
746 case O_ASLICE: case O_LASLICE:
747 arg1[i].arg_ptr.arg_arg->arg_type = O_LASLICE;
749 case O_HSLICE: case O_LHSLICE:
750 arg1[i].arg_ptr.arg_arg->arg_type = O_LHSLICE;
752 case O_SUBSTR: case O_VEC:
753 (void)l(arg1[i].arg_ptr.arg_arg);
754 Renewc(arg1[i].arg_ptr.arg_arg->arg_ptr.arg_str, 1,
755 struct lstring, STR);
756 /* grow string struct to hold an lstring struct */
764 (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue",
765 argname[arg1[i].arg_type&A_MASK]);
769 if (arg->arg_len > 1) {
770 if (arg2->arg_type == O_SPLIT && !arg2[3].arg_type && !arghog) {
771 arg2[3].arg_type = A_SINGLE;
772 arg2[3].arg_ptr.arg_str =
773 str_nmake((double)arg1->arg_len + 1); /* limit split len*/
777 else if (arg1->arg_type == O_AELEM || arg1->arg_type == O_LAELEM)
778 if (arg->arg_type == O_DEFINED)
779 arg1->arg_type = O_AELEM;
781 arg1->arg_type = O_LAELEM;
782 else if (arg1->arg_type == O_ARRAY || arg1->arg_type == O_LARRAY) {
783 arg1->arg_type = O_LARRAY;
784 if (arg->arg_len > 1) {
786 arg2 = arg[2].arg_ptr.arg_arg;
787 if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/
788 spat = arg2[2].arg_ptr.arg_spat;
789 if (!(spat->spat_flags & SPAT_ONCE) &&
790 nothing_in_common(arg1,spat->spat_repl)) {
791 spat->spat_repl[1].arg_ptr.arg_stab =
792 arg1[1].arg_ptr.arg_stab;
793 arg1[1].arg_ptr.arg_stab = Nullstab;
794 spat->spat_flags |= SPAT_ONCE;
795 arg_free(arg1); /* recursive */
796 arg[1].arg_ptr.arg_arg = Nullarg;
797 free_arg(arg); /* non-recursive */
798 return arg2; /* split has builtin assign */
801 else if (nothing_in_common(arg1,arg2))
802 arg->arg_flags &= ~AF_COMMON;
803 if (arg->arg_type == O_ASSIGN) {
804 arg[1].arg_flags |= AF_ARYOK;
805 arg[2].arg_flags |= AF_ARYOK;
808 else if (arg->arg_type == O_ASSIGN)
809 arg[1].arg_flags |= AF_ARYOK;
811 else if (arg1->arg_type == O_HELEM || arg1->arg_type == O_LHELEM)
812 if (arg->arg_type == O_DEFINED)
813 arg1->arg_type = O_HELEM; /* avoid creating one */
815 arg1->arg_type = O_LHELEM;
816 else if (arg1->arg_type == O_HASH || arg1->arg_type == O_LHASH) {
817 arg1->arg_type = O_LHASH;
818 if (arg->arg_len > 1) {
820 arg2 = arg[2].arg_ptr.arg_arg;
821 if (nothing_in_common(arg1,arg2))
822 arg->arg_flags &= ~AF_COMMON;
823 if (arg->arg_type == O_ASSIGN) {
824 arg[1].arg_flags |= AF_ARYOK;
825 arg[2].arg_flags |= AF_ARYOK;
828 else if (arg->arg_type == O_ASSIGN)
829 arg[1].arg_flags |= AF_ARYOK;
831 else if (arg1->arg_type == O_ASLICE) {
832 arg1->arg_type = O_LASLICE;
833 if (arg->arg_type == O_ASSIGN) {
835 arg[1].arg_flags |= AF_ARYOK;
836 arg[2].arg_flags |= AF_ARYOK;
839 else if (arg1->arg_type == O_HSLICE) {
840 arg1->arg_type = O_LHSLICE;
841 if (arg->arg_type == O_ASSIGN) {
843 arg[1].arg_flags |= AF_ARYOK;
844 arg[2].arg_flags |= AF_ARYOK;
847 else if ((arg->arg_type == O_DEFINED || arg->arg_type == O_UNDEF) &&
848 (arg1->arg_type == (perldb ? O_DBSUBR : O_SUBR)) ) {
849 arg[1].arg_type |= A_DONT;
851 else if (arg1->arg_type == O_SUBSTR || arg1->arg_type == O_VEC) {
853 Renewc(arg1->arg_ptr.arg_str, 1, struct lstring, STR);
854 /* grow string struct to hold an lstring struct */
856 else if (arg1->arg_type == O_ASSIGN)
860 (void)sprintf(tokenbuf,
861 "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);
865 arg[1].arg_type = A_LEXPR | (arg[1].arg_type & A_DONT);
866 if (arg->arg_type == O_ASSIGN && (arg1[1].arg_flags & AF_ARYOK)) {
867 arg[1].arg_flags |= AF_ARYOK;
868 if (arg->arg_len > 1)
869 arg[2].arg_flags |= AF_ARYOK;
873 fprintf(stderr,"lval LEXPR\n");
877 if (i == A_STAR || i == A_LSTAR) {
878 arg[1].arg_type = A_LSTAR | (arg[1].arg_type & A_DONT);
882 /* not an array reference, should be a register name */
884 if (i != A_STAB && i != A_LVAL) {
885 (void)sprintf(tokenbuf,
886 "Illegal item (%s) as lvalue",argname[arg[1].arg_type&A_MASK]);
890 arg[1].arg_type = A_LVAL | (arg[1].arg_type & A_DONT);
893 fprintf(stderr,"lval LVAL\n");
903 if (type == O_DEFINED || type == O_UNDEF) {
904 if (arg->arg_type != O_ITEM)
906 if (arg->arg_type == O_ITEM) {
907 type = arg[1].arg_type & A_MASK;
908 if (type == A_EXPR || type == A_LEXPR)
909 arg[1].arg_type = A_LEXPR|A_DONT;
921 if (arg[i].arg_type != A_EXPR) { /* dehoist */
922 tmparg = make_op(O_ITEM,1,Nullarg,Nullarg,Nullarg);
924 arg[i].arg_ptr.arg_arg = tmparg;
925 arg[i].arg_type = A_EXPR;
930 addflags(i,flags,arg)
933 arg[i].arg_flags |= flags;
941 if (arg->arg_type == O_ARRAY || arg->arg_type == O_HASH)
942 return make_op(O_ITEM,1,arg,Nullarg,Nullarg);
946 /* maybe do a join on multiple array dimensions */
952 if (arg && arg->arg_type == O_COMMA) {
954 arg = make_op(O_JOIN, 2,
955 stab2arg(A_STAB,stabent(";",TRUE)),
968 register ARG *nxtnode;
974 arg->arg_type = O_LIST;
976 if (arg->arg_type != O_COMMA) {
977 if (arg->arg_type != O_ARRAY)
978 arg->arg_flags |= AF_LISTISH; /* see listish() below */
979 arg->arg_flags |= AF_LISTISH; /* see listish() below */
982 for (i = 2, node = arg; ; i++) {
983 if (node->arg_len < 2)
985 if (node[1].arg_type != A_EXPR)
987 node = node[1].arg_ptr.arg_arg;
988 if (node->arg_type != O_COMMA)
994 tmpstr = arg->arg_ptr.arg_str;
995 StructCopy(node, arg, ARG); /* copy everything except the STR */
996 arg->arg_ptr.arg_str = tmpstr;
998 StructCopy(node+2, arg+j, ARG);
999 arg[j].arg_flags |= AF_ARYOK;
1000 --j; /* Bug in Xenix compiler */
1002 StructCopy(node+1, arg+1, ARG);
1006 nxtnode = node[1].arg_ptr.arg_arg;
1011 arg[1].arg_flags |= AF_ARYOK;
1012 arg[2].arg_flags |= AF_ARYOK;
1013 arg->arg_type = O_LIST;
1015 str_free(arg->arg_ptr.arg_str);
1016 arg->arg_ptr.arg_str = Nullstr;
1020 /* turn a single item into a list */
1026 if (arg && arg->arg_flags & AF_LISTISH)
1027 arg = make_op(O_LIST,1,arg,Nullarg,Nullarg);
1032 maybelistish(optype, arg)
1038 if (optype == O_RETURN && arg->arg_type == O_ITEM &&
1039 arg[1].arg_type == A_EXPR && (tmparg = arg[1].arg_ptr.arg_arg) &&
1040 ((tmparg->arg_flags & AF_LISTISH) || (tmparg->arg_type == O_ARRAY) )) {
1041 tmparg = listish(tmparg);
1045 else if (optype == O_PRTF ||
1046 (arg->arg_type == O_ASLICE || arg->arg_type == O_HSLICE ||
1047 arg->arg_type == O_F_OR_R) )
1052 /* mark list of local variables */
1058 arg->arg_flags |= AF_LOCAL;
1068 if (arg->arg_type == O_CONCAT && arg[2].arg_type == A_EXPR) {
1069 arg2 = arg[2].arg_ptr.arg_arg;
1070 if (arg2->arg_type == O_ITEM && arg2[1].arg_type == A_READ) {
1071 arg->arg_type = O_RCAT;
1072 arg[2].arg_type = arg2[1].arg_type;
1073 arg[2].arg_ptr = arg2[1].arg_ptr;
1081 stab2arg(atype,stab)
1083 register STAB *stab;
1088 arg->arg_type = O_ITEM;
1089 arg[1].arg_type = atype;
1090 arg[1].arg_ptr.arg_stab = stab;
1096 register char *cval;
1101 arg->arg_type = O_ITEM;
1102 arg[1].arg_type = A_SINGLE;
1103 arg[1].arg_ptr.arg_str = str_make(cval,0);
1114 Newz(203,arg, numargs + 1, ARG);
1115 arg->arg_ptr.arg_str = Str_new(21,0);
1116 arg->arg_len = numargs;
1124 str_free(arg->arg_ptr.arg_str);
1129 make_match(type,expr,spat)
1136 arg = make_op(type,2,expr,Nullarg,Nullarg);
1138 arg[2].arg_type = A_SPAT|A_DONT;
1139 arg[2].arg_ptr.arg_spat = spat;
1142 fprintf(stderr,"make_match SPAT=%lx\n",(long)spat);
1145 if (type == O_SUBST || type == O_NSUBST) {
1146 if (arg[1].arg_type != A_STAB) {
1147 yyerror("Illegal lvalue");
1149 arg[1].arg_type = A_LVAL;
1161 arg->arg_type = O_ITEM;
1162 arg[1].arg_type = A_CMD;
1163 arg[1].arg_ptr.arg_cmd = cmd;
1167 /* Check two expressions to see if there is any identifier in common */
1170 nothing_in_common(arg1,arg2)
1174 static int thisexpr = 0; /* I don't care if this wraps */
1177 if (arg_common(arg1,thisexpr,1))
1178 return 0; /* hit eval or do {} */
1179 stab_lastexpr(defstab) = thisexpr; /* pretend to hit @_ */
1180 if (arg_common(arg2,thisexpr,0))
1181 return 0; /* hit identifier again */
1185 /* Recursively descend an expression and mark any identifier or check
1186 * it to see if it was marked already.
1190 arg_common(arg,exprnum,marking)
1199 for (i = arg->arg_len; i >= 1; i--) {
1200 switch (arg[i].arg_type & A_MASK) {
1205 if (arg_common(arg[i].arg_ptr.arg_arg,exprnum,marking))
1209 return 1; /* assume hanky panky */
1217 stab_lastexpr(arg[i].arg_ptr.arg_stab) = exprnum;
1218 else if (stab_lastexpr(arg[i].arg_ptr.arg_stab) == exprnum)
1224 register char *s = arg[i].arg_ptr.arg_str->str_ptr;
1225 register char *send = s + arg[i].arg_ptr.arg_str->str_cur;
1226 register STAB *stab;
1229 if (*s == '$' && s[1]) {
1230 s = scanident(s,send,tokenbuf);
1231 stab = stabent(tokenbuf,TRUE);
1233 stab_lastexpr(stab) = exprnum;
1234 else if (stab_lastexpr(stab) == exprnum)
1238 else if (*s == '\\' && s[1])
1245 if (spat_common(arg[i].arg_ptr.arg_spat,exprnum,marking))
1256 switch (arg->arg_type) {
1259 if ((arg[1].arg_type & A_MASK) == A_STAB)
1260 (void)aadd(arg[1].arg_ptr.arg_stab);
1264 if ((arg[1].arg_type & A_MASK) == A_STAB)
1265 (void)hadd(arg[1].arg_ptr.arg_stab);
1276 spat_common(spat,exprnum,marking)
1277 register SPAT *spat;
1281 if (spat->spat_runtime)
1282 if (arg_common(spat->spat_runtime,exprnum,marking))
1284 if (spat->spat_repl) {
1285 if (arg_common(spat->spat_repl,exprnum,marking))