Compare commits
6 Commits
e7add9ea0d
...
649874868a
Author | SHA1 | Date |
---|---|---|
David Mak | 649874868a | |
David Mak | 638d9f8a30 | |
David Mak | b9b725e78e | |
David Mak | 7c41036c5c | |
David Mak | aaaeccfc5a | |
David Mak | 3b8309ae75 |
|
@ -145,7 +145,8 @@ impl<'a> ArtiqCodeGenerator<'a> {
|
|||
let end_store = self.gen_store_target(
|
||||
ctx,
|
||||
&end,
|
||||
store_name.map(|name| format!("{name}.addr")).as_deref())?;
|
||||
store_name.map(|name| format!("{name}.addr")).as_deref())?
|
||||
.unwrap();
|
||||
ctx.builder.build_store(end_store, max);
|
||||
}
|
||||
|
||||
|
@ -261,7 +262,9 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||
node: ExprKind::Name { id: start, ctx: name_ctx.clone() },
|
||||
custom: Some(ctx.primitives.int64),
|
||||
};
|
||||
let start = self.gen_store_target(ctx, &start_expr, Some("start.addr"))?;
|
||||
let start = self
|
||||
.gen_store_target(ctx, &start_expr, Some("start.addr"))?
|
||||
.unwrap();
|
||||
ctx.builder.build_store(start, now);
|
||||
Ok(Some(start_expr)) as Result<_, String>
|
||||
},
|
||||
|
@ -274,7 +277,9 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||
node: ExprKind::Name { id: end, ctx: name_ctx.clone() },
|
||||
custom: Some(ctx.primitives.int64),
|
||||
};
|
||||
let end = self.gen_store_target(ctx, &end_expr, Some("end.addr"))?;
|
||||
let end = self
|
||||
.gen_store_target(ctx, &end_expr, Some("end.addr"))?
|
||||
.unwrap();
|
||||
ctx.builder.build_store(end, now);
|
||||
self.end = Some(end_expr);
|
||||
self.name_counter += 1;
|
||||
|
|
|
@ -265,7 +265,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
|||
}
|
||||
}
|
||||
Constant::Ellipsis => {
|
||||
let msg = self.gen_string(generator, "");
|
||||
let msg = self.gen_string(generator, "NotImplementedError");
|
||||
|
||||
self.raise_exn(
|
||||
generator,
|
||||
|
@ -967,9 +967,15 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
ctx.builder.position_at_end(init_bb);
|
||||
|
||||
let Comprehension { target, iter, ifs, .. } = &generators[0];
|
||||
let iter_val = match generator.gen_expr(ctx, iter)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, iter.custom.unwrap())?,
|
||||
None => return Ok(None),
|
||||
let iter_val = if let Some(v) = generator.gen_expr(ctx, iter)? {
|
||||
v.to_basic_value_enum(ctx, generator, iter.custom.unwrap())?
|
||||
} else {
|
||||
for bb in [test_bb, body_bb, cont_bb] {
|
||||
ctx.builder.position_at_end(bb);
|
||||
ctx.builder.build_unreachable();
|
||||
}
|
||||
|
||||
return Ok(None)
|
||||
};
|
||||
let int32 = ctx.ctx.i32_type();
|
||||
let size_t = generator.get_size_type(ctx.ctx);
|
||||
|
@ -1013,9 +1019,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
list_content = ctx.build_gep_and_load(list, &[zero_size_t, zero_32], Some("listcomp.data.addr"))
|
||||
.into_pointer_value();
|
||||
|
||||
let Some(i) = generator.gen_store_target(ctx, target, Some("i.addr"))? else {
|
||||
unreachable!()
|
||||
};
|
||||
let i = generator.gen_store_target(ctx, target, Some("i.addr"))?.unwrap();
|
||||
ctx.builder.build_store(i, ctx.builder.build_int_sub(start, step, "start_init"));
|
||||
|
||||
ctx.builder.build_conditional_branch(
|
||||
|
@ -1070,12 +1074,24 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
generator.gen_assign(ctx, target, val.into())?;
|
||||
}
|
||||
|
||||
// Emits the content of `cont_bb`
|
||||
let emit_cont_bb = |ctx: &CodeGenContext| {
|
||||
ctx.builder.position_at_end(cont_bb);
|
||||
let len_ptr = unsafe {
|
||||
ctx.builder.build_gep(list, &[zero_size_t, int32.const_int(1, false)], "length")
|
||||
};
|
||||
ctx.builder.build_store(len_ptr, ctx.builder.build_load(index, "index"));
|
||||
};
|
||||
|
||||
for cond in ifs.iter() {
|
||||
let result = match generator.gen_expr(ctx, cond)? {
|
||||
Some(v) => v
|
||||
.to_basic_value_enum(ctx, generator, cond.custom.unwrap())?
|
||||
.into_int_value(),
|
||||
None => return Ok(None),
|
||||
let result = if let Some(v) = generator.gen_expr(ctx, cond)? {
|
||||
v.to_basic_value_enum(ctx, generator, cond.custom.unwrap())?.into_int_value()
|
||||
} else {
|
||||
// Bail if the predicate is an ellipsis - Emit cont_bb contents in case the
|
||||
// no element matches the predicate
|
||||
emit_cont_bb(ctx);
|
||||
|
||||
return Ok(None)
|
||||
};
|
||||
let result = generator.bool_to_i1(ctx, result);
|
||||
let succ = ctx.ctx.append_basic_block(current, "then");
|
||||
|
@ -1084,9 +1100,11 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
ctx.builder.position_at_end(succ);
|
||||
}
|
||||
|
||||
let elem = match generator.gen_expr(ctx, elt)? {
|
||||
Some(v) => v,
|
||||
None => return Ok(None),
|
||||
let Some(elem) = generator.gen_expr(ctx, elt)? else {
|
||||
// Similarly, bail if the generator expression is an ellipsis, but keep cont_bb contents
|
||||
emit_cont_bb(ctx);
|
||||
|
||||
return Ok(None)
|
||||
};
|
||||
let i = ctx.builder.build_load(index, "i").into_int_value();
|
||||
let elem_ptr = unsafe { ctx.builder.build_gep(list_content, &[i], "elem_ptr") };
|
||||
|
@ -1096,11 +1114,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
.build_store(index, ctx.builder.build_int_add(i, size_t.const_int(1, false), "inc"));
|
||||
ctx.builder.build_unconditional_branch(test_bb);
|
||||
|
||||
ctx.builder.position_at_end(cont_bb);
|
||||
let len_ptr = unsafe {
|
||||
ctx.builder.build_gep(list, &[zero_size_t, int32.const_int(1, false)], "length")
|
||||
};
|
||||
ctx.builder.build_store(len_ptr, ctx.builder.build_load(index, "index"));
|
||||
emit_cont_bb(ctx);
|
||||
|
||||
Ok(Some(list.into()))
|
||||
} else {
|
||||
|
@ -1126,13 +1140,15 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
) -> Result<Option<ValueEnum<'ctx>>, String> {
|
||||
let ty1 = ctx.unifier.get_representative(left.custom.unwrap());
|
||||
let ty2 = ctx.unifier.get_representative(right.custom.unwrap());
|
||||
let left_val = match generator.gen_expr(ctx, left)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, left.custom.unwrap())?,
|
||||
None => return Ok(None),
|
||||
let left_val = if let Some(v) = generator.gen_expr(ctx, left)? {
|
||||
v.to_basic_value_enum(ctx, generator, left.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let right_val = match generator.gen_expr(ctx, right)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, right.custom.unwrap())?,
|
||||
None => return Ok(None),
|
||||
let right_val = if let Some(v) = generator.gen_expr(ctx, right)? {
|
||||
v.to_basic_value_enum(ctx, generator, right.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
|
||||
// we can directly compare the types, because we've got their representatives
|
||||
|
@ -1360,11 +1376,10 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
ExprKind::BoolOp { op, values } => {
|
||||
// requires conditional branches for short-circuiting...
|
||||
let left = match generator.gen_expr(ctx, &values[0])? {
|
||||
Some(v) => v
|
||||
.to_basic_value_enum(ctx, generator, values[0].custom.unwrap())?
|
||||
.into_int_value(),
|
||||
None => return Ok(None),
|
||||
let left = if let Some(v) = generator.gen_expr(ctx, &values[0])? {
|
||||
v.to_basic_value_enum(ctx, generator, values[0].custom.unwrap())?.into_int_value()
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let left = generator.bool_to_i1(ctx, left);
|
||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||
|
@ -1377,46 +1392,61 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
ctx.builder.position_at_end(a_bb);
|
||||
let a = ctx.ctx.i8_type().const_int(1, false);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
|
||||
ctx.builder.position_at_end(b_bb);
|
||||
let b = match generator.gen_expr(ctx, &values[1])? {
|
||||
Some(v) =>
|
||||
v.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?
|
||||
.into_int_value(),
|
||||
None => return Ok(None),
|
||||
let b = if let Some(v) = generator.gen_expr(ctx, &values[1])? {
|
||||
let b = v.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?.into_int_value();
|
||||
let b = generator.bool_to_i8(ctx, b);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
|
||||
Some(b)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let b = generator.bool_to_i8(ctx, b);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
(a, b)
|
||||
|
||||
(Some(a), b)
|
||||
}
|
||||
Boolop::And => {
|
||||
ctx.builder.position_at_end(a_bb);
|
||||
let a = match generator.gen_expr(ctx, &values[1])? {
|
||||
Some(v) => v
|
||||
.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?
|
||||
.into_int_value(),
|
||||
None => return Ok(None),
|
||||
let a = if let Some(v) = generator.gen_expr(ctx, &values[1])? {
|
||||
let a = v.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?.into_int_value();
|
||||
let a = generator.bool_to_i8(ctx, a);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
|
||||
Some(a)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let a = generator.bool_to_i8(ctx, a);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
|
||||
ctx.builder.position_at_end(b_bb);
|
||||
let b = ctx.ctx.i8_type().const_zero();
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
(a, b)
|
||||
|
||||
(a, Some(b))
|
||||
}
|
||||
};
|
||||
|
||||
ctx.builder.position_at_end(cont_bb);
|
||||
let phi = ctx.builder.build_phi(ctx.ctx.i8_type(), "");
|
||||
phi.add_incoming(&[(&a, a_bb), (&b, b_bb)]);
|
||||
phi.as_basic_value().into()
|
||||
match (a, b) {
|
||||
(Some(a), Some(b)) => {
|
||||
let phi = ctx.builder.build_phi(ctx.ctx.i8_type(), "");
|
||||
phi.add_incoming(&[(&a, a_bb), (&b, b_bb)]);
|
||||
phi.as_basic_value().into()
|
||||
}
|
||||
(Some(a), None) => a.into(),
|
||||
(None, Some(b)) => b.into(),
|
||||
(None, None) => unreachable!(),
|
||||
}
|
||||
}
|
||||
ExprKind::BinOp { op, left, right } => {
|
||||
return gen_binop_expr(generator, ctx, left, op, right, expr.location, false);
|
||||
}
|
||||
ExprKind::UnaryOp { op, operand } => {
|
||||
let ty = ctx.unifier.get_representative(operand.custom.unwrap());
|
||||
let val = match generator.gen_expr(ctx, operand)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, operand.custom.unwrap())?,
|
||||
None => return Ok(None),
|
||||
let val = if let Some(v) = generator.gen_expr(ctx, operand)? {
|
||||
v.to_basic_value_enum(ctx, generator, operand.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
if ty == ctx.primitives.bool {
|
||||
let val = val.into_int_value();
|
||||
|
@ -1454,7 +1484,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
}
|
||||
ExprKind::Compare { left, ops, comparators } => {
|
||||
izip!(chain(once(left.as_ref()), comparators.iter()), comparators.iter(), ops.iter(),)
|
||||
let cmp_val = izip!(chain(once(left.as_ref()), comparators.iter()), comparators.iter(), ops.iter(),)
|
||||
.fold(Ok(None), |prev: Result<Option<_>, String>, (lhs, rhs, op)| {
|
||||
let ty = ctx.unifier.get_representative(lhs.custom.unwrap());
|
||||
let current =
|
||||
|
@ -1529,9 +1559,12 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
unimplemented!()
|
||||
};
|
||||
Ok(prev?.map(|v| ctx.builder.build_and(v, current, "cmp")).or(Some(current)))
|
||||
})?
|
||||
.unwrap()
|
||||
.into() // as there should be at least 1 element, it should never be none
|
||||
})?;
|
||||
|
||||
match cmp_val {
|
||||
Some(v) => v.into(),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
ExprKind::IfExp { test, body, orelse } => {
|
||||
let test = match generator.gen_expr(ctx, test)? {
|
||||
|
@ -1580,9 +1613,10 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
|
||||
ctx.builder.position_at_end(cont_bb);
|
||||
match result {
|
||||
None => return Ok(None),
|
||||
Some(v) => return Ok(Some(ctx.builder.build_load(v, "if_exp_val_load").into()))
|
||||
if let Some(v) = result {
|
||||
ctx.builder.build_load(v, "if_exp_val_load").into()
|
||||
} else {
|
||||
return Ok(None)
|
||||
}
|
||||
}
|
||||
ExprKind::Call { func, args, keywords } => {
|
||||
|
@ -1732,11 +1766,10 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
ExprKind::Subscript { value, slice, .. } => {
|
||||
if let TypeEnum::TList { ty } = &*ctx.unifier.get_ty(value.custom.unwrap()) {
|
||||
let v = match generator.gen_expr(ctx, value)? {
|
||||
Some(v) => v
|
||||
.to_basic_value_enum(ctx, generator, value.custom.unwrap())?
|
||||
.into_pointer_value(),
|
||||
None => return Ok(None),
|
||||
let v = if let Some(v) = generator.gen_expr(ctx, value)? {
|
||||
v.to_basic_value_enum(ctx, generator, value.custom.unwrap())?.into_pointer_value()
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let ty = ctx.get_llvm_type(generator, *ty);
|
||||
let arr_ptr = ctx.build_gep_and_load(v, &[zero, zero], Some("arr.addr"))
|
||||
|
@ -1785,11 +1818,10 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
let len = ctx
|
||||
.build_gep_and_load(v, &[zero, int32.const_int(1, false)], Some("len"))
|
||||
.into_int_value();
|
||||
let raw_index = match generator.gen_expr(ctx, slice)? {
|
||||
Some(v) => v
|
||||
.to_basic_value_enum(ctx, generator, slice.custom.unwrap())?
|
||||
.into_int_value(),
|
||||
None => return Ok(None),
|
||||
let raw_index = if let Some(v) = generator.gen_expr(ctx, slice)? {
|
||||
v.to_basic_value_enum(ctx, generator, slice.custom.unwrap())?.into_int_value()
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let raw_index = ctx.builder.build_int_s_extend(
|
||||
raw_index,
|
||||
|
@ -1855,10 +1887,13 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
unreachable!("should not be other subscriptable types after type check");
|
||||
}
|
||||
},
|
||||
ExprKind::ListComp { .. } => match gen_comprehension(generator, ctx, expr)? {
|
||||
Some(v) => v.into(),
|
||||
None => return Ok(None),
|
||||
},
|
||||
ExprKind::ListComp { .. } => {
|
||||
if let Some(v) = gen_comprehension(generator, ctx, expr)? {
|
||||
v.into()
|
||||
} else {
|
||||
return Ok(None)
|
||||
}
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -166,22 +166,22 @@ pub fn handle_slice_indices<'a, 'ctx, G: CodeGenerator>(
|
|||
let length = ctx.builder.build_int_truncate_or_bit_cast(length, int32, "leni32");
|
||||
Ok(Some(match (start, end, step) {
|
||||
(s, e, None) => (
|
||||
match s.as_ref() {
|
||||
Some(s) => {
|
||||
if let Some(v) = handle_slice_index_bound(s, ctx, generator, length)? {
|
||||
v
|
||||
} else { return Ok(None) }
|
||||
if let Some(s) = s.as_ref() {
|
||||
match handle_slice_index_bound(s, ctx, generator, length)? {
|
||||
Some(v) => v,
|
||||
None => return Ok(None),
|
||||
}
|
||||
None => int32.const_zero(),
|
||||
} else {
|
||||
int32.const_zero()
|
||||
},
|
||||
{
|
||||
let e = match e.as_ref() {
|
||||
Some(s) => {
|
||||
if let Some(v) = handle_slice_index_bound(s, ctx, generator, length)? {
|
||||
v
|
||||
} else { return Ok(None) }
|
||||
let e = if let Some(s) = e.as_ref() {
|
||||
match handle_slice_index_bound(s, ctx, generator, length)? {
|
||||
Some(v) => v,
|
||||
None => return Ok(None),
|
||||
}
|
||||
None => length,
|
||||
} else {
|
||||
length
|
||||
};
|
||||
ctx.builder.build_int_sub(e, one, "final_end")
|
||||
},
|
||||
|
@ -190,7 +190,9 @@ pub fn handle_slice_indices<'a, 'ctx, G: CodeGenerator>(
|
|||
(s, e, Some(step)) => {
|
||||
let step = if let Some(v) = generator.gen_expr(ctx, step)? {
|
||||
v.to_basic_value_enum(ctx, generator, ctx.primitives.int32)?.into_int_value()
|
||||
} else { return Ok(None) };
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
// assert step != 0, throw exception if not
|
||||
let not_zero = ctx.builder.build_int_compare(
|
||||
IntPredicate::NE,
|
||||
|
@ -273,7 +275,9 @@ pub fn handle_slice_index_bound<'a, 'ctx, G: CodeGenerator>(
|
|||
|
||||
let i = if let Some(v) = generator.gen_expr(ctx, i)? {
|
||||
v.to_basic_value_enum(ctx, generator, i.custom.unwrap())?
|
||||
} else { return Ok(None) };
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
Ok(Some(ctx
|
||||
.builder
|
||||
.build_call(func, &[i.into(), length.into()], "bounded_ind")
|
||||
|
|
|
@ -109,13 +109,17 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
|||
let zero = i32_type.const_zero();
|
||||
let v = if let Some(v) = generator.gen_expr(ctx, value)? {
|
||||
v.to_basic_value_enum(ctx, generator, value.custom.unwrap())?.into_pointer_value()
|
||||
} else { return Ok(None) };
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let len = ctx
|
||||
.build_gep_and_load(v, &[zero, i32_type.const_int(1, false)], Some("len"))
|
||||
.into_int_value();
|
||||
let raw_index = if let Some(v) = generator.gen_expr(ctx, slice)? {
|
||||
v.to_basic_value_enum(ctx, generator, slice.custom.unwrap())?.into_int_value()
|
||||
} else { return Ok(None) };
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let raw_index = ctx.builder.build_int_s_extend(
|
||||
raw_index,
|
||||
generator.get_size_type(ctx.ctx),
|
||||
|
@ -272,13 +276,14 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
|||
// store loop bb information and restore it later
|
||||
let loop_bb = ctx.loop_target.replace((incr_bb, cont_bb));
|
||||
|
||||
let iter_val = match generator.gen_expr(ctx, iter)? {
|
||||
Some(v) => v.to_basic_value_enum(
|
||||
let iter_val = if let Some(v) = generator.gen_expr(ctx, iter)? {
|
||||
v.to_basic_value_enum(
|
||||
ctx,
|
||||
generator,
|
||||
iter.custom.unwrap(),
|
||||
)?,
|
||||
None => return Ok(()),
|
||||
)?
|
||||
} else {
|
||||
return Ok(())
|
||||
};
|
||||
if is_iterable_range_expr {
|
||||
let iter_val = iter_val.into_pointer_value();
|
||||
|
@ -421,7 +426,14 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>(
|
|||
ctx.builder.position_at_end(test_bb);
|
||||
let test = if let Some(v) = generator.gen_expr(ctx, test)? {
|
||||
v.to_basic_value_enum(ctx, generator, test.custom.unwrap())?
|
||||
} else { return Ok(()) };
|
||||
} else {
|
||||
for bb in [body_bb, cont_bb] {
|
||||
ctx.builder.position_at_end(bb);
|
||||
ctx.builder.build_unreachable();
|
||||
}
|
||||
|
||||
return Ok(())
|
||||
};
|
||||
if let BasicValueEnum::IntValue(test) = test {
|
||||
ctx.builder.build_conditional_branch(generator.bool_to_i1(ctx, test), body_bb, orelse_bb);
|
||||
} else {
|
||||
|
@ -483,14 +495,11 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator>(
|
|||
};
|
||||
ctx.builder.build_unconditional_branch(test_bb);
|
||||
ctx.builder.position_at_end(test_bb);
|
||||
let test = match generator.gen_expr(ctx, test)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, test.custom.unwrap())?,
|
||||
None => return Ok(()),
|
||||
};
|
||||
if let BasicValueEnum::IntValue(test) = test {
|
||||
let test = generator
|
||||
.gen_expr(ctx, test)
|
||||
.and_then(|v| v.map(|v| v.to_basic_value_enum(ctx, generator, test.custom.unwrap())).transpose())?;
|
||||
if let Some(BasicValueEnum::IntValue(test)) = test {
|
||||
ctx.builder.build_conditional_branch(generator.bool_to_i1(ctx, test), body_bb, orelse_bb);
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
ctx.builder.position_at_end(body_bb);
|
||||
generator.gen_block(ctx, body.iter())?;
|
||||
|
@ -1043,11 +1052,12 @@ pub fn gen_return<'ctx, 'a, G: CodeGenerator>(
|
|||
) -> Result<(), String> {
|
||||
let func = ctx.builder.get_insert_block().and_then(|bb| bb.get_parent()).unwrap();
|
||||
let value = if let Some(v_expr) = value.as_ref() {
|
||||
match generator.gen_expr(ctx, v_expr).transpose() {
|
||||
Some(v) => Some(
|
||||
if let Some(v) = generator.gen_expr(ctx, v_expr).transpose() {
|
||||
Some(
|
||||
v.and_then(|v| v.to_basic_value_enum(ctx, generator, v_expr.custom.unwrap()))?
|
||||
),
|
||||
None => return Ok(())
|
||||
)
|
||||
} else {
|
||||
return Ok(())
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
@extern
|
||||
def output_str(x: str):
|
||||
...
|
||||
|
||||
def run() -> int32:
|
||||
[i for i in range(10) if ...]
|
||||
return 0
|
|
@ -76,7 +76,7 @@ fn handle_typevar_definition(
|
|||
) -> Result<Type, String> {
|
||||
let ExprKind::Call { func, args, .. } = &var.node else {
|
||||
return Err(format!(
|
||||
"expression {:?} cannot be handled as a TypeVar or ConstGeneric in global scope",
|
||||
"expression {:?} cannot be handled as a generic parameter in global scope",
|
||||
var
|
||||
))
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue