Constant Default Parameter Support #98
|
@ -1066,9 +1066,22 @@ impl TopLevelComposer {
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
args.args
|
let mut arg_with_defualt: Vec<(&ast::Located<ast::ArgData<()>>, Option<&ast::Expr>)> = args
|
||||||
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| -> Result<FuncArg, String> {
|
.rev()
|
||||||
|
.zip(args
|
||||||
|
.defaults
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.map(|x| -> Option<&ast::Expr> { Some(x) })
|
||||||
|
.chain(std::iter::repeat(None))
|
||||||
|
).collect_vec();
|
||||||
|
arg_with_defualt.reverse();
|
||||||
|
|
||||||
|
arg_with_defualt
|
||||||
|
.iter()
|
||||||
|
.map(|(x, default)| -> Result<FuncArg, String> {
|
||||||
let annotation = x
|
let annotation = x
|
||||||
.node
|
.node
|
||||||
.annotation
|
.annotation
|
||||||
|
@ -1120,7 +1133,12 @@ impl TopLevelComposer {
|
||||||
Ok(FuncArg {
|
Ok(FuncArg {
|
||||||
name: x.node.arg,
|
name: x.node.arg,
|
||||||
ty,
|
ty,
|
||||||
default_value: Default::default(),
|
default_value: default.map(|default| {
|
||||||
|
match Self::parse_parameter_default_value(default) {
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(err) => panic!("{}", err),
|
||||||
|
}
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?
|
.collect::<Result<Vec<_>, _>>()?
|
||||||
|
@ -1272,7 +1290,20 @@ impl TopLevelComposer {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for x in &args.args {
|
|
||||||
|
let mut arg_with_defualt: Vec<(&ast::Located<ast::ArgData<()>>, Option<&ast::Expr>)> = args
|
||||||
|
.args
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.zip(args
|
||||||
|
.defaults
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.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 {
|
||||||
let name = x.node.arg;
|
let name = x.node.arg;
|
||||||
if name != zelf {
|
if name != zelf {
|
||||||
let type_ann = {
|
let type_ann = {
|
||||||
|
@ -1317,8 +1348,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,
|
||||||
// TODO: default value?
|
default_value: default.map(|default| {
|
||||||
default_value: None,
|
if name == "self".into() {
|
||||||
|
panic!("`self` parameter cannot take default value at {}", x.location)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
use nac3parser::ast::{Constant, Location};
|
||||||
|
use crate::symbol_resolver::SymbolValue;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl TopLevelDef {
|
impl TopLevelDef {
|
||||||
|
@ -341,4 +346,49 @@ impl TopLevelComposer {
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_parameter_default_value(default: &ast::Expr) -> Result<SymbolValue, String> {
|
||||||
|
fn handle_constant(val: &Constant, loc: &Location) -> Result<SymbolValue, String> {
|
||||||
|
match val {
|
||||||
|
Constant::Int(v) => {
|
||||||
|
if let Ok(v) = v.try_into() {
|
||||||
|
Ok(SymbolValue::I32(v))
|
||||||
|
} else {
|
||||||
|
Ok(SymbolValue::I64(v.try_into().unwrap()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constant::Float(v) => Ok(SymbolValue::Double(*v)),
|
||||||
|
Constant::Bool(v) => Ok(SymbolValue::Bool(*v)),
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match &default.node {
|
||||||
|
ast::ExprKind::Constant { value, .. } => handle_constant(value, &default.location),
|
||||||
|
ast::ExprKind::Call { func, args, .. } if {
|
||||||
|
match &func.node {
|
||||||
|
ast::ExprKind::Name { id, .. } => *id == "int64".into(),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
} => {
|
||||||
|
if args.len() == 1 {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("only allow constant integer here at {}", default.location)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::ExprKind::Tuple { elts, .. } => Ok(SymbolValue::Tuple(elts
|
||||||
|
.iter()
|
||||||
|
.map(|x| Self::parse_parameter_default_value(x))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?
|
||||||
|
)),
|
||||||
|
_ => unimplemented!("only constant default is supported now at {}", default.location),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue