Constant Default Parameter Support #98
@ -1066,7 +1066,7 @@ impl TopLevelComposer {
|
|||||||
.into());
|
.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
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
@ -1077,10 +1077,10 @@ impl TopLevelComposer {
|
|||||||
.map(|x| -> Option<&ast::Expr> { Some(x) })
|
.map(|x| -> Option<&ast::Expr> { Some(x) })
|
||||||
.chain(std::iter::repeat(None))
|
.chain(std::iter::repeat(None))
|
||||||
).collect_vec();
|
).collect_vec();
|
||||||
arg_with_defualt.reverse();
|
|
||||||
|
|
||||||
arg_with_defualt
|
arg_with_default
|
||||||
.iter()
|
.iter()
|
||||||
|
.rev()
|
||||||
.map(|(x, default)| -> Result<FuncArg, String> {
|
.map(|(x, default)| -> Result<FuncArg, String> {
|
||||||
let annotation = x
|
let annotation = x
|
||||||
.node
|
.node
|
||||||
@ -1133,12 +1133,11 @@ impl TopLevelComposer {
|
|||||||
Ok(FuncArg {
|
Ok(FuncArg {
|
||||||
name: x.node.arg,
|
name: x.node.arg,
|
||||||
ty,
|
ty,
|
||||||
default_value: default.map(|default| {
|
default_value: match default {
|
||||||
match Self::parse_parameter_default_value(default) {
|
None => None,
|
||||||
Ok(res) => res,
|
Some(default) =>
|
||||||
Err(err) => panic!("{}", err),
|
Some(Self::parse_parameter_default_value(default)?)
|
||||||
}
|
}
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?
|
.collect::<Result<Vec<_>, _>>()?
|
||||||
@ -1291,7 +1290,7 @@ impl TopLevelComposer {
|
|||||||
|
|
||||||
let mut result = Vec::new();
|
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
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
@ -1302,8 +1301,8 @@ impl TopLevelComposer {
|
|||||||
.map(|x| -> Option<&ast::Expr> { Some(x) })
|
.map(|x| -> Option<&ast::Expr> { Some(x) })
|
||||||
.chain(std::iter::repeat(None))
|
.chain(std::iter::repeat(None))
|
||||||
).collect_vec();
|
).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;
|
let name = x.node.arg;
|
||||||
if name != zelf {
|
if name != zelf {
|
||||||
let type_ann = {
|
let type_ann = {
|
||||||
@ -1348,15 +1347,15 @@ impl TopLevelComposer {
|
|||||||
let dummy_func_arg = FuncArg {
|
let dummy_func_arg = FuncArg {
|
||||||
name,
|
name,
|
||||||
ty: unifier.get_fresh_var().0,
|
ty: unifier.get_fresh_var().0,
|
||||||
default_value: default.map(|default| {
|
default_value: match default {
|
||||||
if name == "self".into() {
|
None => None,
|
||||||
panic!("`self` parameter cannot take default value at {}", x.location)
|
Some(default) => {
|
||||||
|
if name == "self".into() {
|
||||||
|
|||||||
|
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
|
// push the dummy type and the type annotation
|
||||||
// into the list for later unification
|
// into the list for later unification
|
||||||
|
@ -362,7 +362,7 @@ impl TopLevelComposer {
|
|||||||
Constant::Tuple(tuple) => Ok(SymbolValue::Tuple(
|
Constant::Tuple(tuple) => Ok(SymbolValue::Tuple(
|
||||||
tuple.iter().map(|x| handle_constant(x, loc)).collect::<Result<Vec<_>, _>>()?
|
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 {
|
match &default.node {
|
||||||
@ -377,10 +377,10 @@ impl TopLevelComposer {
|
|||||||
match &args[0].node {
|
match &args[0].node {
|
||||||
ast::ExprKind::Constant { value: Constant::Int(v), .. } =>
|
ast::ExprKind::Constant { value: Constant::Int(v), .. } =>
|
||||||
Ok(SymbolValue::I64(v.try_into().unwrap())),
|
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 {
|
} 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
|
ast::ExprKind::Tuple { elts, .. } => Ok(SymbolValue::Tuple(elts
|
||||||
|
Loading…
Reference in New Issue
Block a user
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 beself
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)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.