BSD 4_3_Reno development
[unix-history] / usr / src / old / efl / field.c
CommitLineData
64836102
C
1#include "defs"
2
3
4
5ptr mkfield(q)
6register ptr q;
7{
8register ptr p;
9
10if(!instruct)
11 goto err;
12else if(q->upperb == 0)
13 dclerr("must have upper bound in field spcification", "");
14else
15 {
16 p = ALLOC(fieldspec);
17 p->tag = TFIELD;
18 if(q->lowerb)
19 {
20 p->flbound = q->lowerb;
21 p->frange = mknode(TAROP,OPPLUS,mknode(TAROP,OPMINUS,
22 q->upperb, cpexpr(q->lowerb)),
23 mkconst(TYINT,"1") );
24 }
25 else {
26 p->flbound = mkconst(TYINT,"1");
27 p->frange = q->upperb;
28 }
29 p->frange = simple(RVAL,p->frange);
30 if(p->frange->tag != TCONST)
31 {
32 dclerr("field range must be constant", "");
33 cfree(p);
34 goto err;
35 }
36 cfree(q);
37 return(p);
38 }
39
40err:
41 cfree(q);
42 return( errnode() );
43}
44
45
46
47
48
49ptr extrfield(p)
50register ptr p;
51{
52register ptr t;
53
54t = p->vtypep;
55p->vtype = TYINT;
56p->vtypep = 0;
57
58if(t->frshift)
59 p = mknode(TAROP,OPSLASH, p, cpexpr(t->frshift));
60if(t->fanymore)
61 p = mkcall(builtin(TYINT, "mod"), arg2(p, cpexpr(t->frange)) );
62p = mknode(TAROP,OPPLUS, p, cpexpr(t->flbound));
63return(p);
64}
65
66
67
68
69ptr setfield(e)
70ptr e;
71{
72ptr lp, rp;
73register ptr f, p;
74int subt;
75
76lp = cpexpr(e->leftp);
77rp = e->rightp;
78subt = e->subtype;
79f = lp->vtypep;
80lp->vtype = TYINT;
81lp->vtypep = 0;
82
83if(subt==OPPLUS || subt==OPMINUS)
84 {
85 if(f->frshift)
86 rp = mknode(TAROP,OPSTAR,rp,cpexpr(f->frshift));
87 }
88else {
89 if(subt != OPASGN)
90 {
91 rp = mknode(TAROP,subt, extrfield(cpexpr(e->leftp)), rp);
92 subt = OPASGN;
93 }
94 rp = coerce(TYINT,rp);
95 if(f->flbound)
96 rp = simple(RVAL, mknode(TAROP,OPMINUS,rp,cpexpr(f->flbound)) );
97
98 if(f->frshift==0)
99 {
100 if(f->fanymore)
101 {
102 p = mknode(TAROP,OPSLASH,cpexpr(lp),cpexpr(f->frange));
103 p->needpar = YES;
104 p = mknode(TAROP,OPSTAR,cpexpr(f->frange),p);
105 rp = mknode(TAROP,OPPLUS,p,rp);
106 }
107 }
108 else if(f->fanymore==0)
109 {
110 rp = mknode(TAROP,OPSTAR,cpexpr(f->frshift),rp);
111 p = mkcall(builtin(TYINT,"mod"),
112 arg2(cpexpr(lp),cpexpr(f->frshift)) );
113 rp = mknode(TAROP,OPPLUS, p,rp);
114 }
115 else {
116 p = mknode(TAROP,OPSLASH,cpexpr(lp),cpexpr(f->frshift));
117 p = mkcall(builtin(TYINT,"mod"),
118 arg2(p, cpexpr(f->frange)) );
119 if( rp->tag!=TCONST || !equals(rp->leftp, "0") )
120 p = mknode(TAROP,OPMINUS, p, rp);
121 rp = mknode(TAROP,OPSTAR, cpexpr(f->frshift), p);
122 rp = mknode(TAROP,OPMINUS, cpexpr(lp), rp);
123 }
124 }
125frexpr( simple(LVAL, mknode(TASGNOP,subt,lp,rp) ));
126return(extrfield(e->leftp));
127}