Option type support #224

Merged
sb10q merged 8 commits from option into master 2022-03-26 15:09:15 +08:00
5 changed files with 33 additions and 9 deletions
Showing only changes of commit 7ede18429f - Show all commits

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():
ychenfo marked this conversation as resolved Outdated
Outdated
Review

You want to raise an exception if it's None to match the device behavior.

You want to raise an exception if it's ``None`` to match the device behavior.

thanks! now it will raise a ValueError("unwrap on none")

thanks! now it will raise a `ValueError("unwrap on none")`
Outdated
Review

I would suggest a dedicated exception type.

I would suggest a dedicated exception type.

added a new dedicated exception UnwrapNoneError

added a new dedicated exception `UnwrapNoneError`
raise UnwrapNoneError()
return self._nac3_option return self._nac3_option
def __repr__(self) -> str: def __repr__(self) -> str:
ychenfo marked this conversation as resolved Outdated
Outdated
Review

Just none is fine.

Just ``none`` is fine.
@ -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")
}
}, },
Outdated
Review

Okay, so unwrap() can return a NULL pointer which will crash the device later.
I suggest checking for NULL here and raising an exception.

Okay, so ``unwrap()`` can return a NULL pointer which will crash the device later. I suggest checking for NULL here and raising an exception.
)))), )))),
loc: None, loc: None,