Get low-level ops compiling

This commit is contained in:
Richard Feldman 2020-06-19 17:52:16 -04:00
parent b75f061f4f
commit dec5c3a062
19 changed files with 447 additions and 296 deletions

View file

@ -801,6 +801,54 @@ pub fn constrain_expr(
]),
)
}
RunLowLevel { op, args, ret_var } => {
// This is a modified version of what we do for function calls.
let ret_type = Variable(*ret_var);
let mut vars = Vec::with_capacity(1 + args.len());
vars.push(*ret_var);
// Canonicalize the function expression and its arguments
let mut arg_types = Vec::with_capacity(args.len());
let mut arg_cons = Vec::with_capacity(args.len());
for (index, (arg_var, arg_expr)) in args.iter().enumerate() {
let arg_type = Variable(*arg_var);
let reason = Reason::LowLevelOpArg {
op: *op,
arg_index: Index::zero_based(index),
};
let expected_arg = Expected::ForReason(reason, arg_type.clone(), region);
let arg_con = constrain_expr(
env,
var_store,
var_usage,
applied_usage_constraint,
Region::zero(),
arg_expr,
expected_arg,
);
vars.push(*arg_var);
arg_types.push(arg_type);
arg_cons.push(arg_con);
}
let expected_uniq_type = var_store.fresh();
vars.push(expected_uniq_type);
exists(
vars,
And(vec![
And(arg_cons),
Eq(ret_type, expected, Category::LowLevelOpResult(*op), region),
]),
)
}
LetRec(defs, loc_ret, var, unlifted_aliases) => {
// NOTE doesn't currently unregister bound symbols
// may be a problem when symbols are not globally unique
@ -1345,9 +1393,7 @@ pub fn constrain_expr(
And(vec![Eq(fn_type, expected, category, region), record_con]),
)
}
RuntimeError(_) | RunLowLevel(_) => {
// RunLowLevel can only be added by the compiler, so it's safe
// to assume its constraints have already been accounted for.
RuntimeError(_) => {
// Runtime Errors have no constraints because they're going to crash.
True
}