1 /* $Header: consarg.c,v 3.0.1.6 90/08/09 02:38:51 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.6 90/08/09 02:38:51 lwall
10 * patch19: fixed problem with % of negative number
12 * Revision 3.0.1.5 90/03/27 15:36:45 lwall
13 * patch16: support for machines that can't cast negative floats to unsigned ints
15 * Revision 3.0.1.4 90/03/12 16:24:40 lwall
16 * patch13: return (@array) did counter-intuitive things
18 * Revision 3.0.1.3 90/02/28 16:47:54 lwall
19 * patch9: the x operator is now up to 10 times faster
20 * patch9: @_ clobbered by ($foo,$bar) = split
22 * Revision 3.0.1.2 89/11/17 15:11:34 lwall
23 * patch5: defined $foo{'bar'} should not create element
25 * Revision 3.0.1.1 89/11/11 04:14:30 lwall
26 * patch2: '-' x 26 made warnings about undefined value
27 * patch2: eval with no args caused strangeness
28 * patch2: local(@foo) didn't work, but local(@foo,$bar) did
30 * Revision 3.0 89/10/18 15:10:30 lwall
37 static int nothing_in_common();
38 static int arg_common();
39 static int spat_common();
42 make_split(stab,arg,limarg)
49 if (arg->arg_type != O_MATCH) {
50 Newz(201,spat,1,SPAT);
51 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
52 curstash->tbl_spatroot = spat;
54 spat->spat_runtime = arg;
55 arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
60 if (limarg->arg_type == O_ITEM) {
61 Copy(limarg+1,arg+3,1,ARG);
62 limarg[1].arg_type = A_NULL;
67 arg[3].arg_type = A_EXPR;
68 arg[3].arg_ptr.arg_arg = limarg;
72 arg[3].arg_type = A_NULL;
73 arg->arg_type = O_SPLIT;
74 spat = arg[2].arg_ptr.arg_spat;
75 spat->spat_repl = stab2arg(A_STAB,aadd(stab));
76 if (spat->spat_short) { /* exact match can bypass regexec() */
77 if (!((spat->spat_flags & SPAT_SCANFIRST) &&
78 (spat->spat_flags & SPAT_ALL) )) {
79 str_free(spat->spat_short);
80 spat->spat_short = Nullstr;
87 mod_match(type,left,pat)
95 if ((pat->arg_type == O_MATCH ||
96 pat->arg_type == O_SUBST ||
97 pat->arg_type == O_TRANS ||
98 pat->arg_type == O_SPLIT
100 pat[1].arg_ptr.arg_stab == defstab ) {
101 switch (pat->arg_type) {
103 newarg = make_op(type == O_MATCH ? O_MATCH : O_NMATCH,
105 left,Nullarg,Nullarg);
108 newarg = l(make_op(type == O_MATCH ? O_SUBST : O_NSUBST,
110 left,Nullarg,Nullarg));
113 newarg = l(make_op(type == O_MATCH ? O_TRANS : O_NTRANS,
115 left,Nullarg,Nullarg));
118 newarg = make_op(type == O_MATCH ? O_SPLIT : O_SPLIT,
120 left,Nullarg,Nullarg);
123 if (pat->arg_len >= 2) {
124 newarg[2].arg_type = pat[2].arg_type;
125 newarg[2].arg_ptr = pat[2].arg_ptr;
126 newarg[2].arg_flags = pat[2].arg_flags;
127 if (pat->arg_len >= 3) {
128 newarg[3].arg_type = pat[3].arg_type;
129 newarg[3].arg_ptr = pat[3].arg_ptr;
130 newarg[3].arg_flags = pat[3].arg_flags;
136 Newz(202,spat,1,SPAT);
137 spat->spat_next = curstash->tbl_spatroot; /* link into spat list */
138 curstash->tbl_spatroot = spat;
140 spat->spat_runtime = pat;
141 newarg = make_op(type,2,left,Nullarg,Nullarg);
142 newarg[2].arg_type = A_SPAT | A_DONT;
143 newarg[2].arg_ptr.arg_spat = spat;
150 make_op(type,newlen,arg1,arg2,arg3)
160 extern ARG *arg4; /* should be normal arguments, really */
163 arg = op_new(newlen);
164 arg->arg_type = type;
165 doarg = opargs[type];
167 if (chld->arg_type == O_ITEM &&
168 (hoistable[chld[1].arg_type] || chld[1].arg_type == A_LVAL ||
169 (chld[1].arg_type == A_LEXPR &&
170 (chld[1].arg_ptr.arg_arg->arg_type == O_LIST ||
171 chld[1].arg_ptr.arg_arg->arg_type == O_ARRAY ||
172 chld[1].arg_ptr.arg_arg->arg_type == O_HASH ))))
174 arg[1].arg_type = chld[1].arg_type;
175 arg[1].arg_ptr = chld[1].arg_ptr;
176 arg[1].arg_flags |= chld[1].arg_flags;
177 arg[1].arg_len = chld[1].arg_len;
181 arg[1].arg_type = A_EXPR;
182 arg[1].arg_ptr.arg_arg = chld;
185 arg[1].arg_type |= A_DONT;
187 arg[1].arg_flags |= AF_ARYOK;
191 if (chld->arg_type == O_ITEM &&
192 (hoistable[chld[1].arg_type] ||
194 ((chld[1].arg_type == A_READ && !(arg[1].arg_type & A_DONT))
196 (chld[1].arg_type == A_INDREAD && !(arg[1].arg_type & A_DONT))
198 (chld[1].arg_type == A_GLOB && !(arg[1].arg_type & A_DONT))
200 arg[2].arg_type = chld[1].arg_type;
201 arg[2].arg_ptr = chld[1].arg_ptr;
202 arg[2].arg_len = chld[1].arg_len;
206 arg[2].arg_type = A_EXPR;
207 arg[2].arg_ptr.arg_arg = chld;
210 arg[2].arg_type |= A_DONT;
212 arg[2].arg_flags |= AF_ARYOK;
216 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
217 arg[3].arg_type = chld[1].arg_type;
218 arg[3].arg_ptr = chld[1].arg_ptr;
219 arg[3].arg_len = chld[1].arg_len;
223 arg[3].arg_type = A_EXPR;
224 arg[3].arg_ptr.arg_arg = chld;
227 arg[3].arg_type |= A_DONT;
229 arg[3].arg_flags |= AF_ARYOK;
231 if (newlen >= 4 && (chld = arg4)) {
232 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
233 arg[4].arg_type = chld[1].arg_type;
234 arg[4].arg_ptr = chld[1].arg_ptr;
235 arg[4].arg_len = chld[1].arg_len;
239 arg[4].arg_type = A_EXPR;
240 arg[4].arg_ptr.arg_arg = chld;
243 if (newlen >= 5 && (chld = arg5)) {
244 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
245 arg[5].arg_type = chld[1].arg_type;
246 arg[5].arg_ptr = chld[1].arg_ptr;
247 arg[5].arg_len = chld[1].arg_len;
251 arg[5].arg_type = A_EXPR;
252 arg[5].arg_ptr.arg_arg = chld;
257 fprintf(stderr,"%lx <= make_op(%s",arg,opname[arg->arg_type]);
259 fprintf(stderr,",%s=%lx",
260 argname[arg[1].arg_type&A_MASK],arg[1].arg_ptr.arg_arg);
262 fprintf(stderr,",%s=%lx",
263 argname[arg[2].arg_type&A_MASK],arg[2].arg_ptr.arg_arg);
265 fprintf(stderr,",%s=%lx",
266 argname[arg[3].arg_type&A_MASK],arg[3].arg_ptr.arg_arg);
268 fprintf(stderr,",%s=%lx",
269 argname[arg[4].arg_type&A_MASK],arg[4].arg_ptr.arg_arg);
271 fprintf(stderr,",%s=%lx",
272 argname[arg[5].arg_type&A_MASK],arg[5].arg_ptr.arg_arg);
273 fprintf(stderr,")\n");
276 evalstatic(arg); /* see if we can consolidate anything */
287 double value; /* must not be register */
290 unsigned long tmplong;
292 double exp(), log(), sqrt(), modf();
294 double sin(), cos(), atan2(), pow();
296 if (!arg || !arg->arg_len)
299 if ((arg[1].arg_type == A_SINGLE || arg->arg_type == O_AELEM) &&
300 (arg->arg_len == 1 || arg[2].arg_type == A_SINGLE) ) {
302 s1 = arg[1].arg_ptr.arg_str;
303 if (arg->arg_len > 1)
304 s2 = arg[2].arg_ptr.arg_str;
307 switch (arg->arg_type) {
309 i = (int)str_gnum(s2);
310 if (i < 32767 && i >= 0) {
311 arg->arg_type = O_ITEM;
313 arg[1].arg_type = A_ARYSTAB; /* $abc[123] is hoistable now */
320 str = Nullstr; /* can't be evaluated yet */
327 i = (int)str_gnum(s2);
330 STR_GROW(str, i * s1->str_cur + 1);
331 repeatcpy(str->str_ptr, tmps, s1->str_cur, i);
332 str->str_cur = i * s1->str_cur;
333 str->str_ptr[str->str_cur] = '\0';
336 value = str_gnum(s1);
337 str_numset(str,value * str_gnum(s2));
340 value = str_gnum(s2);
342 yyerror("Illegal division by constant zero");
344 str_numset(str,str_gnum(s1) / value);
347 tmplong = (unsigned long)str_gnum(s2);
349 yyerror("Illegal modulus of constant zero");
352 tmp2 = (long)str_gnum(s1);
355 str_numset(str,(double)(tmp2 % tmplong));
357 str_numset(str,(double)(tmplong - ((-tmp2 - 1) % tmplong))) - 1;
363 value = str_gnum(s1);
364 str_numset(str,value + str_gnum(s2));
367 value = str_gnum(s1);
368 str_numset(str,value - str_gnum(s2));
371 value = str_gnum(s1);
372 i = (int)str_gnum(s2);
374 str_numset(str,(double)(((long)value) << i));
378 value = str_gnum(s1);
379 i = (int)str_gnum(s2);
381 str_numset(str,(double)(((long)value) >> i));
385 value = str_gnum(s1);
386 str_numset(str,(value < str_gnum(s2)) ? 1.0 : 0.0);
389 value = str_gnum(s1);
390 str_numset(str,(value > str_gnum(s2)) ? 1.0 : 0.0);
393 value = str_gnum(s1);
394 str_numset(str,(value <= str_gnum(s2)) ? 1.0 : 0.0);
397 value = str_gnum(s1);
398 str_numset(str,(value >= str_gnum(s2)) ? 1.0 : 0.0);
402 if ((!s1->str_nok && !looks_like_number(s1)) ||
403 (!s2->str_nok && !looks_like_number(s2)) )
404 warn("Possible use of == on string value");
406 value = str_gnum(s1);
407 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);
414 value = str_gnum(s1);
416 str_numset(str,(double)(U_L(value) & U_L(str_gnum(s2))));
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))));
444 if ((arg[3].arg_type & A_MASK) != A_SINGLE) {
452 str_sset(str,arg[3].arg_ptr.arg_str);
453 str_free(arg[3].arg_ptr.arg_str);
457 str_numset(str,(double)(-str_gnum(s1)));
460 str_numset(str,(double)(!str_true(s1)));
464 str_numset(str,(double)(~U_L(str_gnum(s1))));
468 str_numset(str,sin(str_gnum(s1)));
471 str_numset(str,cos(str_gnum(s1)));
474 value = str_gnum(s1);
475 str_numset(str,atan2(value, str_gnum(s2)));
478 value = str_gnum(s1);
479 str_numset(str,pow(value, str_gnum(s2)));
482 str_numset(str, (double)str_len(s1));
485 str_numset(str,(double)(str_cmp(s1,s2) < 0));
488 str_numset(str,(double)(str_cmp(s1,s2) > 0));
491 str_numset(str,(double)(str_cmp(s1,s2) <= 0));
494 str_numset(str,(double)(str_cmp(s1,s2) >= 0));
497 str_numset(str,(double)(str_eq(s1,s2)));
500 str_numset(str,(double)(!str_eq(s1,s2)));
505 str_set(str,crypt(tmps,str_get(s2)));
508 "The crypt() function is unimplemented due to excessive paranoia.");
512 str_numset(str,exp(str_gnum(s1)));
515 str_numset(str,log(str_gnum(s1)));
518 str_numset(str,sqrt(str_gnum(s1)));
521 value = str_gnum(s1);
523 (void)modf(value,&value);
525 (void)modf(-value,&value);
528 str_numset(str,value);
532 str_numset(str,(double)(*str_get(s1)));
540 str_numset(str,(double)(zapc));
546 arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */
549 arg[1].arg_ptr.arg_str = str;
564 i = arg[1].arg_type & A_MASK;
566 arg->arg_flags |= AF_COMMON; /* assume something in common */
567 /* which forces us to copy things */
570 arg[1].arg_type = A_LARYLEN;
573 if (i == A_ARYSTAB) {
574 arg[1].arg_type = A_LARYSTAB;
578 /* see if it's an array reference */
580 if (i == A_EXPR || i == A_LEXPR) {
581 arg1 = arg[1].arg_ptr.arg_arg;
583 if (arg1->arg_type == O_LIST || arg1->arg_type == O_ITEM) {
585 if (arg->arg_len > 1) {
587 arg2 = arg[2].arg_ptr.arg_arg;
588 if (nothing_in_common(arg1,arg2))
589 arg->arg_flags &= ~AF_COMMON;
590 if (arg->arg_type == O_ASSIGN) {
591 if (arg1->arg_flags & AF_LOCAL)
592 arg->arg_flags |= AF_LOCAL;
593 arg[1].arg_flags |= AF_ARYOK;
594 arg[2].arg_flags |= AF_ARYOK;
597 else if (arg->arg_type != O_CHOP)
598 arg->arg_type = O_ASSIGN; /* possible local(); */
599 for (i = arg1->arg_len; i >= 1; i--) {
600 switch (arg1[i].arg_type) {
601 case A_STAR: case A_LSTAR:
602 arg1[i].arg_type = A_LSTAR;
604 case A_STAB: case A_LVAL:
605 arg1[i].arg_type = A_LVAL;
607 case A_ARYLEN: case A_LARYLEN:
608 arg1[i].arg_type = A_LARYLEN;
610 case A_ARYSTAB: case A_LARYSTAB:
611 arg1[i].arg_type = A_LARYSTAB;
613 case A_EXPR: case A_LEXPR:
614 arg1[i].arg_type = A_LEXPR;
615 switch(arg1[i].arg_ptr.arg_arg->arg_type) {
616 case O_ARRAY: case O_LARRAY:
617 arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;
620 case O_AELEM: case O_LAELEM:
621 arg1[i].arg_ptr.arg_arg->arg_type = O_LAELEM;
623 case O_HASH: case O_LHASH:
624 arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;
627 case O_HELEM: case O_LHELEM:
628 arg1[i].arg_ptr.arg_arg->arg_type = O_LHELEM;
630 case O_ASLICE: case O_LASLICE:
631 arg1[i].arg_ptr.arg_arg->arg_type = O_LASLICE;
633 case O_HSLICE: case O_LHSLICE:
634 arg1[i].arg_ptr.arg_arg->arg_type = O_LHSLICE;
642 (void)sprintf(tokenbuf, "Illegal item (%s) as lvalue",
643 argname[arg1[i].arg_type&A_MASK]);
647 if (arg->arg_len > 1) {
648 if (arg2->arg_type == O_SPLIT && !arg2[3].arg_type && !arghog) {
649 arg2[3].arg_type = A_SINGLE;
650 arg2[3].arg_ptr.arg_str =
651 str_nmake((double)arg1->arg_len + 1); /* limit split len*/
655 else if (arg1->arg_type == O_AELEM || arg1->arg_type == O_LAELEM)
656 if (arg->arg_type == O_DEFINED)
657 arg1->arg_type = O_AELEM;
659 arg1->arg_type = O_LAELEM;
660 else if (arg1->arg_type == O_ARRAY || arg1->arg_type == O_LARRAY) {
661 arg1->arg_type = O_LARRAY;
662 if (arg->arg_len > 1) {
664 arg2 = arg[2].arg_ptr.arg_arg;
665 if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/
666 spat = arg2[2].arg_ptr.arg_spat;
667 if (!(spat->spat_flags & SPAT_ONCE) &&
668 nothing_in_common(arg1,spat->spat_repl)) {
669 spat->spat_repl[1].arg_ptr.arg_stab =
670 arg1[1].arg_ptr.arg_stab;
671 spat->spat_flags |= SPAT_ONCE;
672 arg_free(arg1); /* recursive */
673 free_arg(arg); /* non-recursive */
674 return arg2; /* split has builtin assign */
677 else if (nothing_in_common(arg1,arg2))
678 arg->arg_flags &= ~AF_COMMON;
679 if (arg->arg_type == O_ASSIGN) {
680 arg[1].arg_flags |= AF_ARYOK;
681 arg[2].arg_flags |= AF_ARYOK;
684 else if (arg->arg_type == O_ASSIGN)
685 arg[1].arg_flags |= AF_ARYOK;
687 else if (arg1->arg_type == O_HELEM || arg1->arg_type == O_LHELEM)
688 if (arg->arg_type == O_DEFINED)
689 arg1->arg_type = O_HELEM; /* avoid creating one */
691 arg1->arg_type = O_LHELEM;
692 else if (arg1->arg_type == O_HASH || arg1->arg_type == O_LHASH) {
693 arg1->arg_type = O_LHASH;
694 if (arg->arg_len > 1) {
696 arg2 = arg[2].arg_ptr.arg_arg;
697 if (nothing_in_common(arg1,arg2))
698 arg->arg_flags &= ~AF_COMMON;
699 if (arg->arg_type == O_ASSIGN) {
700 arg[1].arg_flags |= AF_ARYOK;
701 arg[2].arg_flags |= AF_ARYOK;
704 else if (arg->arg_type == O_ASSIGN)
705 arg[1].arg_flags |= AF_ARYOK;
707 else if (arg1->arg_type == O_ASLICE) {
708 arg1->arg_type = O_LASLICE;
709 if (arg->arg_type == O_ASSIGN) {
710 arg[1].arg_flags |= AF_ARYOK;
711 arg[2].arg_flags |= AF_ARYOK;
714 else if (arg1->arg_type == O_HSLICE) {
715 arg1->arg_type = O_LHSLICE;
716 if (arg->arg_type == O_ASSIGN) {
717 arg[1].arg_flags |= AF_ARYOK;
718 arg[2].arg_flags |= AF_ARYOK;
721 else if ((arg->arg_type == O_DEFINED || arg->arg_type == O_UNDEF) &&
722 (arg1->arg_type == (perldb ? O_DBSUBR : O_SUBR)) ) {
723 arg[1].arg_type |= A_DONT;
725 else if (arg1->arg_type == O_SUBSTR || arg1->arg_type == O_VEC) {
727 Renewc(arg1->arg_ptr.arg_str, 1, struct lstring, STR);
728 /* grow string struct to hold an lstring struct */
730 else if (arg1->arg_type == O_ASSIGN) {
731 if (arg->arg_type == O_CHOP)
732 arg[1].arg_flags &= ~AF_ARYOK; /* grandfather chop idiom */
735 (void)sprintf(tokenbuf,
736 "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);
739 arg[1].arg_type = A_LEXPR | (arg[1].arg_type & A_DONT);
740 if (arg->arg_type == O_ASSIGN && (arg1[1].arg_flags & AF_ARYOK)) {
741 arg[1].arg_flags |= AF_ARYOK;
742 if (arg->arg_len > 1)
743 arg[2].arg_flags |= AF_ARYOK;
747 fprintf(stderr,"lval LEXPR\n");
751 if (i == A_STAR || i == A_LSTAR) {
752 arg[1].arg_type = A_LSTAR | (arg[1].arg_type & A_DONT);
756 /* not an array reference, should be a register name */
758 if (i != A_STAB && i != A_LVAL) {
759 (void)sprintf(tokenbuf,
760 "Illegal item (%s) as lvalue",argname[arg[1].arg_type&A_MASK]);
763 arg[1].arg_type = A_LVAL | (arg[1].arg_type & A_DONT);
766 fprintf(stderr,"lval LVAL\n");
776 if (type == O_DEFINED || type == O_UNDEF) {
777 if (arg->arg_type != O_ITEM)
779 if (arg->arg_type == O_ITEM) {
780 type = arg[1].arg_type & A_MASK;
781 if (type == A_EXPR || type == A_LEXPR)
782 arg[1].arg_type = A_LEXPR|A_DONT;
793 if (arg[i].arg_type != A_EXPR) { /* dehoist */
794 tmparg = make_op(O_ITEM,1,Nullarg,Nullarg,Nullarg);
796 arg[i].arg_ptr.arg_arg = tmparg;
797 arg[i].arg_type = A_EXPR;
802 addflags(i,flags,arg)
805 arg[i].arg_flags |= flags;
813 if (arg->arg_type == O_ARRAY || arg->arg_type == O_HASH)
814 return make_op(O_ITEM,1,arg,Nullarg,Nullarg);
818 /* maybe do a join on multiple array dimensions */
824 if (arg && arg->arg_type == O_COMMA) {
826 arg = make_op(O_JOIN, 2,
827 stab2arg(A_STAB,stabent(";",TRUE)),
840 register ARG *nxtnode;
846 arg->arg_type = O_LIST;
848 if (arg->arg_type != O_COMMA) {
849 if (arg->arg_type != O_ARRAY)
850 arg->arg_flags |= AF_LISTISH; /* see listish() below */
853 for (i = 2, node = arg; ; i++) {
854 if (node->arg_len < 2)
856 if (node[1].arg_type != A_EXPR)
858 node = node[1].arg_ptr.arg_arg;
859 if (node->arg_type != O_COMMA)
865 tmpstr = arg->arg_ptr.arg_str;
867 *arg = *node; /* copy everything except the STR */
869 (void)bcopy((char *)node, (char *)arg, sizeof(ARG));
871 arg->arg_ptr.arg_str = tmpstr;
876 (void)bcopy((char *)(node+2), (char *)(arg+j), sizeof(ARG));
878 arg[j].arg_flags |= AF_ARYOK;
879 --j; /* Bug in Xenix compiler */
884 (void)bcopy((char *)(node+1), (char *)(arg+1), sizeof(ARG));
889 nxtnode = node[1].arg_ptr.arg_arg;
894 arg[1].arg_flags |= AF_ARYOK;
895 arg[2].arg_flags |= AF_ARYOK;
896 arg->arg_type = O_LIST;
901 /* turn a single item into a list */
907 if (arg->arg_flags & AF_LISTISH)
908 arg = make_op(O_LIST,1,arg,Nullarg,Nullarg);
913 maybelistish(optype, arg)
919 if (optype == O_RETURN && arg->arg_type == O_ITEM &&
920 arg[1].arg_type == A_EXPR && (tmparg = arg[1].arg_ptr.arg_arg) &&
921 ((tmparg->arg_flags & AF_LISTISH) || (tmparg->arg_type == O_ARRAY) )) {
922 tmparg = listish(tmparg);
926 else if (optype == O_PRTF ||
927 (arg->arg_type == O_ASLICE || arg->arg_type == O_HSLICE ||
928 arg->arg_type == O_F_OR_R) )
933 /* mark list of local variables */
939 arg->arg_flags |= AF_LOCAL;
948 if (arg->arg_len == 0)
949 arg[1].arg_type = A_NULL;
951 arg[2].arg_flags = 0;
952 arg[2].arg_ptr.arg_hash = curstash;
953 arg[2].arg_type = A_NULL;
961 if (arg->arg_type == O_CONCAT && arg[2].arg_type == A_READ) {
962 arg->arg_type = O_RCAT;
963 arg[2].arg_type = arg[2].arg_ptr.arg_arg[1].arg_type;
964 arg[2].arg_ptr = arg[2].arg_ptr.arg_arg[1].arg_ptr;
965 free_arg(arg[2].arg_ptr.arg_arg);
978 arg->arg_type = O_ITEM;
979 arg[1].arg_type = atype;
980 arg[1].arg_ptr.arg_stab = stab;
991 arg->arg_type = O_ITEM;
992 arg[1].arg_type = A_SINGLE;
993 arg[1].arg_ptr.arg_str = str_make(cval,0);
1004 Newz(203,arg, numargs + 1, ARG);
1005 arg->arg_ptr.arg_str = Str_new(21,0);
1006 arg->arg_len = numargs;
1014 str_free(arg->arg_ptr.arg_str);
1019 make_match(type,expr,spat)
1026 arg = make_op(type,2,expr,Nullarg,Nullarg);
1028 arg[2].arg_type = A_SPAT|A_DONT;
1029 arg[2].arg_ptr.arg_spat = spat;
1032 fprintf(stderr,"make_match SPAT=%lx\n",(long)spat);
1035 if (type == O_SUBST || type == O_NSUBST) {
1036 if (arg[1].arg_type != A_STAB) {
1037 yyerror("Illegal lvalue");
1039 arg[1].arg_type = A_LVAL;
1051 arg->arg_type = O_ITEM;
1052 arg[1].arg_type = A_CMD;
1053 arg[1].arg_ptr.arg_cmd = cmd;
1057 /* Check two expressions to see if there is any identifier in common */
1060 nothing_in_common(arg1,arg2)
1064 static int thisexpr = 0; /* I don't care if this wraps */
1067 if (arg_common(arg1,thisexpr,1))
1068 return 0; /* hit eval or do {} */
1069 if (arg_common(arg2,thisexpr,0))
1070 return 0; /* hit identifier again */
1074 /* Recursively descend an expression and mark any identifier or check
1075 * it to see if it was marked already.
1079 arg_common(arg,exprnum,marking)
1088 for (i = arg->arg_len; i >= 1; i--) {
1089 switch (arg[i].arg_type & A_MASK) {
1094 if (arg_common(arg[i].arg_ptr.arg_arg,exprnum,marking))
1098 return 1; /* assume hanky panky */
1106 stab_lastexpr(arg[i].arg_ptr.arg_stab) = exprnum;
1107 else if (stab_lastexpr(arg[i].arg_ptr.arg_stab) == exprnum)
1113 register char *s = arg[i].arg_ptr.arg_str->str_ptr;
1114 register char *send = s + arg[i].arg_ptr.arg_str->str_cur;
1115 register STAB *stab;
1118 if (*s == '$' && s[1]) {
1119 s = scanreg(s,send,tokenbuf);
1120 stab = stabent(tokenbuf,TRUE);
1122 stab_lastexpr(stab) = exprnum;
1123 else if (stab_lastexpr(stab) == exprnum)
1127 else if (*s == '\\' && s[1])
1134 if (spat_common(arg[i].arg_ptr.arg_spat,exprnum,marking))
1145 switch (arg->arg_type) {
1148 if ((arg[1].arg_type & A_MASK) == A_STAB)
1149 (void)aadd(arg[1].arg_ptr.arg_stab);
1153 if ((arg[1].arg_type & A_MASK) == A_STAB)
1154 (void)hadd(arg[1].arg_ptr.arg_stab);
1165 spat_common(spat,exprnum,marking)
1166 register SPAT *spat;
1170 if (spat->spat_runtime)
1171 if (arg_common(spat->spat_runtime,exprnum,marking))
1173 if (spat->spat_repl) {
1174 if (arg_common(spat->spat_repl,exprnum,marking))