Constant Default Parameter Support #98

Merged
sb10q merged 7 commits from default_parameter into master 2021-11-23 07:32:09 +08:00
2 changed files with 22 additions and 23 deletions
Showing only changes of commit 6b059fa288 - Show all commits

View File

@ -1066,7 +1066,7 @@ impl TopLevelComposer {
.into());
}
let mut arg_with_defualt: Vec<(&ast::Located<ast::ArgData<()>>, Option<&ast::Expr>)> = args
let arg_with_default: Vec<(&ast::Located<ast::ArgData<()>>, Option<&ast::Expr>)> = args
.args
.iter()
.rev()
@ -1077,10 +1077,10 @@ impl TopLevelComposer {
.map(|x| -> Option<&ast::Expr> { Some(x) })
.chain(std::iter::repeat(None))
).collect_vec();
arg_with_defualt.reverse();
arg_with_defualt
arg_with_default
.iter()
.rev()
.map(|(x, default)| -> Result<FuncArg, String> {
let annotation = x
.node
@ -1133,12 +1133,11 @@ impl TopLevelComposer {
Ok(FuncArg {
name: x.node.arg,
ty,
default_value: default.map(|default| {
match Self::parse_parameter_default_value(default) {
Ok(res) => res,
Err(err) => panic!("{}", err),
}
}),
default_value: match default {
None => None,
Some(default) =>
Some(Self::parse_parameter_default_value(default)?)
}
})
})
.collect::<Result<Vec<_>, _>>()?
@ -1291,7 +1290,7 @@ impl TopLevelComposer {
let mut result = Vec::new();
let mut arg_with_defualt: Vec<(&ast::Located<ast::ArgData<()>>, Option<&ast::Expr>)> = args
let arg_with_default: Vec<(&ast::Located<ast::ArgData<()>>, Option<&ast::Expr>)> = args
.args
.iter()
.rev()
@ -1302,8 +1301,8 @@ impl TopLevelComposer {
.map(|x| -> Option<&ast::Expr> { Some(x) })
.chain(std::iter::repeat(None))
).collect_vec();
arg_with_defualt.reverse();
for (x, default) in arg_with_defualt {
for (x, default) in arg_with_default.into_iter().rev() {
let name = x.node.arg;
if name != zelf {
let type_ann = {
@ -1348,15 +1347,15 @@ impl TopLevelComposer {
let dummy_func_arg = FuncArg {
name,
ty: unifier.get_fresh_var().0,
default_value: default.map(|default| {
if name == "self".into() {
panic!("`self` parameter cannot take default value at {}", x.location)
default_value: match default {
None => None,
Some(default) => {
if name == "self".into() {
Outdated
Review

Technically CPython lets you name self whatever you want, it's only a convention.
So this test should be "the function is a method and we are looking at its first parameter".

Technically CPython lets you name ``self`` whatever you want, it's only a convention. So this test should be "the function is a method and we are looking at its first parameter".

Would it be acceptable that in nac3, we just enforce and document that the self should always be self and should not be named arbitrarily? As I think this would not cause very big problems and our existing nac3 codebase is already doing this (e.g., here, here, and here)

Would it be acceptable that in nac3, we just enforce and document that the `self` should always be `self` and should not be named arbitrarily? As I think this would not cause very big problems and our existing nac3 codebase is already doing this (e.g., [here](https://git.m-labs.hk/M-Labs/nac3/src/branch/master/nac3core/src/codegen/expr.rs#L293), [here](https://git.m-labs.hk/M-Labs/nac3/src/branch/master/nac3core/src/codegen/expr.rs#L348), and [here](https://github.com/m-labs/artiq/blob/nac3/artiq/language/core.py#L56))
Outdated
Review

It is acceptable but not super clean - is it difficult to use the condition I proposed instead?

https://github.com/m-labs/artiq/blob/nac3/artiq/language/core.py#L56 is unavoidable without a lot of code (AFAICT) because CPython does not tell you if something is a method until it is bound, but inside NAC3 we have more information.

It is acceptable but not super clean - is it difficult to use the condition I proposed instead? https://github.com/m-labs/artiq/blob/nac3/artiq/language/core.py#L56 is unavoidable without a lot of code (AFAICT) because CPython does not tell you if something is a method until it is bound, but inside NAC3 we have more information.
return Err(format!("`self` parameter cannot take default value at {}", x.location));
}
Some(Self::parse_parameter_default_value(default)?)
}
match Self::parse_parameter_default_value(default) {
Ok(res) => res,
Err(err) => panic!("{}", err),
}
})
}
};
// push the dummy type and the type annotation
// into the list for later unification

View File

@ -362,7 +362,7 @@ impl TopLevelComposer {
Constant::Tuple(tuple) => Ok(SymbolValue::Tuple(
tuple.iter().map(|x| handle_constant(x, loc)).collect::<Result<Vec<_>, _>>()?
)),
_ => unimplemented!("this constant is not supported now at {}", loc),
_ => unimplemented!("this constant is not supported at {}", loc),
}
}
match &default.node {
@ -377,10 +377,10 @@ impl TopLevelComposer {
match &args[0].node {
ast::ExprKind::Constant { value: Constant::Int(v), .. } =>
Ok(SymbolValue::I64(v.try_into().unwrap())),
_ => panic!("only allow constant integer here at {}", default.location)
_ => Err(format!("only allow constant integer here at {}", default.location))
}
} else {
panic!("only allow constant integer here at {}", default.location)
Err(format!("only allow constant integer here at {}", default.location))
}
}
ast::ExprKind::Tuple { elts, .. } => Ok(SymbolValue::Tuple(elts