MCPcopy Create free account
hub / github.com/Schwenger/RustTyC / tc_expr

Function tc_expr

examples/parametrized_function.rs:123–178  ·  view source on GitHub ↗

This function traverses the expression tree. It creates keys on the fly. This is not possible for many kinds of type systems, in which case the functions requires a context with a mapping of e.g. Variable -> Key. The context can be built during a first pass over the tree.

(tc: &mut VarlessTypeChecker<Variant>, expr: &Expression)

Source from the content-addressed store, hash-verified

121/// requires a context with a mapping of e.g. Variable -> Key. The context can be built during a first pass over the
122/// tree.
123fn tc_expr(tc: &mut VarlessTypeChecker<Variant>, expr: &Expression) -> Result<TcKey, TcErr<Variant>> {
124 use Expression::*;
125 let key_result = tc.new_term_key(); // will be returned
126 match expr {
127 ConstInt(c) => {
128 let width = (128 - c.leading_zeros()).try_into().unwrap();
129 tc.impose(key_result.concretizes_explicit(Variant::Integer(width)))?;
130 }
131 ConstFixed(i, f) => {
132 let int_width = (64 - i.leading_zeros()).try_into().unwrap();
133 let frac_width = (64 - f.leading_zeros()).try_into().unwrap();
134 tc.impose(key_result.concretizes_explicit(Variant::Fixed(int_width, frac_width)))?;
135 }
136 ConstBool(_) => tc.impose(key_result.concretizes_explicit(Variant::Bool))?,
137 Conditional { cond, cons, alt } => {
138 let key_cond = tc_expr(tc, cond)?;
139 let key_cons = tc_expr(tc, cons)?;
140 let key_alt = tc_expr(tc, alt)?;
141 tc.impose(key_cond.concretizes_explicit(Variant::Bool))?;
142 tc.impose(key_result.is_meet_of(key_cons, key_alt))?;
143 }
144 PolyFn { name: _, param_constraints, args, returns } => {
145 // Note: The following line cannot be replaced by `vec![param_constraints.len(); tc.new_key()]` as this
146 // would copy the keys rather than creating new ones.
147 let params: Vec<(Option<Variant>, TcKey)> =
148 param_constraints.iter().map(|p| (*p, tc.new_term_key())).collect();
149
150 for (arg_ty, arg_expr) in args {
151 let arg_key = tc_expr(tc, arg_expr)?;
152 match arg_ty {
153 ParamType::ParamId(id) => {
154 let (p_constr, p_key) = params[*id];
155 // We need to enforce that the parameter is more concrete than the passed argument and that the
156 // passed argument satisfies the constraints imposed on the parametric type.
157 tc.impose(p_key.concretizes(arg_key))?;
158 if let Some(c) = p_constr {
159 tc.impose(arg_key.concretizes_explicit(c))?;
160 }
161 }
162 ParamType::Abstract(at) => tc.impose(arg_key.concretizes_explicit(*at))?,
163 };
164 }
165 match returns {
166 ParamType::Abstract(at) => tc.impose(key_result.concretizes_explicit(*at))?,
167 ParamType::ParamId(id) => {
168 let (constr, key) = params[*id];
169 if let Some(c) = constr {
170 tc.impose(key_result.concretizes_explicit(c))?;
171 }
172 tc.impose(key_result.equate_with(key))?;
173 }
174 }
175 }
176 }
177 Ok(key_result)
178}
179
180fn main() {

Callers 1

mainFunction · 0.70

Calls 6

new_term_keyMethod · 0.80
imposeMethod · 0.80
concretizes_explicitMethod · 0.80
is_meet_ofMethod · 0.80
concretizesMethod · 0.80
equate_withMethod · 0.80

Tested by

no test coverage detected