nac3core/artiq: raise dedicated UnwrapNoneError

This commit is contained in:
ychenfo 2022-03-26 01:44:50 +08:00
parent ddc7687ac6
commit 7ede18429f
5 changed files with 33 additions and 9 deletions

View File

@ -16,7 +16,8 @@ class EmbeddingMap:
"CacheError", "CacheError",
"SPIError", "SPIError",
"0:ZeroDivisionError", "0:ZeroDivisionError",
"0:IndexError"]) "0:IndexError",
"0:UnwrapNoneError"])
def preallocate_runtime_exception_names(self, names): def preallocate_runtime_exception_names(self, names):
for i, name in enumerate(names): for i, name in enumerate(names):

View File

@ -11,7 +11,7 @@ from embedding_map import EmbeddingMap
__all__ = [ __all__ = [
"Kernel", "KernelInvariant", "virtual", "Kernel", "KernelInvariant", "virtual",
"Option", "Some", "none", "Option", "Some", "none", "UnwrapNoneError",
"round64", "floor64", "ceil64", "round64", "floor64", "ceil64",
"extern", "kernel", "portable", "nac3", "extern", "kernel", "portable", "nac3",
"rpc", "ms", "us", "ns", "rpc", "ms", "us", "ns",
@ -46,6 +46,8 @@ class Option(Generic[T]):
return not self.is_none() return not self.is_none()
def unwrap(self): def unwrap(self):
if self.is_none():
raise UnwrapNoneError()
return self._nac3_option return self._nac3_option
def __repr__(self) -> str: def __repr__(self) -> str:
@ -272,5 +274,10 @@ class KernelContextManager:
def __exit__(self): def __exit__(self):
pass pass
@nac3
class UnwrapNoneError(Exception):
"""raised when unwrapping a none value"""
artiq_builtin = True
parallel = KernelContextManager() parallel = KernelContextManager()
sequential = KernelContextManager() sequential = KernelContextManager()

View File

@ -496,7 +496,8 @@ impl Nac3 {
"KeyError", "KeyError",
"NotImplementedError", "NotImplementedError",
"OverflowError", "OverflowError",
"IOError" "IOError",
"UnwrapNoneError",
]; ];
add_exceptions(&mut composer, &mut builtins_def, &mut builtins_ty, &exception_names); add_exceptions(&mut composer, &mut builtins_def, &mut builtins_ty, &exception_names);

View File

@ -1309,6 +1309,26 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
unreachable!() unreachable!()
} }
}; };
// directly generate code for option.unwrap
// since it needs location information from ast
if attr == &"unwrap".into()
&& id == ctx.primitives.option.get_obj_id(&ctx.unifier)
{
if let BasicValueEnum::PointerValue(ptr) = val.to_basic_value_enum(ctx, generator)? {
let not_null = ctx.builder.build_is_not_null(ptr, "unwrap_not_null");
ctx.make_assert(
generator,
not_null,
"0:UnwrapNoneError",
"",
[None, None, None],
expr.location,
);
return Ok(Some(ctx.builder.build_load(ptr, "unwrap_some").into()))
} else {
unreachable!("option must be ptr")
}
}
return Ok(generator return Ok(generator
.gen_call( .gen_call(
ctx, ctx,

View File

@ -264,12 +264,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, obj, _, _, generator| { |ctx, obj, _, _, generator| {
let obj_val = obj.unwrap().1.clone().to_basic_value_enum(ctx, generator)?; unreachable!("handled in gen_expr")
if let BasicValueEnum::PointerValue(ptr) = obj_val {
Ok(Some(ctx.builder.build_load(ptr, "unwrap_some")))
} else {
unreachable!("option must be ptr")
}
}, },
)))), )))),
loc: None, loc: None,