core: support raise exception short form #455

Merged
sb10q merged 1 commits from issue-194 into master 2024-07-12 18:58:35 +08:00
2 changed files with 27 additions and 2 deletions

View File

@ -2457,7 +2457,29 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
None => {
let resolver = ctx.resolver.clone();
resolver.get_symbol_value(*id, ctx).unwrap()
if let Some(res) = resolver.get_symbol_value(*id, ctx) {
res
} else {
// Allow "raise Exception" short form
Outdated
Review

No need to quote issue number.

Why is the code so complicated?

No need to quote issue number. Why is the code so complicated?

No need to quote issue number.

Ok.

Why is the code so complicated?

The shorthand exception notation is treated as a variable in the AST. Here I am performing a lookup using the variable definition to get the signature of the exception. Most of the code is to ensure the exception is matched to correct type.

> No need to quote issue number. Ok. > Why is the code so complicated? The shorthand exception notation is treated as a variable in the AST. Here I am performing a lookup using the variable definition to get the signature of the exception. Most of the code is to ensure the exception is matched to correct type.
Outdated
Review

Sounds fishy to me. The other one would be a variable inside a call, so there shouldn't be that much difference.

Sounds fishy to me. The other one would be a variable inside a call, so there shouldn't be that much difference.

Sounds fishy to me. The other one would be a variable inside a call, so there shouldn't be that much difference.

The other already has the function signature (the constructor of the exception) linked to it, so there is no need for lookup.

> Sounds fishy to me. The other one would be a variable inside a call, so there shouldn't be that much difference. The other already has the function signature (the constructor of the exception) linked to it, so there is no need for lookup.
let def_id = resolver.get_identifier_def(*id).map_err(|e| {
format!("{} (at {})", e.iter().next().unwrap(), expr.location)
})?;
let def = ctx.top_level.definitions.read();
if let TopLevelDef::Class { constructor, .. } = *def[def_id.0].read() {
let TypeEnum::TFunc(signature) =
ctx.unifier.get_ty(constructor.unwrap()).as_ref().clone()
else {
return Err(format!(
"Failed to resolve symbol {} (at {})",
id, expr.location
));
};
return Ok(generator
.gen_call(ctx, None, (&signature, def_id), Vec::default())?
.map(Into::into));
}
return Err(format!("Failed to resolve symbol {} (at {})", id, expr.location));
}
}
},
ExprKind::List { elts, .. } => {

View File

@ -398,7 +398,10 @@ impl<'a> Fold<()> for Inferencer<'a> {
}
if let Some(exc) = exc {
self.virtual_checks.push((
exc.custom.unwrap(),
match &*self.unifier.get_ty(exc.custom.unwrap()) {
TypeEnum::TFunc(sign) => sign.ret,
_ => exc.custom.unwrap(),
},
self.primitives.exception,
exc.location,
));