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
use crate::score::*;
impl_make!(self, id: ExprRef => &Const {
let hir = self.lazy_hir(id)?;
Ok(match hir.data {
hir::ExprData::IntegerLiteral(ref c) => self.intern_const(c.clone()),
hir::ExprData::FloatLiteral(ref c) => self.intern_const(c.clone()),
hir::ExprData::Unary(op, _, arg_id) => {
let arg = self.const_value(arg_id)?;
match op.value {
UnaryOp::Pos => arg,
UnaryOp::Neg => self.intern_const(arg.clone().negate()),
_ => {
self.emit(
DiagBuilder2::bug(format!("constant unary operator {:?} not yet implemented", op.value))
.span(op.span)
);
return Err(());
}
}
}
hir::ExprData::Range(dir, lb_id, rb_id) => {
let lb = self.const_value(lb_id)?;
let rb = self.const_value(rb_id)?;
match (lb, rb) {
(&Const::Int(ref lb), &Const::Int(ref rb)) => {
self.intern_const(ConstIntRange::new(dir, lb.clone(), rb.clone()))
}
(&Const::Float(ref lb), &Const::Float(ref rb)) => {
self.intern_const(ConstFloatRange::new(dir, lb.clone(), rb.clone()))
}
_ => {
self.emit(
DiagBuilder2::error("left and right bound of range must both be integer or float")
.span(hir.span)
);
return Err(());
}
}
}
hir::ExprData::Name(Def::Enum(EnumRef(decl, index)), _) => self.intern_const(ConstEnum::new(decl, index)),
_ => {
self.emit(
DiagBuilder2::error("expression does not have a constant value")
.span(hir.span)
);
return Err(());
}
})
});