More complicated FormalParam type
This commit is contained in:
parent
30498d5c98
commit
33c2786ea1
@ -43,7 +43,13 @@ pub enum Statement {
|
||||
|
||||
pub type Block = Vec<Meta<Statement>>;
|
||||
pub type ParamName = Rc<String>;
|
||||
pub type FormalParam = (ParamName, Option<TypeIdentifier>);
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct FormalParam {
|
||||
pub name: ParamName,
|
||||
pub default: Option<Expression>,
|
||||
pub anno: Option<TypeIdentifier>
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Declaration {
|
||||
|
@ -461,14 +461,16 @@ impl Parser {
|
||||
Ok(delimited!(self, LParen, formal_param, Comma, RParen))
|
||||
}
|
||||
|
||||
//TODO needs to support default values
|
||||
#[recursive_descent_method]
|
||||
fn formal_param(&mut self) -> ParseResult<FormalParam> {
|
||||
let name = self.identifier()?;
|
||||
let ty = match self.token_handler.peek_kind() {
|
||||
let anno = match self.token_handler.peek_kind() {
|
||||
Colon => Some(self.type_anno()?),
|
||||
_ => None
|
||||
};
|
||||
Ok((name, ty))
|
||||
let default = None;
|
||||
Ok(FormalParam { name, anno, default })
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
@ -1185,7 +1187,7 @@ mod parse_tests {
|
||||
use super::tokenize;
|
||||
use super::ParseResult;
|
||||
use crate::builtin::{PrefixOp, BinOp};
|
||||
use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument};
|
||||
use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam};
|
||||
use super::Statement::*;
|
||||
use super::Declaration::*;
|
||||
use super::Signature;
|
||||
@ -1375,15 +1377,16 @@ mod parse_tests {
|
||||
|
||||
parse_test!("fn a(b, c: Int): Int", AST(vec![Meta::new(Declaration(
|
||||
FuncSig(Signature { name: rc!(a), operator: false, params: vec![
|
||||
(rc!(b), None), (rc!(c), Some(ty!("Int")))
|
||||
FormalParam { name: rc!(b), anno: None, default: None },
|
||||
FormalParam { name: rc!(c), anno: Some(ty!("Int")), default: None }
|
||||
], type_anno: Some(ty!("Int")) })))]));
|
||||
|
||||
|
||||
parse_test!("fn a(x) { x() }", AST(vec![Meta::new(Declaration(
|
||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), anno: None, default: None }], type_anno: None },
|
||||
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))]));
|
||||
parse_test!("fn a(x) {\n x() }", AST(vec![Meta::new(Declaration(
|
||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), anno: None, default: None }], type_anno: None },
|
||||
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))]));
|
||||
|
||||
let multiline = r#"
|
||||
@ -1392,7 +1395,7 @@ fn a(x) {
|
||||
}
|
||||
"#;
|
||||
parse_test!(multiline, AST(vec![Meta::new(Declaration(
|
||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), default: None, anno: None }], type_anno: None },
|
||||
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))]));
|
||||
let multiline2 = r#"
|
||||
fn a(x) {
|
||||
@ -1402,7 +1405,7 @@ fn a(x) {
|
||||
}
|
||||
"#;
|
||||
parse_test!(multiline2, AST(vec![Meta::new(Declaration(
|
||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), default: None, anno: None }], type_anno: None },
|
||||
vec![exst!(s "x()")])))]));
|
||||
}
|
||||
|
||||
@ -1535,7 +1538,14 @@ fn a(x) {
|
||||
Meta::new(Declaration(Interface {
|
||||
name: rc!(Unglueable),
|
||||
signatures: vec![
|
||||
Signature { name: rc!(unglue), operator: false, params: vec![(rc!(a), Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })))], type_anno: None },
|
||||
Signature {
|
||||
name: rc!(unglue),
|
||||
operator: false,
|
||||
params: vec![
|
||||
FormalParam { name: rc!(a), anno: Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })), default: None }
|
||||
],
|
||||
type_anno: None
|
||||
},
|
||||
Signature { name: rc!(mar), operator: false, params: vec![], type_anno: Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })) },
|
||||
]
|
||||
}))
|
||||
@ -1613,13 +1623,16 @@ fn a(x) {
|
||||
#[test]
|
||||
fn parsing_lambdas() {
|
||||
parse_test_wrap_ast! { r#"\(x) { x + 1}"#, exst!(
|
||||
Lambda { params: vec![(rc!(x), None)], type_anno: None, body: vec![exst!(s "x + 1")] }
|
||||
)
|
||||
Lambda { params: vec![FormalParam { name: rc!(x), anno: None, default: None } ], type_anno: None, body: vec![exst!(s "x + 1")] }
|
||||
)
|
||||
}
|
||||
|
||||
parse_test!(r#"\ (x: Int, y) { a;b;c;}"#, AST(vec![
|
||||
exst!(Lambda {
|
||||
params: vec![(rc!(x), Some(ty!("Int"))), (rc!(y), None)],
|
||||
params: vec![
|
||||
FormalParam { name: rc!(x), anno: Some(ty!("Int")), default: None },
|
||||
FormalParam { name: rc!(y), anno: None, default: None }
|
||||
],
|
||||
type_anno: None,
|
||||
body: vec![exst!(s "a"), exst!(s "b"), exst!(s "c")]
|
||||
})
|
||||
@ -1627,8 +1640,10 @@ fn a(x) {
|
||||
|
||||
parse_test!(r#"\(x){y}(1)"#, AST(vec![
|
||||
exst!(Call { f: bx!(ex!(m
|
||||
Lambda {
|
||||
params: vec![(rc!(x), None)],
|
||||
Lambda {
|
||||
params: vec![
|
||||
FormalParam { name: rc!(x), anno: None, default: None }
|
||||
],
|
||||
type_anno: None,
|
||||
body: vec![exst!(s "y")] }
|
||||
)),
|
||||
@ -1637,7 +1652,9 @@ fn a(x) {
|
||||
parse_test_wrap_ast! {
|
||||
r#"\(x: Int): String { "q" }"#,
|
||||
exst!(Lambda {
|
||||
params: vec![(rc!(x), Some(ty!("Int")))],
|
||||
params: vec![
|
||||
FormalParam { name: rc!(x), anno: Some(ty!("Int")), default: None },
|
||||
],
|
||||
type_anno: Some(ty!("String")),
|
||||
body: vec![exst!(s r#""q""#)]
|
||||
})
|
||||
@ -1647,18 +1664,18 @@ fn a(x) {
|
||||
#[test]
|
||||
fn single_param_lambda() {
|
||||
parse_test_wrap_ast! {
|
||||
r"\x { x + 10 }",
|
||||
r"\x { x + 10 }",
|
||||
exst!(Lambda {
|
||||
params: vec![(rc!(x), None)],
|
||||
params: vec![FormalParam { name: rc!(x), anno: None, default: None }],
|
||||
type_anno: None,
|
||||
body: vec![exst!(s r"x + 10")]
|
||||
})
|
||||
}
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
r"\x: Nat { x + 10 }",
|
||||
r"\x: Nat { x + 10 }",
|
||||
exst!(Lambda {
|
||||
params: vec![(rc!(x), Some(ty!("Nat")))],
|
||||
params: vec![FormalParam { name: rc!(x), anno: Some(ty!("Nat")), default: None }],
|
||||
type_anno: None,
|
||||
body: vec![exst!(s r"x + 10")]
|
||||
})
|
||||
|
@ -165,7 +165,7 @@ impl Expression {
|
||||
fn reduce_lambda(params: &Vec<FormalParam>, body: &Block, symbol_table: &SymbolTable) -> Expr {
|
||||
Expr::Func(Func::UserDefined {
|
||||
name: None,
|
||||
params: params.iter().map(|param| param.0.clone()).collect(),
|
||||
params: params.iter().map(|param| param.name.clone()).collect(),
|
||||
body: reduce_block(body, symbol_table),
|
||||
})
|
||||
}
|
||||
@ -377,7 +377,7 @@ impl Declaration {
|
||||
name: name.clone(),
|
||||
func: Func::UserDefined {
|
||||
name: Some(name.clone()),
|
||||
params: params.iter().map(|param| param.0.clone()).collect(),
|
||||
params: params.iter().map(|param| param.name.clone()).collect(),
|
||||
body: reduce_block(&statements, symbol_table),
|
||||
}
|
||||
},
|
||||
|
@ -169,9 +169,9 @@ impl SymbolTable {
|
||||
|
||||
fn add_function_signature(&mut self, signature: &Signature, scope_name_stack: &mut Vec<ScopeSegment>) -> Result<(), String> {
|
||||
let mut local_type_context = LocalTypeContext::new();
|
||||
let types = signature.params.iter().map(|param| match param {
|
||||
(_, Some(type_identifier)) => Rc::new(format!("{:?}", type_identifier)),
|
||||
(_, None) => local_type_context.new_universal_type()
|
||||
let types = signature.params.iter().map(|param| match param.anno {
|
||||
Some(ref type_identifier) => Rc::new(format!("{:?}", type_identifier)),
|
||||
None => local_type_context.new_universal_type()
|
||||
}).collect();
|
||||
self.add_new_symbol(&signature.name, scope_name_stack, SymbolSpec::Func(types));
|
||||
Ok(())
|
||||
|
@ -369,7 +369,7 @@ impl<'a> TypeContext<'a> {
|
||||
|
||||
fn lambda(&mut self, params: &Vec<FormalParam>, type_anno: &Option<TypeIdentifier>, _body: &Block) -> InferResult<Type> {
|
||||
let argument_types: InferResult<Vec<Type>> = params.iter().map(|param: &FormalParam| {
|
||||
if let (_, Some(type_identifier)) = param {
|
||||
if let FormalParam { anno: Some(type_identifier), .. } = param {
|
||||
self.get_type_from_name(type_identifier)
|
||||
} else {
|
||||
Ok(Type::Var(self.fresh_type_variable()))
|
||||
|
Loading…
Reference in New Issue
Block a user