1 /* $Header: consarg.c,v 3.0.1.8 91/01/11 17:37:31 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.8 91/01/11 17:37:31 lwall
10 * patch42: assignment to a slice didn't supply an array context to RHS
11 * patch42: suppressed variable suicide on local($a,$b) = @_
13 * Revision 3.0.1.7 90/10/15 15:55:28 lwall
14 * patch29: defined @foo was behaving inconsistently
15 * patch29: -5 % 5 was wrong
16 * patch29: package behavior is now more consistent
18 * Revision 3.0.1.6 90/08/09 02:38:51 lwall
19 * patch19: fixed problem with % of negative number
21 * Revision 3.0.1.5 90/03/27 15:36:45 lwall
22 * patch16: support for machines that can't cast negative floats to unsigned ints
24 * Revision 3.0.1.4 90/03/12 16:24:40 lwall
25 * patch13: return (@array) did counter-intuitive things
27 * Revision 3.0.1.3 90/02/28 16:47:54 lwall
28 * patch9: the x operator is now up to 10 times faster
29 * patch9: @_ clobbered by ($foo,$bar) = split
31 * Revision 3.0.1.2 89/11/17 15:11:34 lwall
32 * patch5: defined $foo{'bar'} should not create element
34 * Revision 3.0.1.1 89/11/11 04:14:30 lwall
35 * patch2: '-' x 26 made warnings about undefined value
36 * patch2: eval with no args caused strangeness
37 * patch2: local(@foo) didn't work, but local(@foo,$bar) did
39 * Revision 3.0 89/10/18 15:10:30 lwall
46 static int nothing_in_common();
47 static int arg_common();
48 static int spat_common();
51 make_split(stab,arg,limarg)
58 if (arg->arg_type != O_MATCH) {
59 Newz(201,spat,1,SPAT);
60 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
61 curstash->tbl_spatroot = spat;
63 spat->spat_runtime = arg;
64 arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
69 if (limarg->arg_type == O_ITEM) {
70 Copy(limarg+1,arg+3,1,ARG);
71 limarg[1].arg_type = A_NULL;
76 arg[3].arg_type = A_EXPR;
77 arg[3].arg_ptr.arg_arg = limarg;
81 arg[3].arg_type = A_NULL;
82 arg->arg_type = O_SPLIT;
83 spat = arg[2].arg_ptr.arg_spat;
84 spat->spat_repl = stab2arg(A_STAB,aadd(stab));
85 if (spat->spat_short) { /* exact match can bypass regexec() */
86 if (!((spat->spat_flags & SPAT_SCANFIRST) &&
87 (spat->spat_flags & SPAT_ALL) )) {
88 str_free(spat->spat_short);
89 spat->spat_short = Nullstr;
96 mod_match(type,left,pat)
102 register ARG *newarg;
107 if ((pat->arg_type == O_MATCH ||
108 pat->arg_type == O_SUBST ||
109 pat->arg_type == O_TRANS ||
110 pat->arg_type == O_SPLIT
112 pat[1].arg_ptr.arg_stab == defstab ) {
113 switch (pat->arg_type) {
115 newarg = make_op(type == O_MATCH ? O_MATCH : O_NMATCH,
117 left,Nullarg,Nullarg);
120 newarg = l(make_op(type == O_MATCH ? O_SUBST : O_NSUBST,
122 left,Nullarg,Nullarg));
125 newarg = l(make_op(type == O_MATCH ? O_TRANS : O_NTRANS,
127 left,Nullarg,Nullarg));
130 newarg = make_op(type == O_MATCH ? O_SPLIT : O_SPLIT,
132 left,Nullarg,Nullarg);
135 if (pat->arg_len >= 2) {
136 newarg[2].arg_type = pat[2].arg_type;
137 newarg[2].arg_ptr = pat[2].arg_ptr;
138 newarg[2].arg_flags = pat[2].arg_flags;
139 if (pat->arg_len >= 3) {
140 newarg[3].arg_type = pat[3].arg_type;
141 newarg[3].arg_ptr = pat[3].arg_ptr;
142 newarg[3].arg_flags = pat[3].arg_flags;
148 Newz(202,spat,1,SPAT);
149 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
150 curstash->tbl_spatroot = spat;
152 spat->spat_runtime = pat;
153 newarg = make_op(type,2,left,Nullarg,Nullarg);
154 newarg[2].arg_type = A_SPAT | A_DONT;
155 newarg[2].arg_ptr.arg_spat = spat;
162 make_op(type,newlen,arg1,arg2,arg3)
171 register unsigned doarg;
173 extern ARG *arg4; /* should be normal arguments, really */
176 arg = op_new(newlen);
177 arg->arg_type = type;
179 if (chld->arg_type == O_ITEM &&
180 (hoistable[ i = (chld[1].arg_type&A_MASK)] || i == A_LVAL ||
182 (chld[1].arg_ptr.arg_arg->arg_type == O_LIST ||
183 chld[1].arg_ptr.arg_arg->arg_type == O_ARRAY ||
184 chld[1].arg_ptr.arg_arg->arg_type == O_HASH ))))
186 arg[1].arg_type = chld[1].arg_type;
187 arg[1].arg_ptr = chld[1].arg_ptr;
188 arg[1].arg_flags |= chld[1].arg_flags;
189 arg[1].arg_len = chld[1].arg_len;
193 arg[1].arg_type = A_EXPR;
194 arg[1].arg_ptr.arg_arg = chld;
198 if (chld->arg_type == O_ITEM &&
199 (hoistable[chld[1].arg_type&A_MASK] ||
201 ((chld[1].arg_type == A_READ && !(arg[1].arg_type & A_DONT))
203 (chld[1].arg_type == A_INDREAD && !(arg[1].arg_type & A_DONT))
205 (chld[1].arg_type == A_GLOB && !(arg[1].arg_type & A_DONT))
207 arg[2].arg_type = chld[1].arg_type;
208 arg[2].arg_ptr = chld[1].arg_ptr;
209 arg[2].arg_len = chld[1].arg_len;
213 arg[2].arg_type = A_EXPR;
214 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 evalstatic(arg); /* see if we can consolidate anything */
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)
305 if ((arg[1].arg_type == A_SINGLE || arg->arg_type == O_AELEM) &&
306 (arg->arg_len == 1 || arg[2].arg_type == A_SINGLE) ) {
308 s1 = arg[1].arg_ptr.arg_str;
309 if (arg->arg_len > 1)
310 s2 = arg[2].arg_ptr.arg_str;
313 switch (arg->arg_type) {
315 i = (int)str_gnum(s2);
316 if (i < 32767 && i >= 0) {
317 arg->arg_type = O_ITEM;
319 arg[1].arg_type = A_ARYSTAB; /* $abc[123] is hoistable now */
326 str = Nullstr; /* can't be evaluated yet */
333 i = (int)str_gnum(s2);
336 STR_GROW(str, i * s1->str_cur + 1);
337 repeatcpy(str->str_ptr, tmps, s1->str_cur, i);
338 str->str_cur = i * s1->str_cur;
339 str->str_ptr[str->str_cur] = '\0';
342 value = str_gnum(s1);
343 str_numset(str,value * str_gnum(s2));
346 value = str_gnum(s2);
348 yyerror("Illegal division by constant zero");
350 str_numset(str,str_gnum(s1) / value);
353 tmplong = (unsigned long)str_gnum(s2);
355 yyerror("Illegal modulus of constant zero");
358 tmp2 = (long)str_gnum(s1);
361 str_numset(str,(double)(tmp2 % tmplong));
363 str_numset(str,(double)((tmplong-((-tmp2 - 1) % tmplong)) - 1));
369 value = str_gnum(s1);
370 str_numset(str,value + str_gnum(s2));
373 value = str_gnum(s1);
374 str_numset(str,value - str_gnum(s2));
377 value = str_gnum(s1);
378 i = (int)str_gnum(s2);
380 str_numset(str,(double)(((long)value) << i));
384 value = str_gnum(s1);
385 i = (int)str_gnum(s2);
387 str_numset(str,(double)(((long)value) >> i));
391 value = str_gnum(s1);
392 str_numset(str,(value < str_gnum(s2)) ? 1.0 : 0.0);
395 value = str_gnum(s1);
396 str_numset(str,(value > str_gnum(s2)) ? 1.0 : 0.0);
399 value = str_gnum(s1);
400 str_numset(str,(value <= str_gnum(s2)) ? 1.0 : 0.0);
403 value = str_gnum(s1);
404 str_numset(str,(value >= str_gnum(s2)) ? 1.0 : 0.0);
408 if ((!s1->str_nok && !looks_like_number(s1)) ||
409 (!s2->str_nok && !looks_like_number(s2)) )
410 warn("Possible use of == on string value");
412 value = str_gnum(s1);
413 str_numset(str,(value == str_gnum(s2)) ? 1.0 : 0.0);
416 value = str_gnum(s1);
417 str_numset(str,(value != str_gnum(s2)) ? 1.0 : 0.0);
420 value = str_gnum(s1);
421 value -= str_gnum(s2);
424 else if (value < 0.0)
426 str_numset(str,value);
429 value = str_gnum(s1);
431 str_numset(str,(double)(U_L(value) & U_L(str_gnum(s2))));
435 value = str_gnum(s1);
437 str_numset(str,(double)(U_L(value) ^ U_L(str_gnum(s2))));
441 value = str_gnum(s1);
443 str_numset(str,(double)(U_L(value) | U_L(str_gnum(s2))));
459 if ((arg[3].arg_type & A_MASK) != A_SINGLE) {
467 str_sset(str,arg[3].arg_ptr.arg_str);
468 str_free(arg[3].arg_ptr.arg_str);
472 str_numset(str,(double)(-str_gnum(s1)));
475 str_numset(str,(double)(!str_true(s1)));
479 str_numset(str,(double)(~U_L(str_gnum(s1))));
483 str_numset(str,sin(str_gnum(s1)));
486 str_numset(str,cos(str_gnum(s1)));
489 value = str_gnum(s1);
490 str_numset(str,atan2(value, str_gnum(s2)));
493 value = str_gnum(s1);
494 str_numset(str,pow(value, str_gnum(s2)));
497 str_numset(str, (double)str_len(s1));
500 str_numset(str,(double)(str_cmp(s1,s2) < 0));
503 str_numset(str,(double)(str_cmp(s1,s2) > 0));
506 str_numset(str,(double)(str_cmp(s1,s2) <= 0));
509 str_numset(str,(double)(str_cmp(s1,s2) >= 0));
512 str_numset(str,(double)(str_eq(s1,s2)));
515 str_numset(str,(double)(!str_eq(s1,s2)));
518 str_numset(str,(double)(str_cmp(s1,s2)));
523 str_set(str,crypt(tmps,str_get(s2)));
526 "The crypt() function is unimplemented due to excessive paranoia.");
530 str_numset(str,exp(str_gnum(s1)));
533 str_numset(str,log(str_gnum(s1)));
536 str_numset(str,sqrt(str_gnum(s1)));
539 value = str_gnum(s1);
541 (void)modf(value,&value);
543 (void)modf(-value,&value);
546 str_numset(str,value);
550 str_numset(str,(double)(*str_get(s1)));
558 str_numset(str,(double)(zapc));
564 arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */
567 arg[1].arg_ptr.arg_str = str;
582 i = arg[1].arg_type & A_MASK;
584 arg->arg_flags |= AF_COMMON; /* assume something in common */
585 /* which forces us to copy things */
588 arg[1].arg_type = A_LARYLEN;
591 if (i == A_ARYSTAB) {
592 arg[1].arg_type = A_LARYSTAB;
596 /* see if it's an array reference */
598 if (i == A_EXPR || i == A_LEXPR) {
599 arg1 = arg[1].arg_ptr.arg_arg;
601 if (arg1->arg_type == O_LIST || arg1->arg_type == O_ITEM) {
603 if (arg->arg_len > 1) {
605 arg2 = arg[2].arg_ptr.arg_arg;
606 if (nothing_in_common(arg1,arg2))
607 arg->arg_flags &= ~AF_COMMON;
608 if (arg->arg_type == O_ASSIGN) {
609 if (arg1->arg_flags & AF_LOCAL)
610 arg->arg_flags |= AF_LOCAL;
611 arg[1].arg_flags |= AF_ARYOK;
612 arg[2].arg_flags |= AF_ARYOK;
615 else if (arg->arg_type != O_CHOP)
616 arg->arg_type = O_ASSIGN; /* possible local(); */
617 for (i = arg1->arg_len; i >= 1; i--) {
618 switch (arg1[i].arg_type) {
619 case A_STAR: case A_LSTAR:
620 arg1[i].arg_type = A_LSTAR;
622 case A_STAB: case A_LVAL:
623 arg1[i].arg_type = A_LVAL;
625 case A_ARYLEN: case A_LARYLEN:
626 arg1[i].arg_type = A_LARYLEN;
628 case A_ARYSTAB: case A_LARYSTAB:
629 arg1[i].arg_type = A_LARYSTAB;
631 case A_EXPR: case A_LEXPR:
632 arg1[i].arg_type = A_LEXPR;
633 switch(arg1[i].arg_ptr.arg_arg->arg_type) {
634 case O_ARRAY: case O_LARRAY:
635 arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;
638 case O_AELEM: case O_LAELEM:
639 arg1[i].arg_ptr.arg_arg->arg_type = O_LAELEM;
641 case O_HASH: case O_LHASH:
642 arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;
645 case O_HELEM: case O_LHELEM:
646 arg1[i].arg_ptr.arg_arg->arg_type = O_LHELEM;
648 case O_ASLICE: case O_LASLICE:
649 arg1[i].arg_ptr.arg_arg->arg_type = O_LASLICE;
651 case O_HSLICE: case O_LHSLICE:
652 arg1[i].arg_ptr.arg_arg->arg_type = O_LHSLICE;
660 (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue",
661 argname[arg1[i].arg_type&A_MASK]);
665 if (arg->arg_len > 1) {
666 if (arg2->arg_type == O_SPLIT && !arg2[3].arg_type && !arghog) {
667 arg2[3].arg_type = A_SINGLE;
668 arg2[3].arg_ptr.arg_str =
669 str_nmake((double)arg1->arg_len + 1); /* limit split len*/
673 else if (arg1->arg_type == O_AELEM || arg1->arg_type == O_LAELEM)
674 if (arg->arg_type == O_DEFINED)
675 arg1->arg_type = O_AELEM;
677 arg1->arg_type = O_LAELEM;
678 else if (arg1->arg_type == O_ARRAY || arg1->arg_type == O_LARRAY) {
679 arg1->arg_type = O_LARRAY;
680 if (arg->arg_len > 1) {
682 arg2 = arg[2].arg_ptr.arg_arg;
683 if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/
684 spat = arg2[2].arg_ptr.arg_spat;
685 if (!(spat->spat_flags & SPAT_ONCE) &&
686 nothing_in_common(arg1,spat->spat_repl)) {
687 spat->spat_repl[1].arg_ptr.arg_stab =
688 arg1[1].arg_ptr.arg_stab;
689 spat->spat_flags |= SPAT_ONCE;
690 arg_free(arg1); /* recursive */
691 free_arg(arg); /* non-recursive */
692 return arg2; /* split has builtin assign */
695 else if (nothing_in_common(arg1,arg2))
696 arg->arg_flags &= ~AF_COMMON;
697 if (arg->arg_type == O_ASSIGN) {
698 arg[1].arg_flags |= AF_ARYOK;
699 arg[2].arg_flags |= AF_ARYOK;
702 else if (arg->arg_type == O_ASSIGN)
703 arg[1].arg_flags |= AF_ARYOK;
705 else if (arg1->arg_type == O_HELEM || arg1->arg_type == O_LHELEM)
706 if (arg->arg_type == O_DEFINED)
707 arg1->arg_type = O_HELEM; /* avoid creating one */
709 arg1->arg_type = O_LHELEM;
710 else if (arg1->arg_type == O_HASH || arg1->arg_type == O_LHASH) {
711 arg1->arg_type = O_LHASH;
712 if (arg->arg_len > 1) {
714 arg2 = arg[2].arg_ptr.arg_arg;
715 if (nothing_in_common(arg1,arg2))
716 arg->arg_flags &= ~AF_COMMON;
717 if (arg->arg_type == O_ASSIGN) {
718 arg[1].arg_flags |= AF_ARYOK;
719 arg[2].arg_flags |= AF_ARYOK;
722 else if (arg->arg_type == O_ASSIGN)
723 arg[1].arg_flags |= AF_ARYOK;
725 else if (arg1->arg_type == O_ASLICE) {
726 arg1->arg_type = O_LASLICE;
727 if (arg->arg_type == O_ASSIGN) {
729 arg[1].arg_flags |= AF_ARYOK;
730 arg[2].arg_flags |= AF_ARYOK;
733 else if (arg1->arg_type == O_HSLICE) {
734 arg1->arg_type = O_LHSLICE;
735 if (arg->arg_type == O_ASSIGN) {
737 arg[1].arg_flags |= AF_ARYOK;
738 arg[2].arg_flags |= AF_ARYOK;
741 else if ((arg->arg_type == O_DEFINED || arg->arg_type == O_UNDEF) &&
742 (arg1->arg_type == (perldb ? O_DBSUBR : O_SUBR)) ) {
743 arg[1].arg_type |= A_DONT;
745 else if (arg1->arg_type == O_SUBSTR || arg1->arg_type == O_VEC) {
747 Renewc(arg1->arg_ptr.arg_str, 1, struct lstring, STR);
748 /* grow string struct to hold an lstring struct */
750 else if (arg1->arg_type == O_ASSIGN) {
751 if (arg->arg_type == O_CHOP)
752 arg[1].arg_flags &= ~AF_ARYOK; /* grandfather chop idiom */
755 (void)sprintf(tokenbuf,
756 "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);
759 arg[1].arg_type = A_LEXPR | (arg[1].arg_type & A_DONT);
760 if (arg->arg_type == O_ASSIGN && (arg1[1].arg_flags & AF_ARYOK)) {
761 arg[1].arg_flags |= AF_ARYOK;
762 if (arg->arg_len > 1)
763 arg[2].arg_flags |= AF_ARYOK;
767 fprintf(stderr,"lval LEXPR\n");
771 if (i == A_STAR || i == A_LSTAR) {
772 arg[1].arg_type = A_LSTAR | (arg[1].arg_type & A_DONT);
776 /* not an array reference, should be a register name */
778 if (i != A_STAB && i != A_LVAL) {
779 (void)sprintf(tokenbuf,
780 "Illegal item (%s) as lvalue",argname[arg[1].arg_type&A_MASK]);
783 arg[1].arg_type = A_LVAL | (arg[1].arg_type & A_DONT);
786 fprintf(stderr,"lval LVAL\n");
796 if (type == O_DEFINED || type == O_UNDEF) {
797 if (arg->arg_type != O_ITEM)
799 if (arg->arg_type == O_ITEM) {
800 type = arg[1].arg_type & A_MASK;
801 if (type == A_EXPR || type == A_LEXPR)
802 arg[1].arg_type = A_LEXPR|A_DONT;
813 if (arg[i].arg_type != A_EXPR) { /* dehoist */
814 tmparg = make_op(O_ITEM,1,Nullarg,Nullarg,Nullarg);
816 arg[i].arg_ptr.arg_arg = tmparg;
817 arg[i].arg_type = A_EXPR;
822 addflags(i,flags,arg)
825 arg[i].arg_flags |= flags;
833 if (arg->arg_type == O_ARRAY || arg->arg_type == O_HASH)
834 return make_op(O_ITEM,1,arg,Nullarg,Nullarg);
838 /* maybe do a join on multiple array dimensions */
844 if (arg && arg->arg_type == O_COMMA) {
846 arg = make_op(O_JOIN, 2,
847 stab2arg(A_STAB,stabent(";",TRUE)),
860 register ARG *nxtnode;
866 arg->arg_type = O_LIST;
868 if (arg->arg_type != O_COMMA) {
869 if (arg->arg_type != O_ARRAY)
870 arg->arg_flags |= AF_LISTISH; /* see listish() below */
873 for (i = 2, node = arg; ; i++) {
874 if (node->arg_len < 2)
876 if (node[1].arg_type != A_EXPR)
878 node = node[1].arg_ptr.arg_arg;
879 if (node->arg_type != O_COMMA)
885 tmpstr = arg->arg_ptr.arg_str;
887 *arg = *node; /* copy everything except the STR */
889 (void)bcopy((char *)node, (char *)arg, sizeof(ARG));
891 arg->arg_ptr.arg_str = tmpstr;
896 (void)bcopy((char *)(node+2), (char *)(arg+j), sizeof(ARG));
898 arg[j].arg_flags |= AF_ARYOK;
899 --j; /* Bug in Xenix compiler */
904 (void)bcopy((char *)(node+1), (char *)(arg+1), sizeof(ARG));
909 nxtnode = node[1].arg_ptr.arg_arg;
914 arg[1].arg_flags |= AF_ARYOK;
915 arg[2].arg_flags |= AF_ARYOK;
916 arg->arg_type = O_LIST;
921 /* turn a single item into a list */
927 if (arg->arg_flags & AF_LISTISH)
928 arg = make_op(O_LIST,1,arg,Nullarg,Nullarg);
933 maybelistish(optype, arg)
939 if (optype == O_RETURN && arg->arg_type == O_ITEM &&
940 arg[1].arg_type == A_EXPR && (tmparg = arg[1].arg_ptr.arg_arg) &&
941 ((tmparg->arg_flags & AF_LISTISH) || (tmparg->arg_type == O_ARRAY) )) {
942 tmparg = listish(tmparg);
946 else if (optype == O_PRTF ||
947 (arg->arg_type == O_ASLICE || arg->arg_type == O_HSLICE ||
948 arg->arg_type == O_F_OR_R) )
953 /* mark list of local variables */
959 arg->arg_flags |= AF_LOCAL;
967 if (arg->arg_type == O_CONCAT && arg[2].arg_type == A_READ) {
968 arg->arg_type = O_RCAT;
969 arg[2].arg_type = arg[2].arg_ptr.arg_arg[1].arg_type;
970 arg[2].arg_ptr = arg[2].arg_ptr.arg_arg[1].arg_ptr;
971 free_arg(arg[2].arg_ptr.arg_arg);
984 arg->arg_type = O_ITEM;
985 arg[1].arg_type = atype;
986 arg[1].arg_ptr.arg_stab = stab;
997 arg->arg_type = O_ITEM;
998 arg[1].arg_type = A_SINGLE;
999 arg[1].arg_ptr.arg_str = str_make(cval,0);
1010 Newz(203,arg, numargs + 1, ARG);
1011 arg->arg_ptr.arg_str = Str_new(21,0);
1012 arg->arg_len = numargs;
1020 str_free(arg->arg_ptr.arg_str);
1025 make_match(type,expr,spat)
1032 arg = make_op(type,2,expr,Nullarg,Nullarg);
1034 arg[2].arg_type = A_SPAT|A_DONT;
1035 arg[2].arg_ptr.arg_spat = spat;
1038 fprintf(stderr,"make_match SPAT=%lx\n",(long)spat);
1041 if (type == O_SUBST || type == O_NSUBST) {
1042 if (arg[1].arg_type != A_STAB) {
1043 yyerror("Illegal lvalue");
1045 arg[1].arg_type = A_LVAL;
1057 arg->arg_type = O_ITEM;
1058 arg[1].arg_type = A_CMD;
1059 arg[1].arg_ptr.arg_cmd = cmd;
1063 /* Check two expressions to see if there is any identifier in common */
1066 nothing_in_common(arg1,arg2)
1070 static int thisexpr = 0; /* I don't care if this wraps */
1073 if (arg_common(arg1,thisexpr,1))
1074 return 0; /* hit eval or do {} */
1075 stab_lastexpr(defstab) = thisexpr; /* pretend to hit @_ */
1076 if (arg_common(arg2,thisexpr,0))
1077 return 0; /* hit identifier again */
1081 /* Recursively descend an expression and mark any identifier or check
1082 * it to see if it was marked already.
1086 arg_common(arg,exprnum,marking)
1095 for (i = arg->arg_len; i >= 1; i--) {
1096 switch (arg[i].arg_type & A_MASK) {
1101 if (arg_common(arg[i].arg_ptr.arg_arg,exprnum,marking))
1105 return 1; /* assume hanky panky */
1113 stab_lastexpr(arg[i].arg_ptr.arg_stab) = exprnum;
1114 else if (stab_lastexpr(arg[i].arg_ptr.arg_stab) == exprnum)
1120 register char *s = arg[i].arg_ptr.arg_str->str_ptr;
1121 register char *send = s + arg[i].arg_ptr.arg_str->str_cur;
1122 register STAB *stab;
1125 if (*s == '$' && s[1]) {
1126 s = scanreg(s,send,tokenbuf);
1127 stab = stabent(tokenbuf,TRUE);
1129 stab_lastexpr(stab) = exprnum;
1130 else if (stab_lastexpr(stab) == exprnum)
1134 else if (*s == '\\' && s[1])
1141 if (spat_common(arg[i].arg_ptr.arg_spat,exprnum,marking))
1152 switch (arg->arg_type) {
1155 if ((arg[1].arg_type & A_MASK) == A_STAB)
1156 (void)aadd(arg[1].arg_ptr.arg_stab);
1160 if ((arg[1].arg_type & A_MASK) == A_STAB)
1161 (void)hadd(arg[1].arg_ptr.arg_stab);
1172 spat_common(spat,exprnum,marking)
1173 register SPAT *spat;
1177 if (spat->spat_runtime)
1178 if (arg_common(spat->spat_runtime,exprnum,marking))
1180 if (spat->spat_repl) {
1181 if (arg_common(spat->spat_repl,exprnum,marking))