summaryrefslogtreecommitdiff
path: root/do/slice
blob: a55a69e12207d46b42a23479e5056c9af996bd02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
int
do_slice(stab,TARG,numarray,lval,gimme,arglast)
STAB *stab;
STR *TARG;
int numarray;
int lval;
int gimme;
int *arglast;
{
    register STR **st = stack->ary_array;
    register int sp = arglast[1];
    register int max = arglast[2];
    register char *tmps;
    register int len;
    register int magic = 0;
    register ARRAY *ary;
    register HASH *hash;
    int oldarybase = arybase;

    if (numarray) {
	if (numarray == 2) {		/* a slice of a LIST */
	    ary = stack;
	    ary->ary_fill = arglast[3];
	    arybase -= max + 1;
	    st[sp] = TARG;		/* make stack size available */
	    str_numset(TARG,(double)(sp - 1));
	}
	else
	    ary = stab_array(stab);	/* a slice of an array */
    }
    else {
	if (lval) {
	    if (stab == envstab)
		magic = 'E';
	    else if (stab == sigstab)
		magic = 'S';
#ifdef SOME_DBM
	    else if (stab_hash(stab)->tbl_dbm)
		magic = 'D';
#endif /* SOME_DBM */
	}
	hash = stab_hash(stab);		/* a slice of an associative array */
    }

    if (gimme == G_ARRAY) {
	if (numarray) {
	    while (sp < max) {
		if (st[++sp]) {
		    st[sp-1] = afetch(ary,
		      ((int)str_gnum(st[sp])) - arybase, lval);
		}
		else
		    st[sp-1] = &str_undef;
	    }
	}
	else {
	    while (sp < max) {
		if (st[++sp]) {
		    tmps = str_get(st[sp]);
		    len = st[sp]->str_cur;
		    st[sp-1] = hfetch(hash,tmps,len, lval);
		    if (magic)
			str_magic(st[sp-1],stab,magic,tmps,len);
		}
		else
		    st[sp-1] = &str_undef;
	    }
	}
	sp--;
    }
    else {
	if (sp == max)
	    st[sp] = &str_undef;
	else if (numarray) {
	    if (st[max])
		st[sp] = afetch(ary,
		  ((int)str_gnum(st[max])) - arybase, lval);
	    else
		st[sp] = &str_undef;
	}
	else {
	    if (st[max]) {
		tmps = str_get(st[max]);
		len = st[max]->str_cur;
		st[sp] = hfetch(hash,tmps,len, lval);
		if (magic)
		    str_magic(st[sp],stab,magic,tmps,len);
	    }
	    else
		st[sp] = &str_undef;
	}
    }
    arybase = oldarybase;
    return sp;
}