1 /* $Header: consarg.c,v 3.0.1.3 90/02/28 16:47:54 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.3 90/02/28 16:47:54 lwall
10 * patch9: the x operator is now up to 10 times faster
11 * patch9: @_ clobbered by ($foo,$bar) = split
13 * Revision 3.0.1.2 89/11/17 15:11:34 lwall
14 * patch5: defined $foo{'bar'} should not create element
16 * Revision 3.0.1.1 89/11/11 04:14:30 lwall
17 * patch2: '-' x 26 made warnings about undefined value
18 * patch2: eval with no args caused strangeness
19 * patch2: local(@foo) didn't work, but local(@foo,$bar) did
21 * Revision 3.0 89/10/18 15:10:30 lwall
28 static int nothing_in_common();
29 static int arg_common();
30 static int spat_common();
33 make_split(stab,arg,limarg)
40 if (arg->arg_type != O_MATCH) {
41 Newz(201,spat,1,SPAT);
42 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
43 curstash->tbl_spatroot = spat;
45 spat->spat_runtime = arg;
46 arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
51 if (limarg->arg_type == O_ITEM) {
52 Copy(limarg+1,arg+3,1,ARG);
53 limarg[1].arg_type = A_NULL;
57 arg[3].arg_type = A_EXPR;
58 arg[3].arg_ptr.arg_arg = limarg;
62 arg[3].arg_type = A_NULL;
63 arg->arg_type = O_SPLIT;
64 spat = arg[2].arg_ptr.arg_spat;
65 spat->spat_repl = stab2arg(A_STAB,aadd(stab));
66 if (spat->spat_short) { /* exact match can bypass regexec() */
67 if (!((spat->spat_flags & SPAT_SCANFIRST) &&
68 (spat->spat_flags & SPAT_ALL) )) {
69 str_free(spat->spat_short);
70 spat->spat_short = Nullstr;
77 mod_match(type,left,pat)
85 if ((pat->arg_type == O_MATCH ||
86 pat->arg_type == O_SUBST ||
87 pat->arg_type == O_TRANS ||
88 pat->arg_type == O_SPLIT
90 pat[1].arg_ptr.arg_stab == defstab ) {
91 switch (pat->arg_type) {
93 newarg = make_op(type == O_MATCH ? O_MATCH : O_NMATCH,
95 left,Nullarg,Nullarg);
98 newarg = l(make_op(type == O_MATCH ? O_SUBST : O_NSUBST,
100 left,Nullarg,Nullarg));
103 newarg = l(make_op(type == O_MATCH ? O_TRANS : O_NTRANS,
105 left,Nullarg,Nullarg));
108 newarg = make_op(type == O_MATCH ? O_SPLIT : O_SPLIT,
110 left,Nullarg,Nullarg);
113 if (pat->arg_len >= 2) {
114 newarg[2].arg_type = pat[2].arg_type;
115 newarg[2].arg_ptr = pat[2].arg_ptr;
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_flags = pat[3].arg_flags;
126 Newz(202,spat,1,SPAT);
127 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
128 curstash->tbl_spatroot = spat;
130 spat->spat_runtime = pat;
131 newarg = make_op(type,2,left,Nullarg,Nullarg);
132 newarg[2].arg_type = A_SPAT | A_DONT;
133 newarg[2].arg_ptr.arg_spat = spat;
140 make_op(type,newlen,arg1,arg2,arg3)
150 extern ARG *arg4; /* should be normal arguments, really */
153 arg = op_new(newlen);
154 arg->arg_type = type;
155 doarg = opargs[type];
157 if (chld->arg_type == O_ITEM &&
158 (hoistable[chld[1].arg_type] || chld[1].arg_type == A_LVAL ||
159 (chld[1].arg_type == A_LEXPR &&
160 (chld[1].arg_ptr.arg_arg->arg_type == O_LIST ||
161 chld[1].arg_ptr.arg_arg->arg_type == O_ARRAY ||
162 chld[1].arg_ptr.arg_arg->arg_type == O_HASH ))))
164 arg[1].arg_type = chld[1].arg_type;
165 arg[1].arg_ptr = chld[1].arg_ptr;
166 arg[1].arg_flags |= chld[1].arg_flags;
167 arg[1].arg_len = chld[1].arg_len;
171 arg[1].arg_type = A_EXPR;
172 arg[1].arg_ptr.arg_arg = chld;
175 arg[1].arg_type |= A_DONT;
177 arg[1].arg_flags |= AF_ARYOK;
181 if (chld->arg_type == O_ITEM &&
182 (hoistable[chld[1].arg_type] ||
184 ((chld[1].arg_type == A_READ && !(arg[1].arg_type & A_DONT))
186 (chld[1].arg_type == A_INDREAD && !(arg[1].arg_type & A_DONT))
188 (chld[1].arg_type == A_GLOB && !(arg[1].arg_type & A_DONT))
190 arg[2].arg_type = chld[1].arg_type;
191 arg[2].arg_ptr = chld[1].arg_ptr;
192 arg[2].arg_len = chld[1].arg_len;
196 arg[2].arg_type = A_EXPR;
197 arg[2].arg_ptr.arg_arg = chld;
200 arg[2].arg_type |= A_DONT;
202 arg[2].arg_flags |= AF_ARYOK;
206 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
207 arg[3].arg_type = chld[1].arg_type;
208 arg[3].arg_ptr = chld[1].arg_ptr;
209 arg[3].arg_len = chld[1].arg_len;
213 arg[3].arg_type = A_EXPR;
214 arg[3].arg_ptr.arg_arg = chld;
217 arg[3].arg_type |= A_DONT;
219 arg[3].arg_flags |= AF_ARYOK;
221 if (newlen >= 4 && (chld = arg4)) {
222 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
223 arg[4].arg_type = chld[1].arg_type;
224 arg[4].arg_ptr = chld[1].arg_ptr;
225 arg[4].arg_len = chld[1].arg_len;
229 arg[4].arg_type = A_EXPR;
230 arg[4].arg_ptr.arg_arg = chld;
233 if (newlen >= 5 && (chld = arg5)) {
234 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
235 arg[5].arg_type = chld[1].arg_type;
236 arg[5].arg_ptr = chld[1].arg_ptr;
237 arg[5].arg_len = chld[1].arg_len;
241 arg[5].arg_type = A_EXPR;
242 arg[5].arg_ptr.arg_arg = chld;
247 fprintf(stderr,"%lx <= make_op(%s",arg,opname[arg->arg_type]);
249 fprintf(stderr,",%s=%lx",
250 argname[arg[1].arg_type&A_MASK],arg[1].arg_ptr.arg_arg);
252 fprintf(stderr,",%s=%lx",
253 argname[arg[2].arg_type&A_MASK],arg[2].arg_ptr.arg_arg);
255 fprintf(stderr,",%s=%lx",
256 argname[arg[3].arg_type&A_MASK],arg[3].arg_ptr.arg_arg);
258 fprintf(stderr,",%s=%lx",
259 argname[arg[4].arg_type&A_MASK],arg[4].arg_ptr.arg_arg);
261 fprintf(stderr,",%s=%lx",
262 argname[arg[5].arg_type&A_MASK],arg[5].arg_ptr.arg_arg);
263 fprintf(stderr,")\n");
266 evalstatic(arg); /* see if we can consolidate anything */
277 double value; /* must not be register */
280 unsigned long tmplong;
282 double exp(), log(), sqrt(), modf();
284 double sin(), cos(), atan2(), pow();
286 if (!arg || !arg->arg_len)
289 if ((arg[1].arg_type == A_SINGLE || arg->arg_type == O_AELEM) &&
290 (arg->arg_len == 1 || arg[2].arg_type == A_SINGLE) ) {
292 s1 = arg[1].arg_ptr.arg_str;
293 if (arg->arg_len > 1)
294 s2 = arg[2].arg_ptr.arg_str;
297 switch (arg->arg_type) {
299 i = (int)str_gnum(s2);
300 if (i < 32767 && i >= 0) {
301 arg->arg_type = O_ITEM;
303 arg[1].arg_type = A_ARYSTAB; /* $abc[123] is hoistable now */
305 arg[1].arg_ptr = arg[1].arg_ptr; /* get stab pointer */
311 str = Nullstr; /* can't be evaluated yet */
318 i = (int)str_gnum(s2);
321 STR_GROW(str, i * s1->str_cur + 1);
322 repeatcpy(str->str_ptr, tmps, s1->str_cur, i);
323 str->str_cur = i * s1->str_cur;
324 str->str_ptr[str->str_cur] = '\0';
327 value = str_gnum(s1);
328 str_numset(str,value * str_gnum(s2));
331 value = str_gnum(s2);
333 yyerror("Illegal division by constant zero");
335 str_numset(str,str_gnum(s1) / value);
338 tmplong = (long)str_gnum(s2);
340 yyerror("Illegal modulus of constant zero");
343 tmp2 = (long)str_gnum(s1);
346 str_numset(str,(double)(tmp2 % tmplong));
348 str_numset(str,(double)(tmplong - (-tmp2 % tmplong)));
354 value = str_gnum(s1);
355 str_numset(str,value + str_gnum(s2));
358 value = str_gnum(s1);
359 str_numset(str,value - str_gnum(s2));
362 value = str_gnum(s1);
363 i = (int)str_gnum(s2);
365 str_numset(str,(double)(((long)value) << i));
369 value = str_gnum(s1);
370 i = (int)str_gnum(s2);
372 str_numset(str,(double)(((long)value) >> i));
376 value = str_gnum(s1);
377 str_numset(str,(value < str_gnum(s2)) ? 1.0 : 0.0);
380 value = str_gnum(s1);
381 str_numset(str,(value > str_gnum(s2)) ? 1.0 : 0.0);
384 value = str_gnum(s1);
385 str_numset(str,(value <= str_gnum(s2)) ? 1.0 : 0.0);
388 value = str_gnum(s1);
389 str_numset(str,(value >= str_gnum(s2)) ? 1.0 : 0.0);
393 if ((!s1->str_nok && !looks_like_number(s1)) ||
394 (!s2->str_nok && !looks_like_number(s2)) )
395 warn("Possible use of == on string value");
397 value = str_gnum(s1);
398 str_numset(str,(value == str_gnum(s2)) ? 1.0 : 0.0);
401 value = str_gnum(s1);
402 str_numset(str,(value != str_gnum(s2)) ? 1.0 : 0.0);
405 value = str_gnum(s1);
407 str_numset(str,(double)(((long)value) & ((long)str_gnum(s2))));
411 value = str_gnum(s1);
413 str_numset(str,(double)(((long)value) ^ ((long)str_gnum(s2))));
417 value = str_gnum(s1);
419 str_numset(str,(double)(((long)value) | ((long)str_gnum(s2))));
435 if ((arg[3].arg_type & A_MASK) != A_SINGLE) {
443 str_sset(str,arg[3].arg_ptr.arg_str);
444 str_free(arg[3].arg_ptr.arg_str);
448 str_numset(str,(double)(-str_gnum(s1)));
451 str_numset(str,(double)(!str_true(s1)));
455 str_numset(str,(double)(~(long)str_gnum(s1)));
459 str_numset(str,sin(str_gnum(s1)));
462 str_numset(str,cos(str_gnum(s1)));
465 value = str_gnum(s1);
466 str_numset(str,atan2(value, str_gnum(s2)));
469 value = str_gnum(s1);
470 str_numset(str,pow(value, str_gnum(s2)));
473 str_numset(str, (double)str_len(s1));
476 str_numset(str,(double)(str_cmp(s1,s2) < 0));
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_eq(s1,s2)));
491 str_numset(str,(double)(!str_eq(s1,s2)));
496 str_set(str,crypt(tmps,str_get(s2)));
499 "The crypt() function is unimplemented due to excessive paranoia.");
503 str_numset(str,exp(str_gnum(s1)));
506 str_numset(str,log(str_gnum(s1)));
509 str_numset(str,sqrt(str_gnum(s1)));
512 value = str_gnum(s1);
514 (void)modf(value,&value);
516 (void)modf(-value,&value);
519 str_numset(str,value);
523 str_numset(str,(double)(*str_get(s1)));
531 str_numset(str,(double)(zapc));
537 arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */
540 arg[1].arg_ptr.arg_str = str;
555 i = arg[1].arg_type & A_MASK;
557 arg->arg_flags |= AF_COMMON; /* assume something in common */
558 /* which forces us to copy things */
561 arg[1].arg_type = A_LARYLEN;
564 if (i == A_ARYSTAB) {
565 arg[1].arg_type = A_LARYSTAB;
569 /* see if it's an array reference */
571 if (i == A_EXPR || i == A_LEXPR) {
572 arg1 = arg[1].arg_ptr.arg_arg;
574 if (arg1->arg_type == O_LIST || arg1->arg_type == O_ITEM) {
576 if (arg->arg_len > 1) {
578 arg2 = arg[2].arg_ptr.arg_arg;
579 if (nothing_in_common(arg1,arg2))
580 arg->arg_flags &= ~AF_COMMON;
581 if (arg->arg_type == O_ASSIGN) {
582 if (arg1->arg_flags & AF_LOCAL)
583 arg->arg_flags |= AF_LOCAL;
584 arg[1].arg_flags |= AF_ARYOK;
585 arg[2].arg_flags |= AF_ARYOK;
588 else if (arg->arg_type != O_CHOP)
589 arg->arg_type = O_ASSIGN; /* possible local(); */
590 for (i = arg1->arg_len; i >= 1; i--) {
591 switch (arg1[i].arg_type) {
592 case A_STAR: case A_LSTAR:
593 arg1[i].arg_type = A_LSTAR;
595 case A_STAB: case A_LVAL:
596 arg1[i].arg_type = A_LVAL;
598 case A_ARYLEN: case A_LARYLEN:
599 arg1[i].arg_type = A_LARYLEN;
601 case A_ARYSTAB: case A_LARYSTAB:
602 arg1[i].arg_type = A_LARYSTAB;
604 case A_EXPR: case A_LEXPR:
605 arg1[i].arg_type = A_LEXPR;
606 switch(arg1[i].arg_ptr.arg_arg->arg_type) {
607 case O_ARRAY: case O_LARRAY:
608 arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;
611 case O_AELEM: case O_LAELEM:
612 arg1[i].arg_ptr.arg_arg->arg_type = O_LAELEM;
614 case O_HASH: case O_LHASH:
615 arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;
618 case O_HELEM: case O_LHELEM:
619 arg1[i].arg_ptr.arg_arg->arg_type = O_LHELEM;
621 case O_ASLICE: case O_LASLICE:
622 arg1[i].arg_ptr.arg_arg->arg_type = O_LASLICE;
624 case O_HSLICE: case O_LHSLICE:
625 arg1[i].arg_ptr.arg_arg->arg_type = O_LHSLICE;
633 (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue",
634 argname[arg1[i].arg_type&A_MASK]);
638 if (arg->arg_len > 1) {
639 if (arg2->arg_type == O_SPLIT && !arg2[3].arg_type && !arghog) {
640 arg2[3].arg_type = A_SINGLE;
641 arg2[3].arg_ptr.arg_str =
642 str_nmake((double)arg1->arg_len + 1); /* limit split len*/
646 else if (arg1->arg_type == O_AELEM || arg1->arg_type == O_LAELEM)
647 if (arg->arg_type == O_DEFINED)
648 arg1->arg_type = O_AELEM;
650 arg1->arg_type = O_LAELEM;
651 else if (arg1->arg_type == O_ARRAY || arg1->arg_type == O_LARRAY) {
652 arg1->arg_type = O_LARRAY;
653 if (arg->arg_len > 1) {
655 arg2 = arg[2].arg_ptr.arg_arg;
656 if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/
657 spat = arg2[2].arg_ptr.arg_spat;
658 if (!(spat->spat_flags & SPAT_ONCE) &&
659 nothing_in_common(arg1,spat->spat_repl)) {
660 spat->spat_repl[1].arg_ptr.arg_stab =
661 arg1[1].arg_ptr.arg_stab;
662 spat->spat_flags |= SPAT_ONCE;
663 arg_free(arg1); /* recursive */
664 free_arg(arg); /* non-recursive */
665 return arg2; /* split has builtin assign */
668 else if (nothing_in_common(arg1,arg2))
669 arg->arg_flags &= ~AF_COMMON;
670 if (arg->arg_type == O_ASSIGN) {
671 arg[1].arg_flags |= AF_ARYOK;
672 arg[2].arg_flags |= AF_ARYOK;
675 else if (arg->arg_type == O_ASSIGN)
676 arg[1].arg_flags |= AF_ARYOK;
678 else if (arg1->arg_type == O_HELEM || arg1->arg_type == O_LHELEM)
679 if (arg->arg_type == O_DEFINED)
680 arg1->arg_type = O_HELEM; /* avoid creating one */
682 arg1->arg_type = O_LHELEM;
683 else if (arg1->arg_type == O_HASH || arg1->arg_type == O_LHASH) {
684 arg1->arg_type = O_LHASH;
685 if (arg->arg_len > 1) {
687 arg2 = arg[2].arg_ptr.arg_arg;
688 if (nothing_in_common(arg1,arg2))
689 arg->arg_flags &= ~AF_COMMON;
690 if (arg->arg_type == O_ASSIGN) {
691 arg[1].arg_flags |= AF_ARYOK;
692 arg[2].arg_flags |= AF_ARYOK;
695 else if (arg->arg_type == O_ASSIGN)
696 arg[1].arg_flags |= AF_ARYOK;
698 else if (arg1->arg_type == O_ASLICE) {
699 arg1->arg_type = O_LASLICE;
700 if (arg->arg_type == O_ASSIGN) {
701 arg[1].arg_flags |= AF_ARYOK;
702 arg[2].arg_flags |= AF_ARYOK;
705 else if (arg1->arg_type == O_HSLICE) {
706 arg1->arg_type = O_LHSLICE;
707 if (arg->arg_type == O_ASSIGN) {
708 arg[1].arg_flags |= AF_ARYOK;
709 arg[2].arg_flags |= AF_ARYOK;
712 else if ((arg->arg_type == O_DEFINED || arg->arg_type == O_UNDEF) &&
713 (arg1->arg_type == (perldb ? O_DBSUBR : O_SUBR)) ) {
714 arg[1].arg_type |= A_DONT;
716 else if (arg1->arg_type == O_SUBSTR || arg1->arg_type == O_VEC) {
718 Renewc(arg1->arg_ptr.arg_str, 1, struct lstring, STR);
719 /* grow string struct to hold an lstring struct */
721 else if (arg1->arg_type == O_ASSIGN) {
722 if (arg->arg_type == O_CHOP)
723 arg[1].arg_flags &= ~AF_ARYOK; /* grandfather chop idiom */
726 (void)sprintf(tokenbuf,
727 "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);
730 arg[1].arg_type = A_LEXPR | (arg[1].arg_type & A_DONT);
731 if (arg->arg_type == O_ASSIGN && (arg1[1].arg_flags & AF_ARYOK)) {
732 arg[1].arg_flags |= AF_ARYOK;
733 if (arg->arg_len > 1)
734 arg[2].arg_flags |= AF_ARYOK;
738 fprintf(stderr,"lval LEXPR\n");
742 if (i == A_STAR || i == A_LSTAR) {
743 arg[1].arg_type = A_LSTAR | (arg[1].arg_type & A_DONT);
747 /* not an array reference, should be a register name */
749 if (i != A_STAB && i != A_LVAL) {
750 (void)sprintf(tokenbuf,
751 "Illegal item (%s) as lvalue",argname[arg[1].arg_type&A_MASK]);
754 arg[1].arg_type = A_LVAL | (arg[1].arg_type & A_DONT);
757 fprintf(stderr,"lval LVAL\n");
767 if (type == O_DEFINED || type == O_UNDEF) {
768 if (arg->arg_type != O_ITEM)
770 if (arg->arg_type == O_ITEM) {
771 type = arg[1].arg_type & A_MASK;
772 if (type == A_EXPR || type == A_LEXPR)
773 arg[1].arg_type = A_LEXPR|A_DONT;
784 if (arg[i].arg_type != A_EXPR) { /* dehoist */
785 tmparg = make_op(O_ITEM,1,Nullarg,Nullarg,Nullarg);
787 arg[i].arg_ptr.arg_arg = tmparg;
788 arg[i].arg_type = A_EXPR;
793 addflags(i,flags,arg)
796 arg[i].arg_flags |= flags;
804 if (arg->arg_type == O_ARRAY || arg->arg_type == O_HASH)
805 return make_op(O_ITEM,1,arg,Nullarg,Nullarg);
809 /* maybe do a join on multiple array dimensions */
815 if (arg && arg->arg_type == O_COMMA) {
817 arg = make_op(O_JOIN, 2,
818 stab2arg(A_STAB,stabent(";",TRUE)),
831 register ARG *nxtnode;
837 arg->arg_type = O_LIST;
839 if (arg->arg_type != O_COMMA) {
840 if (arg->arg_type != O_ARRAY)
841 arg->arg_flags |= AF_LISTISH; /* see listish() below */
844 for (i = 2, node = arg; ; i++) {
845 if (node->arg_len < 2)
847 if (node[1].arg_type != A_EXPR)
849 node = node[1].arg_ptr.arg_arg;
850 if (node->arg_type != O_COMMA)
856 tmpstr = arg->arg_ptr.arg_str;
858 *arg = *node; /* copy everything except the STR */
860 (void)bcopy((char *)node, (char *)arg, sizeof(ARG));
862 arg->arg_ptr.arg_str = tmpstr;
867 (void)bcopy((char *)(node+2), (char *)(arg+j), sizeof(ARG));
869 arg[j].arg_flags |= AF_ARYOK;
870 --j; /* Bug in Xenix compiler */
875 (void)bcopy((char *)(node+1), (char *)(arg+1), sizeof(ARG));
880 nxtnode = node[1].arg_ptr.arg_arg;
885 arg[1].arg_flags |= AF_ARYOK;
886 arg[2].arg_flags |= AF_ARYOK;
887 arg->arg_type = O_LIST;
892 /* turn a single item into a list */
898 if (arg->arg_flags & AF_LISTISH)
899 arg = make_op(O_LIST,1,arg,Nullarg,Nullarg);
904 maybelistish(optype, arg)
908 if (optype == O_PRTF ||
909 (arg->arg_type == O_ASLICE || arg->arg_type == O_HSLICE ||
910 arg->arg_type == O_F_OR_R) )
915 /* mark list of local variables */
921 arg->arg_flags |= AF_LOCAL;
930 if (arg->arg_len == 0)
931 arg[1].arg_type = A_NULL;
933 arg[2].arg_ptr.arg_hash = curstash;
934 arg[2].arg_type = A_NULL;
942 if (arg->arg_type == O_CONCAT && arg[2].arg_type == A_READ) {
943 arg->arg_type = O_RCAT;
944 arg[2].arg_type = arg[2].arg_ptr.arg_arg[1].arg_type;
945 arg[2].arg_ptr = arg[2].arg_ptr.arg_arg[1].arg_ptr;
946 free_arg(arg[2].arg_ptr.arg_arg);
959 arg->arg_type = O_ITEM;
960 arg[1].arg_type = atype;
961 arg[1].arg_ptr.arg_stab = stab;
972 arg->arg_type = O_ITEM;
973 arg[1].arg_type = A_SINGLE;
974 arg[1].arg_ptr.arg_str = str_make(cval,0);
985 Newz(203,arg, numargs + 1, ARG);
986 arg->arg_ptr.arg_str = Str_new(21,0);
987 arg->arg_len = numargs;
995 str_free(arg->arg_ptr.arg_str);
1000 make_match(type,expr,spat)
1007 arg = make_op(type,2,expr,Nullarg,Nullarg);
1009 arg[2].arg_type = A_SPAT|A_DONT;
1010 arg[2].arg_ptr.arg_spat = spat;
1013 fprintf(stderr,"make_match SPAT=%lx\n",(long)spat);
1016 if (type == O_SUBST || type == O_NSUBST) {
1017 if (arg[1].arg_type != A_STAB) {
1018 yyerror("Illegal lvalue");
1020 arg[1].arg_type = A_LVAL;
1032 arg->arg_type = O_ITEM;
1033 arg[1].arg_type = A_CMD;
1034 arg[1].arg_ptr.arg_cmd = cmd;
1038 /* Check two expressions to see if there is any identifier in common */
1041 nothing_in_common(arg1,arg2)
1045 static int thisexpr = 0; /* I don't care if this wraps */
1048 if (arg_common(arg1,thisexpr,1))
1049 return 0; /* hit eval or do {} */
1050 if (arg_common(arg2,thisexpr,0))
1051 return 0; /* hit identifier again */
1055 /* Recursively descend an expression and mark any identifier or check
1056 * it to see if it was marked already.
1060 arg_common(arg,exprnum,marking)
1069 for (i = arg->arg_len; i >= 1; i--) {
1070 switch (arg[i].arg_type & A_MASK) {
1075 if (arg_common(arg[i].arg_ptr.arg_arg,exprnum,marking))
1079 return 1; /* assume hanky panky */
1087 stab_lastexpr(arg[i].arg_ptr.arg_stab) = exprnum;
1088 else if (stab_lastexpr(arg[i].arg_ptr.arg_stab) == exprnum)
1094 register char *s = arg[i].arg_ptr.arg_str->str_ptr;
1095 register char *send = s + arg[i].arg_ptr.arg_str->str_cur;
1096 register STAB *stab;
1099 if (*s == '$' && s[1]) {
1100 s = scanreg(s,send,tokenbuf);
1101 stab = stabent(tokenbuf,TRUE);
1103 stab_lastexpr(stab) = exprnum;
1104 else if (stab_lastexpr(stab) == exprnum)
1108 else if (*s == '\\' && s[1])
1115 if (spat_common(arg[i].arg_ptr.arg_spat,exprnum,marking))
1126 switch (arg->arg_type) {
1129 if ((arg[1].arg_type & A_MASK) == A_STAB)
1130 (void)aadd(arg[1].arg_ptr.arg_stab);
1134 if ((arg[1].arg_type & A_MASK) == A_STAB)
1135 (void)hadd(arg[1].arg_ptr.arg_stab);
1146 spat_common(spat,exprnum,marking)
1147 register SPAT *spat;
1151 if (spat->spat_runtime)
1152 if (arg_common(spat->spat_runtime,exprnum,marking))
1154 if (spat->spat_repl) {
1155 if (arg_common(spat->spat_repl,exprnum,marking))