forked from M-Labs/nac3
nac3artiq: improve error message for out of range error
This commit is contained in:
parent
d41c923cfd
commit
323d77a455
@ -67,7 +67,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||||||
) -> Result<Option<BasicValueEnum<'ctx>>, String> {
|
) -> Result<Option<BasicValueEnum<'ctx>>, String> {
|
||||||
let result = gen_call(self, ctx, obj, fun, params)?;
|
let result = gen_call(self, ctx, obj, fun, params)?;
|
||||||
if let Some(end) = self.end.clone() {
|
if let Some(end) = self.end.clone() {
|
||||||
let old_end = self.gen_expr(ctx, &end)?.unwrap().to_basic_value_enum(ctx, self);
|
let old_end = self.gen_expr(ctx, &end)?.unwrap().to_basic_value_enum(ctx, self)?;
|
||||||
let now = self.timeline.emit_now_mu(ctx);
|
let now = self.timeline.emit_now_mu(ctx);
|
||||||
let smax = ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| {
|
let smax = ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| {
|
||||||
let i64 = ctx.ctx.i64_type();
|
let i64 = ctx.ctx.i64_type();
|
||||||
@ -87,7 +87,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||||||
ctx.builder.build_store(end_store, max);
|
ctx.builder.build_store(end_store, max);
|
||||||
}
|
}
|
||||||
if let Some(start) = self.start.clone() {
|
if let Some(start) = self.start.clone() {
|
||||||
let start_val = self.gen_expr(ctx, &start)?.unwrap().to_basic_value_enum(ctx, self);
|
let start_val = self.gen_expr(ctx, &start)?.unwrap().to_basic_value_enum(ctx, self)?;
|
||||||
self.timeline.emit_at_mu(ctx, start_val);
|
self.timeline.emit_at_mu(ctx, start_val);
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@ -119,7 +119,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||||||
let old_start = self.start.take();
|
let old_start = self.start.take();
|
||||||
let old_end = self.end.take();
|
let old_end = self.end.take();
|
||||||
let now = if let Some(old_start) = &old_start {
|
let now = if let Some(old_start) = &old_start {
|
||||||
self.gen_expr(ctx, old_start)?.unwrap().to_basic_value_enum(ctx, self)
|
self.gen_expr(ctx, old_start)?.unwrap().to_basic_value_enum(ctx, self)?
|
||||||
} else {
|
} else {
|
||||||
self.timeline.emit_now_mu(ctx)
|
self.timeline.emit_now_mu(ctx)
|
||||||
};
|
};
|
||||||
@ -174,7 +174,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||||||
// set duration
|
// set duration
|
||||||
let end_expr = self.end.take().unwrap();
|
let end_expr = self.end.take().unwrap();
|
||||||
let end_val =
|
let end_val =
|
||||||
self.gen_expr(ctx, &end_expr)?.unwrap().to_basic_value_enum(ctx, self);
|
self.gen_expr(ctx, &end_expr)?.unwrap().to_basic_value_enum(ctx, self)?;
|
||||||
|
|
||||||
// inside a sequential block
|
// inside a sequential block
|
||||||
if old_start.is_none() {
|
if old_start.is_none() {
|
||||||
@ -185,7 +185,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||||||
let outer_end_val = self
|
let outer_end_val = self
|
||||||
.gen_expr(ctx, old_end)?
|
.gen_expr(ctx, old_end)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, self);
|
.to_basic_value_enum(ctx, self)?;
|
||||||
let smax =
|
let smax =
|
||||||
ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| {
|
||||||
let i64 = ctx.ctx.i64_type();
|
let i64 = ctx.ctx.i64_type();
|
||||||
@ -370,7 +370,7 @@ fn rpc_codegen_callback_fn<'ctx, 'a>(
|
|||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| mapping.remove(&arg.name).unwrap().to_basic_value_enum(ctx, generator))
|
.map(|arg| mapping.remove(&arg.name).unwrap().to_basic_value_enum(ctx, generator))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
if let Some(obj) = obj {
|
if let Some(obj) = obj {
|
||||||
if let ValueEnum::Static(obj) = obj.1 {
|
if let ValueEnum::Static(obj) = obj.1 {
|
||||||
real_params.insert(0, obj.get_const_obj(ctx, generator));
|
real_params.insert(0, obj.get_const_obj(ctx, generator));
|
||||||
|
@ -295,7 +295,7 @@ impl Nac3 {
|
|||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
},
|
},
|
||||||
Arc::new(GenCall::new(Box::new(move |ctx, _, _, args, generator| {
|
Arc::new(GenCall::new(Box::new(move |ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator).unwrap();
|
||||||
time_fns.emit_at_mu(ctx, arg);
|
time_fns.emit_at_mu(ctx, arg);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}))),
|
}))),
|
||||||
@ -312,7 +312,7 @@ impl Nac3 {
|
|||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
},
|
},
|
||||||
Arc::new(GenCall::new(Box::new(move |ctx, _, _, args, generator| {
|
Arc::new(GenCall::new(Box::new(move |ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator).unwrap();
|
||||||
time_fns.emit_delay_mu(ctx, arg);
|
time_fns.emit_delay_mu(ctx, arg);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}))),
|
}))),
|
||||||
@ -434,6 +434,7 @@ impl Nac3 {
|
|||||||
embedding_map: &PyAny,
|
embedding_map: &PyAny,
|
||||||
py: Python,
|
py: Python,
|
||||||
) -> PyResult<()> {
|
) -> PyResult<()> {
|
||||||
|
println!("start compilation");
|
||||||
let (mut composer, _, _) = TopLevelComposer::new(
|
let (mut composer, _, _) = TopLevelComposer::new(
|
||||||
self.builtins.clone(),
|
self.builtins.clone(),
|
||||||
ComposerConfig { kernel_ann: Some("Kernel"), kernel_invariant_ann: "KernelInvariant" },
|
ComposerConfig { kernel_ann: Some("Kernel"), kernel_invariant_ann: "KernelInvariant" },
|
||||||
@ -598,7 +599,7 @@ impl Nac3 {
|
|||||||
&mut composer.unifier,
|
&mut composer.unifier,
|
||||||
&self.primitive,
|
&self.primitive,
|
||||||
);
|
);
|
||||||
return Err(CompileError::new_err(msg.unwrap()));
|
return Err(CompileError::new_err(msg.unwrap_or(e)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let top_level = Arc::new(composer.make_top_level_context());
|
let top_level = Arc::new(composer.make_top_level_context());
|
||||||
@ -650,6 +651,7 @@ impl Nac3 {
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
println!("typecheck complete");
|
||||||
|
|
||||||
let task = CodeGenTask {
|
let task = CodeGenTask {
|
||||||
subst: Default::default(),
|
subst: Default::default(),
|
||||||
|
@ -109,27 +109,26 @@ impl StaticValue for PythonValue {
|
|||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> Result<BasicValueEnum<'ctx>, String> {
|
||||||
if let Some(val) = self.resolver.id_to_primitive.read().get(&self.id) {
|
if let Some(val) = self.resolver.id_to_primitive.read().get(&self.id) {
|
||||||
return match val {
|
return Ok(match val {
|
||||||
PrimitiveValue::I32(val) => ctx.ctx.i32_type().const_int(*val as u64, false).into(),
|
PrimitiveValue::I32(val) => ctx.ctx.i32_type().const_int(*val as u64, false).into(),
|
||||||
PrimitiveValue::I64(val) => ctx.ctx.i64_type().const_int(*val as u64, false).into(),
|
PrimitiveValue::I64(val) => ctx.ctx.i64_type().const_int(*val as u64, false).into(),
|
||||||
PrimitiveValue::F64(val) => ctx.ctx.f64_type().const_float(*val).into(),
|
PrimitiveValue::F64(val) => ctx.ctx.f64_type().const_float(*val).into(),
|
||||||
PrimitiveValue::Bool(val) => {
|
PrimitiveValue::Bool(val) => {
|
||||||
ctx.ctx.bool_type().const_int(*val as u64, false).into()
|
ctx.ctx.bool_type().const_int(*val as u64, false).into()
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
if let Some(global) = ctx.module.get_global(&self.id.to_string()) {
|
if let Some(global) = ctx.module.get_global(&self.id.to_string()) {
|
||||||
return global.as_pointer_value().into();
|
return Ok(global.as_pointer_value().into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Python::with_gil(|py| -> PyResult<BasicValueEnum<'ctx>> {
|
Python::with_gil(|py| -> PyResult<BasicValueEnum<'ctx>> {
|
||||||
self.resolver
|
self.resolver
|
||||||
.get_obj_value(py, self.value.as_ref(py), ctx, generator)
|
.get_obj_value(py, self.value.as_ref(py), ctx, generator)
|
||||||
.map(Option::unwrap)
|
.map(Option::unwrap)
|
||||||
})
|
}).map_err(|e| e.to_string())
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_field<'ctx, 'a>(
|
fn get_field<'ctx, 'a>(
|
||||||
@ -594,19 +593,23 @@ impl InnerResolver {
|
|||||||
self.helper.id_fn.call1(py, (self.helper.type_fn.call1(py, (obj,))?,))?.extract(py)?;
|
self.helper.id_fn.call1(py, (self.helper.type_fn.call1(py, (obj,))?,))?.extract(py)?;
|
||||||
let id: u64 = self.helper.id_fn.call1(py, (obj,))?.extract(py)?;
|
let id: u64 = self.helper.id_fn.call1(py, (obj,))?.extract(py)?;
|
||||||
if ty_id == self.primitive_ids.int || ty_id == self.primitive_ids.int32 {
|
if ty_id == self.primitive_ids.int || ty_id == self.primitive_ids.int32 {
|
||||||
let val: i32 = obj.extract()?;
|
let val: i32 = obj.extract().map_err(|_| super::CompileError::new_err(
|
||||||
|
format!("{} is not in the range of int32", obj)))?;
|
||||||
self.id_to_primitive.write().insert(id, PrimitiveValue::I32(val));
|
self.id_to_primitive.write().insert(id, PrimitiveValue::I32(val));
|
||||||
Ok(Some(ctx.ctx.i32_type().const_int(val as u64, false).into()))
|
Ok(Some(ctx.ctx.i32_type().const_int(val as u64, false).into()))
|
||||||
} else if ty_id == self.primitive_ids.int64 {
|
} else if ty_id == self.primitive_ids.int64 {
|
||||||
let val: i64 = obj.extract()?;
|
let val: i64 = obj.extract().map_err(|_| super::CompileError::new_err(
|
||||||
|
format!("{} is not in the range of int64", obj)))?;
|
||||||
self.id_to_primitive.write().insert(id, PrimitiveValue::I64(val));
|
self.id_to_primitive.write().insert(id, PrimitiveValue::I64(val));
|
||||||
Ok(Some(ctx.ctx.i64_type().const_int(val as u64, false).into()))
|
Ok(Some(ctx.ctx.i64_type().const_int(val as u64, false).into()))
|
||||||
} else if ty_id == self.primitive_ids.bool {
|
} else if ty_id == self.primitive_ids.bool {
|
||||||
let val: bool = obj.extract()?;
|
let val: bool = obj.extract().map_err(|_| super::CompileError::new_err(
|
||||||
|
format!("{} is not in the range of bool", obj)))?;
|
||||||
self.id_to_primitive.write().insert(id, PrimitiveValue::Bool(val));
|
self.id_to_primitive.write().insert(id, PrimitiveValue::Bool(val));
|
||||||
Ok(Some(ctx.ctx.bool_type().const_int(val as u64, false).into()))
|
Ok(Some(ctx.ctx.bool_type().const_int(val as u64, false).into()))
|
||||||
} else if ty_id == self.primitive_ids.float {
|
} else if ty_id == self.primitive_ids.float {
|
||||||
let val: f64 = obj.extract()?;
|
let val: f64 = obj.extract().map_err(|_| super::CompileError::new_err(
|
||||||
|
format!("{} is not in the range of float64", obj)))?;
|
||||||
self.id_to_primitive.write().insert(id, PrimitiveValue::F64(val));
|
self.id_to_primitive.write().insert(id, PrimitiveValue::F64(val));
|
||||||
Ok(Some(ctx.ctx.f64_type().const_float(val).into()))
|
Ok(Some(ctx.ctx.f64_type().const_float(val).into()))
|
||||||
} else if ty_id == self.primitive_ids.list {
|
} else if ty_id == self.primitive_ids.list {
|
||||||
@ -649,7 +652,8 @@ impl InnerResolver {
|
|||||||
|
|
||||||
let arr: Result<Option<Vec<_>>, _> = (0..len)
|
let arr: Result<Option<Vec<_>>, _> = (0..len)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
obj.get_item(i).and_then(|elem| self.get_obj_value(py, elem, ctx, generator))
|
obj.get_item(i).and_then(|elem| self.get_obj_value(py, elem, ctx, generator).map_err(
|
||||||
|
|e| super::CompileError::new_err(format!("Error getting element {}: {}", i, e))))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let arr = arr?.unwrap();
|
let arr = arr?.unwrap();
|
||||||
@ -699,7 +703,8 @@ impl InnerResolver {
|
|||||||
let elements: &PyTuple = obj.cast_as()?;
|
let elements: &PyTuple = obj.cast_as()?;
|
||||||
let types: Result<Result<Vec<_>, _>, _> = elements
|
let types: Result<Result<Vec<_>, _>, _> = elements
|
||||||
.iter()
|
.iter()
|
||||||
.map(|elem| {
|
.enumerate()
|
||||||
|
.map(|(i, elem)| {
|
||||||
self.get_obj_type(
|
self.get_obj_type(
|
||||||
py,
|
py,
|
||||||
elem,
|
elem,
|
||||||
@ -707,6 +712,7 @@ impl InnerResolver {
|
|||||||
&ctx.top_level.definitions.read(),
|
&ctx.top_level.definitions.read(),
|
||||||
&ctx.primitives,
|
&ctx.primitives,
|
||||||
)
|
)
|
||||||
|
.map_err(|e| super::CompileError::new_err(format!("Error getting element {}: {}", i, e)))
|
||||||
.map(|ty| ty.map(|ty| ctx.get_llvm_type(generator, ty)))
|
.map(|ty| ty.map(|ty| ctx.get_llvm_type(generator, ty)))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@ -725,7 +731,8 @@ impl InnerResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let val: Result<Option<Vec<_>>, _> =
|
let val: Result<Option<Vec<_>>, _> =
|
||||||
elements.iter().map(|elem| self.get_obj_value(py, elem, ctx, generator)).collect();
|
elements.iter().enumerate().map(|(i, elem)| self.get_obj_value(py, elem, ctx, generator).map_err(|e|
|
||||||
|
super::CompileError::new_err(format!("Error getting element {}: {}", i, e)))).collect();
|
||||||
let val = val?.unwrap();
|
let val = val?.unwrap();
|
||||||
let val = ctx.ctx.const_struct(&val, false);
|
let val = ctx.ctx.const_struct(&val, false);
|
||||||
let global = ctx.module.add_global(ty, Some(AddressSpace::Generic), &id_str);
|
let global = ctx.module.add_global(ty, Some(AddressSpace::Generic), &id_str);
|
||||||
@ -764,7 +771,8 @@ impl InnerResolver {
|
|||||||
let values: Result<Option<Vec<_>>, _> = fields
|
let values: Result<Option<Vec<_>>, _> = fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(name, _, _)| {
|
.map(|(name, _, _)| {
|
||||||
self.get_obj_value(py, obj.getattr(&name.to_string())?, ctx, generator)
|
self.get_obj_value(py, obj.getattr(&name.to_string())?, ctx, generator).map_err(|e|
|
||||||
|
super::CompileError::new_err(format!("Error getting field {}: {}", name, e)))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let values = values?;
|
let values = values?;
|
||||||
|
@ -576,7 +576,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
|||||||
param_vals = real_params
|
param_vals = real_params
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|p| p.to_basic_value_enum(ctx, generator))
|
.map(|p| p.to_basic_value_enum(ctx, generator))
|
||||||
.collect_vec();
|
.collect::<Result<Vec<_>, String>>()?;
|
||||||
instance_to_symbol.get(&key).cloned().ok_or_else(|| "".into())
|
instance_to_symbol.get(&key).cloned().ok_or_else(|| "".into())
|
||||||
}
|
}
|
||||||
TopLevelDef::Class { .. } => {
|
TopLevelDef::Class { .. } => {
|
||||||
@ -661,7 +661,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
|
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
|
||||||
|
|
||||||
let Comprehension { target, iter, ifs, .. } = &generators[0];
|
let Comprehension { target, iter, ifs, .. } = &generators[0];
|
||||||
let iter_val = generator.gen_expr(ctx, iter)?.unwrap().to_basic_value_enum(ctx, generator);
|
let iter_val = generator.gen_expr(ctx, iter)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
let int32 = ctx.ctx.i32_type();
|
let int32 = ctx.ctx.i32_type();
|
||||||
let size_t = generator.get_size_type(ctx.ctx);
|
let size_t = generator.get_size_type(ctx.ctx);
|
||||||
let zero_size_t = size_t.const_zero();
|
let zero_size_t = size_t.const_zero();
|
||||||
@ -766,7 +766,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let result = generator
|
let result = generator
|
||||||
.gen_expr(ctx, cond)?
|
.gen_expr(ctx, cond)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
let succ = ctx.ctx.append_basic_block(current, "then");
|
let succ = ctx.ctx.append_basic_block(current, "then");
|
||||||
ctx.builder.build_conditional_branch(result, succ, test_bb);
|
ctx.builder.build_conditional_branch(result, succ, test_bb);
|
||||||
@ -775,7 +775,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let elem = generator.gen_expr(ctx, elt)?.unwrap();
|
let elem = generator.gen_expr(ctx, elt)?.unwrap();
|
||||||
let i = ctx.builder.build_load(index, "i").into_int_value();
|
let i = ctx.builder.build_load(index, "i").into_int_value();
|
||||||
let elem_ptr = unsafe { ctx.builder.build_gep(list_content, &[i], "elem_ptr") };
|
let elem_ptr = unsafe { ctx.builder.build_gep(list_content, &[i], "elem_ptr") };
|
||||||
let val = elem.to_basic_value_enum(ctx, generator);
|
let val = elem.to_basic_value_enum(ctx, generator)?;
|
||||||
ctx.builder.build_store(elem_ptr, val);
|
ctx.builder.build_store(elem_ptr, val);
|
||||||
ctx.builder
|
ctx.builder
|
||||||
.build_store(index, ctx.builder.build_int_add(i, size_t.const_int(1, false), "inc"));
|
.build_store(index, ctx.builder.build_int_add(i, size_t.const_int(1, false), "inc"));
|
||||||
@ -800,8 +800,8 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
) -> Result<ValueEnum<'ctx>, String> {
|
) -> Result<ValueEnum<'ctx>, String> {
|
||||||
let ty1 = ctx.unifier.get_representative(left.custom.unwrap());
|
let ty1 = ctx.unifier.get_representative(left.custom.unwrap());
|
||||||
let ty2 = ctx.unifier.get_representative(right.custom.unwrap());
|
let ty2 = ctx.unifier.get_representative(right.custom.unwrap());
|
||||||
let left = generator.gen_expr(ctx, left)?.unwrap().to_basic_value_enum(ctx, generator);
|
let left = generator.gen_expr(ctx, left)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
let right = generator.gen_expr(ctx, right)?.unwrap().to_basic_value_enum(ctx, generator);
|
let right = generator.gen_expr(ctx, right)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
|
|
||||||
// we can directly compare the types, because we've got their representatives
|
// we can directly compare the types, because we've got their representatives
|
||||||
// which would be unchanged until further unification, which we would never do
|
// which would be unchanged until further unification, which we would never do
|
||||||
@ -856,7 +856,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
resolver
|
resolver
|
||||||
.get_symbol_value(*id, ctx)
|
.get_symbol_value(*id, ctx)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator),
|
.to_basic_value_enum(ctx, generator)?,
|
||||||
) {
|
) {
|
||||||
ctx.builder.build_load(ptr, "tup_val").into()
|
ctx.builder.build_load(ptr, "tup_val").into()
|
||||||
} else {
|
} else {
|
||||||
@ -872,7 +872,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
.map(|x| {
|
.map(|x| {
|
||||||
generator
|
generator
|
||||||
.gen_expr(ctx, x)
|
.gen_expr(ctx, x)
|
||||||
.map(|v| v.unwrap().to_basic_value_enum(ctx, generator))
|
.map_or_else(|e| Err(e), |v| v.unwrap().to_basic_value_enum(ctx, generator))
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let ty = if elements.is_empty() {
|
let ty = if elements.is_empty() {
|
||||||
@ -905,7 +905,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
.map(|x| {
|
.map(|x| {
|
||||||
generator
|
generator
|
||||||
.gen_expr(ctx, x)
|
.gen_expr(ctx, x)
|
||||||
.map(|v| v.unwrap().to_basic_value_enum(ctx, generator))
|
.map_or_else(|e| Err(e), |v| v.unwrap().to_basic_value_enum(ctx, generator))
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec();
|
let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec();
|
||||||
@ -926,14 +926,14 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
ExprKind::Attribute { value, attr, .. } => {
|
ExprKind::Attribute { value, attr, .. } => {
|
||||||
// note that we would handle class methods directly in calls
|
// note that we would handle class methods directly in calls
|
||||||
match generator.gen_expr(ctx, value)?.unwrap() {
|
match generator.gen_expr(ctx, value)?.unwrap() {
|
||||||
ValueEnum::Static(v) => v.get_field(*attr, ctx).unwrap_or_else(|| {
|
ValueEnum::Static(v) => v.get_field(*attr, ctx).map_or_else(|| {
|
||||||
let v = v.to_basic_value_enum(ctx, generator);
|
let v = v.to_basic_value_enum(ctx, generator)?;
|
||||||
let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
|
let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
|
||||||
ValueEnum::Dynamic(ctx.build_gep_and_load(
|
Ok(ValueEnum::Dynamic(ctx.build_gep_and_load(
|
||||||
v.into_pointer_value(),
|
v.into_pointer_value(),
|
||||||
&[zero, int32.const_int(index as u64, false)],
|
&[zero, int32.const_int(index as u64, false)],
|
||||||
))
|
))) as Result<_, String>
|
||||||
}),
|
}, |v| Ok(v))?,
|
||||||
ValueEnum::Dynamic(v) => {
|
ValueEnum::Dynamic(v) => {
|
||||||
let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
|
let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
|
||||||
ValueEnum::Dynamic(ctx.build_gep_and_load(
|
ValueEnum::Dynamic(ctx.build_gep_and_load(
|
||||||
@ -948,7 +948,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let left = generator
|
let left = generator
|
||||||
.gen_expr(ctx, &values[0])?
|
.gen_expr(ctx, &values[0])?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||||
let a_bb = ctx.ctx.append_basic_block(current, "a");
|
let a_bb = ctx.ctx.append_basic_block(current, "a");
|
||||||
@ -964,7 +964,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let b = generator
|
let b = generator
|
||||||
.gen_expr(ctx, &values[1])?
|
.gen_expr(ctx, &values[1])?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
ctx.builder.build_unconditional_branch(cont_bb);
|
ctx.builder.build_unconditional_branch(cont_bb);
|
||||||
(a, b)
|
(a, b)
|
||||||
@ -974,7 +974,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let a = generator
|
let a = generator
|
||||||
.gen_expr(ctx, &values[1])?
|
.gen_expr(ctx, &values[1])?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
ctx.builder.build_unconditional_branch(cont_bb);
|
ctx.builder.build_unconditional_branch(cont_bb);
|
||||||
ctx.builder.position_at_end(b_bb);
|
ctx.builder.position_at_end(b_bb);
|
||||||
@ -992,7 +992,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
ExprKind::UnaryOp { op, operand } => {
|
ExprKind::UnaryOp { op, operand } => {
|
||||||
let ty = ctx.unifier.get_representative(operand.custom.unwrap());
|
let ty = ctx.unifier.get_representative(operand.custom.unwrap());
|
||||||
let val =
|
let val =
|
||||||
generator.gen_expr(ctx, operand)?.unwrap().to_basic_value_enum(ctx, generator);
|
generator.gen_expr(ctx, operand)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
if ty == ctx.primitives.bool {
|
if ty == ctx.primitives.bool {
|
||||||
let val = val.into_int_value();
|
let val = val.into_int_value();
|
||||||
match op {
|
match op {
|
||||||
@ -1052,11 +1052,11 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
generator
|
generator
|
||||||
.gen_expr(ctx, lhs)?
|
.gen_expr(ctx, lhs)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator),
|
.to_basic_value_enum(ctx, generator)?,
|
||||||
generator
|
generator
|
||||||
.gen_expr(ctx, rhs)?
|
.gen_expr(ctx, rhs)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator),
|
.to_basic_value_enum(ctx, generator)?,
|
||||||
) {
|
) {
|
||||||
(lhs, rhs)
|
(lhs, rhs)
|
||||||
} else {
|
} else {
|
||||||
@ -1080,11 +1080,11 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
generator
|
generator
|
||||||
.gen_expr(ctx, lhs)?
|
.gen_expr(ctx, lhs)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator),
|
.to_basic_value_enum(ctx, generator)?,
|
||||||
generator
|
generator
|
||||||
.gen_expr(ctx, rhs)?
|
.gen_expr(ctx, rhs)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator),
|
.to_basic_value_enum(ctx, generator)?,
|
||||||
) {
|
) {
|
||||||
(lhs, rhs)
|
(lhs, rhs)
|
||||||
} else {
|
} else {
|
||||||
@ -1112,7 +1112,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let test = generator
|
let test = generator
|
||||||
.gen_expr(ctx, test)?
|
.gen_expr(ctx, test)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||||
let then_bb = ctx.ctx.append_basic_block(current, "then");
|
let then_bb = ctx.ctx.append_basic_block(current, "then");
|
||||||
@ -1120,10 +1120,10 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
|
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
|
||||||
ctx.builder.build_conditional_branch(test, then_bb, else_bb);
|
ctx.builder.build_conditional_branch(test, then_bb, else_bb);
|
||||||
ctx.builder.position_at_end(then_bb);
|
ctx.builder.position_at_end(then_bb);
|
||||||
let a = generator.gen_expr(ctx, body)?.unwrap().to_basic_value_enum(ctx, generator);
|
let a = generator.gen_expr(ctx, body)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
ctx.builder.build_unconditional_branch(cont_bb);
|
ctx.builder.build_unconditional_branch(cont_bb);
|
||||||
ctx.builder.position_at_end(else_bb);
|
ctx.builder.position_at_end(else_bb);
|
||||||
let b = generator.gen_expr(ctx, orelse)?.unwrap().to_basic_value_enum(ctx, generator);
|
let b = generator.gen_expr(ctx, orelse)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
ctx.builder.build_unconditional_branch(cont_bb);
|
ctx.builder.build_unconditional_branch(cont_bb);
|
||||||
ctx.builder.position_at_end(cont_bb);
|
ctx.builder.position_at_end(cont_bb);
|
||||||
let phi = ctx.builder.build_phi(a.get_type(), "ifexpr");
|
let phi = ctx.builder.build_phi(a.get_type(), "ifexpr");
|
||||||
@ -1208,7 +1208,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let v = generator
|
let v = generator
|
||||||
.gen_expr(ctx, value)?
|
.gen_expr(ctx, value)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
let ty = ctx.get_llvm_type(generator, *ty);
|
let ty = ctx.get_llvm_type(generator, *ty);
|
||||||
let arr_ptr = ctx.build_gep_and_load(v, &[zero, zero]).into_pointer_value();
|
let arr_ptr = ctx.build_gep_and_load(v, &[zero, zero]).into_pointer_value();
|
||||||
@ -1254,7 +1254,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let raw_index = generator
|
let raw_index = generator
|
||||||
.gen_expr(ctx, slice)?
|
.gen_expr(ctx, slice)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
let raw_index = ctx.builder.build_int_s_extend(
|
let raw_index = ctx.builder.build_int_s_extend(
|
||||||
raw_index,
|
raw_index,
|
||||||
@ -1295,7 +1295,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let v = generator
|
let v = generator
|
||||||
.gen_expr(ctx, value)?
|
.gen_expr(ctx, value)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_struct_value();
|
.into_struct_value();
|
||||||
let index: u32 =
|
let index: u32 =
|
||||||
if let ExprKind::Constant { value: ast::Constant::Int(v), .. } = &slice.node {
|
if let ExprKind::Constant { value: ast::Constant::Int(v), .. } = &slice.node {
|
||||||
|
@ -151,7 +151,7 @@ pub fn handle_slice_indices<'a, 'ctx, G: CodeGenerator>(
|
|||||||
let step = generator
|
let step = generator
|
||||||
.gen_expr(ctx, step)?
|
.gen_expr(ctx, step)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
let len_id = ctx.builder.build_int_sub(length, one, "lenmin1");
|
let len_id = ctx.builder.build_int_sub(length, one, "lenmin1");
|
||||||
let neg = ctx.builder.build_int_compare(IntPredicate::SLT, step, zero, "step_is_neg");
|
let neg = ctx.builder.build_int_compare(IntPredicate::SLT, step, zero, "step_is_neg");
|
||||||
@ -214,7 +214,7 @@ pub fn handle_slice_index_bound<'a, 'ctx, G: CodeGenerator>(
|
|||||||
ctx.module.add_function(SYMBOL, fn_t, None)
|
ctx.module.add_function(SYMBOL, fn_t, None)
|
||||||
});
|
});
|
||||||
|
|
||||||
let i = generator.gen_expr(ctx, i)?.unwrap().to_basic_value_enum(ctx, generator);
|
let i = generator.gen_expr(ctx, i)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
Ok(ctx
|
Ok(ctx
|
||||||
.builder
|
.builder
|
||||||
.build_call(func, &[i.into(), length.into()], "bounded_ind")
|
.build_call(func, &[i.into(), length.into()], "bounded_ind")
|
||||||
|
@ -276,6 +276,7 @@ fn get_llvm_type<'ctx>(
|
|||||||
&*definition.read()
|
&*definition.read()
|
||||||
{
|
{
|
||||||
let struct_type = ctx.opaque_struct_type(&name.to_string());
|
let struct_type = ctx.opaque_struct_type(&name.to_string());
|
||||||
|
type_cache.insert(unifier.get_representative(ty), struct_type.ptr_type(AddressSpace::Generic).into());
|
||||||
let fields = fields_list
|
let fields = fields_list
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
@ -294,7 +295,7 @@ fn get_llvm_type<'ctx>(
|
|||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
ty
|
return ty;
|
||||||
}
|
}
|
||||||
TTuple { ty } => {
|
TTuple { ty } => {
|
||||||
// a struct with fields in the order present in the tuple
|
// a struct with fields in the order present in the tuple
|
||||||
|
@ -54,7 +54,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
|||||||
}
|
}
|
||||||
ExprKind::Attribute { value, attr, .. } => {
|
ExprKind::Attribute { value, attr, .. } => {
|
||||||
let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
|
let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
|
||||||
let val = generator.gen_expr(ctx, value)?.unwrap().to_basic_value_enum(ctx, generator);
|
let val = generator.gen_expr(ctx, value)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
let ptr = if let BasicValueEnum::PointerValue(v) = val {
|
let ptr = if let BasicValueEnum::PointerValue(v) = val {
|
||||||
v
|
v
|
||||||
} else {
|
} else {
|
||||||
@ -76,12 +76,12 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let v = generator
|
let v = generator
|
||||||
.gen_expr(ctx, value)?
|
.gen_expr(ctx, value)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
let index = generator
|
let index = generator
|
||||||
.gen_expr(ctx, slice)?
|
.gen_expr(ctx, slice)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
unsafe {
|
unsafe {
|
||||||
let arr_ptr = ctx
|
let arr_ptr = ctx
|
||||||
@ -102,7 +102,7 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
|
|||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
match &target.node {
|
match &target.node {
|
||||||
ExprKind::Tuple { elts, .. } => {
|
ExprKind::Tuple { elts, .. } => {
|
||||||
if let BasicValueEnum::StructValue(v) = value.to_basic_value_enum(ctx, generator) {
|
if let BasicValueEnum::StructValue(v) = value.to_basic_value_enum(ctx, generator)? {
|
||||||
for (i, elt) in elts.iter().enumerate() {
|
for (i, elt) in elts.iter().enumerate() {
|
||||||
let v = ctx
|
let v = ctx
|
||||||
.builder
|
.builder
|
||||||
@ -121,11 +121,11 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let ls = generator
|
let ls = generator
|
||||||
.gen_expr(ctx, ls)?
|
.gen_expr(ctx, ls)?
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_basic_value_enum(ctx, generator)
|
.to_basic_value_enum(ctx, generator)?
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
let (start, end, step) =
|
let (start, end, step) =
|
||||||
handle_slice_indices(lower, upper, step, ctx, generator, ls)?;
|
handle_slice_indices(lower, upper, step, ctx, generator, ls)?;
|
||||||
let value = value.to_basic_value_enum(ctx, generator).into_pointer_value();
|
let value = value.to_basic_value_enum(ctx, generator)?.into_pointer_value();
|
||||||
let ty =
|
let ty =
|
||||||
if let TypeEnum::TList { ty } = &*ctx.unifier.get_ty(target.custom.unwrap()) {
|
if let TypeEnum::TList { ty } = &*ctx.unifier.get_ty(target.custom.unwrap()) {
|
||||||
ctx.get_llvm_type(generator, *ty)
|
ctx.get_llvm_type(generator, *ty)
|
||||||
@ -155,7 +155,7 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
|
|||||||
*static_value = Some(s.clone());
|
*static_value = Some(s.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let val = value.to_basic_value_enum(ctx, generator);
|
let val = value.to_basic_value_enum(ctx, generator)?;
|
||||||
ctx.builder.build_store(ptr, val);
|
ctx.builder.build_store(ptr, val);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -185,7 +185,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
|||||||
// store loop bb information and restore it later
|
// store loop bb information and restore it later
|
||||||
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
|
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
|
||||||
|
|
||||||
let iter_val = generator.gen_expr(ctx, iter)?.unwrap().to_basic_value_enum(ctx, generator);
|
let iter_val = generator.gen_expr(ctx, iter)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
if ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range) {
|
if ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range) {
|
||||||
// setup
|
// setup
|
||||||
let iter_val = iter_val.into_pointer_value();
|
let iter_val = iter_val.into_pointer_value();
|
||||||
@ -296,7 +296,7 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
|
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
|
||||||
ctx.builder.build_unconditional_branch(test_bb);
|
ctx.builder.build_unconditional_branch(test_bb);
|
||||||
ctx.builder.position_at_end(test_bb);
|
ctx.builder.position_at_end(test_bb);
|
||||||
let test = generator.gen_expr(ctx, test)?.unwrap().to_basic_value_enum(ctx, generator);
|
let test = generator.gen_expr(ctx, test)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
if let BasicValueEnum::IntValue(test) = test {
|
if let BasicValueEnum::IntValue(test) = test {
|
||||||
ctx.builder.build_conditional_branch(test, body_bb, orelse_bb);
|
ctx.builder.build_conditional_branch(test, body_bb, orelse_bb);
|
||||||
} else {
|
} else {
|
||||||
@ -357,7 +357,7 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator>(
|
|||||||
};
|
};
|
||||||
ctx.builder.build_unconditional_branch(test_bb);
|
ctx.builder.build_unconditional_branch(test_bb);
|
||||||
ctx.builder.position_at_end(test_bb);
|
ctx.builder.position_at_end(test_bb);
|
||||||
let test = generator.gen_expr(ctx, test)?.unwrap().to_basic_value_enum(ctx, generator);
|
let test = generator.gen_expr(ctx, test)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
if let BasicValueEnum::IntValue(test) = test {
|
if let BasicValueEnum::IntValue(test) = test {
|
||||||
ctx.builder.build_conditional_branch(test, body_bb, orelse_bb);
|
ctx.builder.build_conditional_branch(test, body_bb, orelse_bb);
|
||||||
} else {
|
} else {
|
||||||
@ -454,7 +454,7 @@ pub fn exn_constructor<'ctx, 'a>(
|
|||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
) -> Result<Option<BasicValueEnum<'ctx>>, String> {
|
) -> Result<Option<BasicValueEnum<'ctx>>, String> {
|
||||||
let (zelf_ty, zelf) = obj.unwrap();
|
let (zelf_ty, zelf) = obj.unwrap();
|
||||||
let zelf = zelf.to_basic_value_enum(ctx, generator).into_pointer_value();
|
let zelf = zelf.to_basic_value_enum(ctx, generator)?.into_pointer_value();
|
||||||
let int32 = ctx.ctx.i32_type();
|
let int32 = ctx.ctx.i32_type();
|
||||||
let zero = int32.const_zero();
|
let zero = int32.const_zero();
|
||||||
let zelf_id = {
|
let zelf_id = {
|
||||||
@ -477,14 +477,14 @@ pub fn exn_constructor<'ctx, 'a>(
|
|||||||
let ptr =
|
let ptr =
|
||||||
ctx.builder.build_in_bounds_gep(zelf, &[zero, int32.const_int(5, false)], "exn.msg");
|
ctx.builder.build_in_bounds_gep(zelf, &[zero, int32.const_int(5, false)], "exn.msg");
|
||||||
let msg = if !args.is_empty() {
|
let msg = if !args.is_empty() {
|
||||||
args.remove(0).1.to_basic_value_enum(ctx, generator)
|
args.remove(0).1.to_basic_value_enum(ctx, generator)?
|
||||||
} else {
|
} else {
|
||||||
empty_string
|
empty_string
|
||||||
};
|
};
|
||||||
ctx.builder.build_store(ptr, msg);
|
ctx.builder.build_store(ptr, msg);
|
||||||
for i in [6, 7, 8].iter() {
|
for i in [6, 7, 8].iter() {
|
||||||
let value = if !args.is_empty() {
|
let value = if !args.is_empty() {
|
||||||
args.remove(0).1.to_basic_value_enum(ctx, generator)
|
args.remove(0).1.to_basic_value_enum(ctx, generator)?
|
||||||
} else {
|
} else {
|
||||||
ctx.ctx.i64_type().const_zero().into()
|
ctx.ctx.i64_type().const_zero().into()
|
||||||
};
|
};
|
||||||
@ -900,7 +900,7 @@ pub fn gen_return<'ctx, 'a, G: CodeGenerator>(
|
|||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let value = value
|
let value = value
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|v| generator.gen_expr(ctx, v).map(|v| v.unwrap().to_basic_value_enum(ctx, generator)))
|
.map(|v| generator.gen_expr(ctx, v).and_then(|v| v.unwrap().to_basic_value_enum(ctx, generator)))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
if let Some(return_target) = ctx.return_target {
|
if let Some(return_target) = ctx.return_target {
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
@ -957,7 +957,7 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>(
|
|||||||
StmtKind::Raise { exc, .. } => {
|
StmtKind::Raise { exc, .. } => {
|
||||||
if let Some(exc) = exc {
|
if let Some(exc) = exc {
|
||||||
let exc =
|
let exc =
|
||||||
generator.gen_expr(ctx, exc)?.unwrap().to_basic_value_enum(ctx, generator);
|
generator.gen_expr(ctx, exc)?.unwrap().to_basic_value_enum(ctx, generator)?;
|
||||||
gen_raise(generator, ctx, Some(&exc), stmt.location);
|
gen_raise(generator, ctx, Some(&exc), stmt.location);
|
||||||
} else {
|
} else {
|
||||||
gen_raise(generator, ctx, None, stmt.location);
|
gen_raise(generator, ctx, None, stmt.location);
|
||||||
|
@ -63,7 +63,7 @@ pub trait StaticValue {
|
|||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
) -> BasicValueEnum<'ctx>;
|
) -> Result<BasicValueEnum<'ctx>, String>;
|
||||||
|
|
||||||
fn get_field<'ctx, 'a>(
|
fn get_field<'ctx, 'a>(
|
||||||
&self,
|
&self,
|
||||||
@ -107,10 +107,10 @@ impl<'ctx> ValueEnum<'ctx> {
|
|||||||
self,
|
self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> Result<BasicValueEnum<'ctx>, String> {
|
||||||
match self {
|
match self {
|
||||||
ValueEnum::Static(v) => v.to_basic_value_enum(ctx, generator),
|
ValueEnum::Static(v) => v.to_basic_value_enum(ctx, generator),
|
||||||
ValueEnum::Dynamic(v) => v,
|
ValueEnum::Dynamic(v) => Ok(v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
let float = ctx.primitives.float;
|
let float = ctx.primitives.float;
|
||||||
let boolean = ctx.primitives.bool;
|
let boolean = ctx.primitives.bool;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
Ok(if ctx.unifier.unioned(arg_ty, boolean) {
|
Ok(if ctx.unifier.unioned(arg_ty, boolean) {
|
||||||
Some(
|
Some(
|
||||||
ctx.builder
|
ctx.builder
|
||||||
@ -253,7 +253,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
let float = ctx.primitives.float;
|
let float = ctx.primitives.float;
|
||||||
let boolean = ctx.primitives.bool;
|
let boolean = ctx.primitives.bool;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
Ok(
|
Ok(
|
||||||
if ctx.unifier.unioned(arg_ty, boolean)
|
if ctx.unifier.unioned(arg_ty, boolean)
|
||||||
|| ctx.unifier.unioned(arg_ty, int32)
|
|| ctx.unifier.unioned(arg_ty, int32)
|
||||||
@ -306,7 +306,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
let boolean = ctx.primitives.bool;
|
let boolean = ctx.primitives.bool;
|
||||||
let float = ctx.primitives.float;
|
let float = ctx.primitives.float;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
Ok(
|
Ok(
|
||||||
if ctx.unifier.unioned(arg_ty, boolean)
|
if ctx.unifier.unioned(arg_ty, boolean)
|
||||||
|| ctx.unifier.unioned(arg_ty, int32)
|
|| ctx.unifier.unioned(arg_ty, int32)
|
||||||
@ -342,7 +342,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, _, args, generator| {
|
|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
let round_intrinsic =
|
let round_intrinsic =
|
||||||
ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
@ -382,7 +382,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, _, args, generator| {
|
|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
let round_intrinsic =
|
let round_intrinsic =
|
||||||
ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
@ -442,17 +442,17 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
let zero = int32.const_zero();
|
let zero = int32.const_zero();
|
||||||
for (i, arg) in args.iter().enumerate() {
|
for (i, arg) in args.iter().enumerate() {
|
||||||
if arg.0 == Some("start".into()) {
|
if arg.0 == Some("start".into()) {
|
||||||
start = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
start = Some(arg.1.clone().to_basic_value_enum(ctx, generator)?);
|
||||||
} else if arg.0 == Some("stop".into()) {
|
} else if arg.0 == Some("stop".into()) {
|
||||||
stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator)?);
|
||||||
} else if arg.0 == Some("step".into()) {
|
} else if arg.0 == Some("step".into()) {
|
||||||
step = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
step = Some(arg.1.clone().to_basic_value_enum(ctx, generator)?);
|
||||||
} else if i == 0 {
|
} else if i == 0 {
|
||||||
start = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
start = Some(arg.1.clone().to_basic_value_enum(ctx, generator)?);
|
||||||
} else if i == 1 {
|
} else if i == 1 {
|
||||||
stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator)?);
|
||||||
} else if i == 2 {
|
} else if i == 2 {
|
||||||
step = Some(arg.1.clone().to_basic_value_enum(ctx, generator));
|
step = Some(arg.1.clone().to_basic_value_enum(ctx, generator)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: error when step == 0
|
// TODO: error when step == 0
|
||||||
@ -500,7 +500,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, _, args, generator| {
|
|ctx, _, _, args, generator| {
|
||||||
Ok(Some(args[0].1.clone().to_basic_value_enum(ctx, generator)))
|
Ok(Some(args[0].1.clone().to_basic_value_enum(ctx, generator)?))
|
||||||
},
|
},
|
||||||
)))),
|
)))),
|
||||||
loc: None,
|
loc: None,
|
||||||
@ -524,7 +524,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
let float = ctx.primitives.float;
|
let float = ctx.primitives.float;
|
||||||
let boolean = ctx.primitives.bool;
|
let boolean = ctx.primitives.bool;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
Ok(if ctx.unifier.unioned(arg_ty, boolean) {
|
Ok(if ctx.unifier.unioned(arg_ty, boolean) {
|
||||||
Some(arg)
|
Some(arg)
|
||||||
} else if ctx.unifier.unioned(arg_ty, int32) {
|
} else if ctx.unifier.unioned(arg_ty, int32) {
|
||||||
@ -582,7 +582,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, _, args, generator| {
|
|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
let floor_intrinsic =
|
let floor_intrinsic =
|
||||||
ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
@ -622,7 +622,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, _, args, generator| {
|
|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
let floor_intrinsic =
|
let floor_intrinsic =
|
||||||
ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
@ -662,7 +662,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, _, args, generator| {
|
|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
let ceil_intrinsic =
|
let ceil_intrinsic =
|
||||||
ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
@ -702,7 +702,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
resolver: None,
|
resolver: None,
|
||||||
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
codegen_callback: Some(Arc::new(GenCall::new(Box::new(
|
||||||
|ctx, _, _, args, generator| {
|
|ctx, _, _, args, generator| {
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
let ceil_intrinsic =
|
let ceil_intrinsic =
|
||||||
ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| {
|
ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| {
|
||||||
let float = ctx.ctx.f64_type();
|
let float = ctx.ctx.f64_type();
|
||||||
@ -754,7 +754,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
|ctx, _, fun, args, generator| {
|
|ctx, _, fun, args, generator| {
|
||||||
let range_ty = ctx.primitives.range;
|
let range_ty = ctx.primitives.range;
|
||||||
let arg_ty = fun.0.args[0].ty;
|
let arg_ty = fun.0.args[0].ty;
|
||||||
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator);
|
let arg = args[0].1.clone().to_basic_value_enum(ctx, generator)?;
|
||||||
Ok(if ctx.unifier.unioned(arg_ty, range_ty) {
|
Ok(if ctx.unifier.unioned(arg_ty, range_ty) {
|
||||||
let arg = arg.into_pointer_value();
|
let arg = arg.into_pointer_value();
|
||||||
let (start, end, step) = destructure_range(ctx, arg);
|
let (start, end, step) = destructure_range(ctx, arg);
|
||||||
|
Loading…
Reference in New Issue
Block a user