@@ -35,232 +35,9 @@ fn void Limit.init(Limit* l, u32 width, bool is_signed) {
3535 }
3636}
3737
38- #if 1
3938public fn Value get_value(const Expr* e) {
4039 return ast.evalExpr(e);
4140}
42- #else
43- public fn Value get_value(const Expr* e) {
44- Value result = { }
45-
46- if (!e.isCtv()) {
47- e.dump(); // TEMP
48- assert(e.isCtv());
49- }
50-
51- switch (e.getKind()) {
52- case IntegerLiteral:
53- const IntegerLiteral* i = (IntegerLiteral*)e;
54- return i.getValue();
55- case FloatLiteral:
56- const FloatLiteral* f = (FloatLiteral*)e;
57- return f.getValue();
58- case BooleanLiteral:
59- const BooleanLiteral* b = (BooleanLiteral*)e;
60- return b.getValue();
61- case CharLiteral:
62- const CharLiteral* c = (CharLiteral*)e;
63- return c.getValue();
64- case StringLiteral:
65- assert(0);
66- break;
67- case Nil:
68- break;
69- case Identifier:
70- const IdentifierExpr* i = (IdentifierExpr*)e;
71- return get_decl_value(i.getDecl());
72- case Type:
73- case Call:
74- case InitList:
75- case FieldDesignatedInit:
76- case ArrayDesignatedInit:
77- // should not happen
78- break;
79- case BinaryOperator:
80- return get_binaryop_value((BinaryOperator*)e);
81- case UnaryOperator:
82- return get_unaryop_value((UnaryOperator*)e);
83- case ConditionalOperator:
84- ConditionalOperator* c = (ConditionalOperator*)e;
85- Value v = get_value(c.getCond());
86- return !v.isZero() ? get_value(c.getLHS()) : get_value(c.getRHS());
87- case Builtin:
88- const BuiltinExpr* bi = (BuiltinExpr*)e;
89- return bi.getValue();
90- case ArraySubscript: // a[high:low], both included
91- // note: can be CTV if BitOffsetExpr
92- ArraySubscriptExpr* a = (ArraySubscriptExpr*)e;
93-
94- result = get_value(a.getBase());
95- // Dont allow negative/float
96- assert(result.isDecimal() && !result.isNegative());
97-
98- Expr* index = a.getIndex();
99- assert(index.isBitOffset());
100- BitOffsetExpr* bo = (BitOffsetExpr*)index;
101- Value high = get_value(bo.getLHS());
102- Value low = get_value(bo.getRHS());
103- Value width = high.minus(&low);
104- width.incr();
105- // calculate result = (base >> low) & bitmask(width))
106- result = result.right_shift(&low);
107- result.mask(width.as_u32());
108- break;
109- case Member:
110- const MemberExpr* m = (MemberExpr*)e;
111- return get_decl_value(m.getFullDecl());
112- case Paren:
113- const ParenExpr* p = (ParenExpr*)e;
114- return get_value(p.getInner());
115- case BitOffset:
116- assert(0); // TODO
117- break;
118- case ExplicitCast:
119- const ExplicitCastExpr* i = (ExplicitCastExpr*)e;
120- result = get_value(i.getInner());
121- return result.castAs(e.getType());
122- case ImplicitCast:
123- const ImplicitCastExpr* i = (ImplicitCastExpr*)e;
124- return get_value(i.getInner());
125- case Range:
126- // should not happen
127- break;
128- }
129-
130- return result;
131- }
132-
133- fn Value get_decl_value(const Decl* d) {
134- assert(d);
135- switch (d.getKind()) {
136- case EnumConstant:
137- const EnumConstantDecl* ecd = (EnumConstantDecl*)d;
138- return ecd.getValue();
139- case Variable:
140- const VarDecl* vd = (VarDecl*)d;
141- const Expr* initval = vd.getInit();
142- assert(initval);
143- return get_value(initval);
144- default:
145- assert(0);
146- break;
147- }
148- return Value.error("not a constant value");
149- }
150-
151- fn Value get_unaryop_value(const UnaryOperator* e) {
152- Value result = { }
153- const Expr* inner = e.getInner();
154- Value res2 = get_value(inner);
155-
156- switch (e.getOpcode()) {
157- case PostInc:
158- case PostDec:
159- case PreInc:
160- case PreDec:
161- // should not happen
162- break;
163- case AddrOf:
164- case Deref:
165- // Allowed?
166- break;
167- case Plus:
168- result = res2;
169- break;
170- case Minus:
171- result = res2.negate();
172- break;
173- case Not:
174- assert(res2.isDecimal()); // TODO give error
175- result = res2.bitnot();
176- break;
177- case LNot:
178- assert(res2.isDecimal()); // TODO give error
179- result = res2.lnot();
180- break;
181- }
182- return result;
183- }
184-
185- fn Value get_binaryop_value(const BinaryOperator* e) {
186- Value result = { }
187- Value left = get_value(e.getLHS());
188- Value right = get_value(e.getRHS());
189-
190- switch (e.getOpcode()) {
191- case Multiply:
192- result = left.multiply(&right);
193- break;
194- case Divide:
195- // Note: should already be checked!
196- result = left.divide(&right);
197- break;
198- case Remainder:
199- // Note: should already be checked!
200- result = left.remainder(&right);
201- break;
202- case Add:
203- result = left.add(&right);
204- break;
205- case Subtract:
206- result = left.minus(&right);
207- break;
208- case ShiftLeft:
209- // Note: neither may be negative, should already be checked
210- // TODO warn about overflow
211- // TODO fix
212- result = left.left_shift(&right);
213- break;
214- case ShiftRight:
215- // Note: neither may be negative, should already be checked
216- // Note: rhs value should be less than bitwidth of lhs type, should already be checked
217- // TODO fix
218- result = left.right_shift(&right);
219- break;
220- case LessThan:
221- return Value.createBool(left.is_less(&right));
222- case GreaterThan:
223- return Value.createBool(left.is_greater(&right));
224- case LessEqual:
225- return Value.createBool(left.is_less_equal(&right));
226- case GreaterEqual:
227- return Value.createBool(left.is_greater_equal(&right));
228- case Equal:
229- return Value.createBool(left.is_equal(&right));
230- case NotEqual:
231- return Value.createBool(!left.is_equal(&right));
232- case And:
233- result = left.and(&right);
234- break;
235- case Xor:
236- result = left.xor(&right);
237- break;
238- case Or:
239- result = left.or(&right);
240- break;
241- case LAnd:
242- result = left.land(&right);
243- break;
244- case LOr:
245- result = left.lor(&right);
246- break;
247- case Assign:
248- case MulAssign:
249- case DivAssign:
250- case RemAssign:
251- case AddAssign:
252- case SubAssign:
253- case ShlAssign:
254- case ShrAssign:
255- case AndAssign:
256- case XorAssign:
257- case OrAssign:
258- assert(0);
259- break;
260- }
261- return result;
262- }
263- #endif
26441
26542public fn bool check(diagnostics.Diags* diags, QualType qt, const Expr* e) {
26643 QualType canon = qt.getCanonicalType();
0 commit comments