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 Block = Vec<Meta<Statement>>;
|
||||||
pub type ParamName = Rc<String>;
|
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)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Declaration {
|
pub enum Declaration {
|
||||||
|
@ -461,14 +461,16 @@ impl Parser {
|
|||||||
Ok(delimited!(self, LParen, formal_param, Comma, RParen))
|
Ok(delimited!(self, LParen, formal_param, Comma, RParen))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO needs to support default values
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn formal_param(&mut self) -> ParseResult<FormalParam> {
|
fn formal_param(&mut self) -> ParseResult<FormalParam> {
|
||||||
let name = self.identifier()?;
|
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()?),
|
Colon => Some(self.type_anno()?),
|
||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
Ok((name, ty))
|
let default = None;
|
||||||
|
Ok(FormalParam { name, anno, default })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -1185,7 +1187,7 @@ mod parse_tests {
|
|||||||
use super::tokenize;
|
use super::tokenize;
|
||||||
use super::ParseResult;
|
use super::ParseResult;
|
||||||
use crate::builtin::{PrefixOp, BinOp};
|
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::Statement::*;
|
||||||
use super::Declaration::*;
|
use super::Declaration::*;
|
||||||
use super::Signature;
|
use super::Signature;
|
||||||
@ -1375,15 +1377,16 @@ mod parse_tests {
|
|||||||
|
|
||||||
parse_test!("fn a(b, c: Int): Int", AST(vec![Meta::new(Declaration(
|
parse_test!("fn a(b, c: Int): Int", AST(vec![Meta::new(Declaration(
|
||||||
FuncSig(Signature { name: rc!(a), operator: false, params: vec![
|
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")) })))]));
|
], type_anno: Some(ty!("Int")) })))]));
|
||||||
|
|
||||||
|
|
||||||
parse_test!("fn a(x) { x() }", AST(vec![Meta::new(Declaration(
|
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![] })])))]));
|
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))]));
|
||||||
parse_test!("fn a(x) {\n x() }", AST(vec![Meta::new(Declaration(
|
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![] })])))]));
|
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))]));
|
||||||
|
|
||||||
let multiline = r#"
|
let multiline = r#"
|
||||||
@ -1392,7 +1395,7 @@ fn a(x) {
|
|||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
parse_test!(multiline, AST(vec![Meta::new(Declaration(
|
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![] })])))]));
|
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))]));
|
||||||
let multiline2 = r#"
|
let multiline2 = r#"
|
||||||
fn a(x) {
|
fn a(x) {
|
||||||
@ -1402,7 +1405,7 @@ fn a(x) {
|
|||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
parse_test!(multiline2, AST(vec![Meta::new(Declaration(
|
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()")])))]));
|
vec![exst!(s "x()")])))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1535,7 +1538,14 @@ fn a(x) {
|
|||||||
Meta::new(Declaration(Interface {
|
Meta::new(Declaration(Interface {
|
||||||
name: rc!(Unglueable),
|
name: rc!(Unglueable),
|
||||||
signatures: vec![
|
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![] })) },
|
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]
|
#[test]
|
||||||
fn parsing_lambdas() {
|
fn parsing_lambdas() {
|
||||||
parse_test_wrap_ast! { r#"\(x) { x + 1}"#, exst!(
|
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![
|
parse_test!(r#"\ (x: Int, y) { a;b;c;}"#, AST(vec![
|
||||||
exst!(Lambda {
|
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,
|
type_anno: None,
|
||||||
body: vec![exst!(s "a"), exst!(s "b"), exst!(s "c")]
|
body: vec![exst!(s "a"), exst!(s "b"), exst!(s "c")]
|
||||||
})
|
})
|
||||||
@ -1628,7 +1641,9 @@ fn a(x) {
|
|||||||
parse_test!(r#"\(x){y}(1)"#, AST(vec![
|
parse_test!(r#"\(x){y}(1)"#, AST(vec![
|
||||||
exst!(Call { f: bx!(ex!(m
|
exst!(Call { f: bx!(ex!(m
|
||||||
Lambda {
|
Lambda {
|
||||||
params: vec![(rc!(x), None)],
|
params: vec![
|
||||||
|
FormalParam { name: rc!(x), anno: None, default: None }
|
||||||
|
],
|
||||||
type_anno: None,
|
type_anno: None,
|
||||||
body: vec![exst!(s "y")] }
|
body: vec![exst!(s "y")] }
|
||||||
)),
|
)),
|
||||||
@ -1637,7 +1652,9 @@ fn a(x) {
|
|||||||
parse_test_wrap_ast! {
|
parse_test_wrap_ast! {
|
||||||
r#"\(x: Int): String { "q" }"#,
|
r#"\(x: Int): String { "q" }"#,
|
||||||
exst!(Lambda {
|
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")),
|
type_anno: Some(ty!("String")),
|
||||||
body: vec![exst!(s r#""q""#)]
|
body: vec![exst!(s r#""q""#)]
|
||||||
})
|
})
|
||||||
@ -1649,7 +1666,7 @@ fn a(x) {
|
|||||||
parse_test_wrap_ast! {
|
parse_test_wrap_ast! {
|
||||||
r"\x { x + 10 }",
|
r"\x { x + 10 }",
|
||||||
exst!(Lambda {
|
exst!(Lambda {
|
||||||
params: vec![(rc!(x), None)],
|
params: vec![FormalParam { name: rc!(x), anno: None, default: None }],
|
||||||
type_anno: None,
|
type_anno: None,
|
||||||
body: vec![exst!(s r"x + 10")]
|
body: vec![exst!(s r"x + 10")]
|
||||||
})
|
})
|
||||||
@ -1658,7 +1675,7 @@ fn a(x) {
|
|||||||
parse_test_wrap_ast! {
|
parse_test_wrap_ast! {
|
||||||
r"\x: Nat { x + 10 }",
|
r"\x: Nat { x + 10 }",
|
||||||
exst!(Lambda {
|
exst!(Lambda {
|
||||||
params: vec![(rc!(x), Some(ty!("Nat")))],
|
params: vec![FormalParam { name: rc!(x), anno: Some(ty!("Nat")), default: None }],
|
||||||
type_anno: None,
|
type_anno: None,
|
||||||
body: vec![exst!(s r"x + 10")]
|
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 {
|
fn reduce_lambda(params: &Vec<FormalParam>, body: &Block, symbol_table: &SymbolTable) -> Expr {
|
||||||
Expr::Func(Func::UserDefined {
|
Expr::Func(Func::UserDefined {
|
||||||
name: None,
|
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),
|
body: reduce_block(body, symbol_table),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -377,7 +377,7 @@ impl Declaration {
|
|||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
func: Func::UserDefined {
|
func: Func::UserDefined {
|
||||||
name: Some(name.clone()),
|
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),
|
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> {
|
fn add_function_signature(&mut self, signature: &Signature, scope_name_stack: &mut Vec<ScopeSegment>) -> Result<(), String> {
|
||||||
let mut local_type_context = LocalTypeContext::new();
|
let mut local_type_context = LocalTypeContext::new();
|
||||||
let types = signature.params.iter().map(|param| match param {
|
let types = signature.params.iter().map(|param| match param.anno {
|
||||||
(_, Some(type_identifier)) => Rc::new(format!("{:?}", type_identifier)),
|
Some(ref type_identifier) => Rc::new(format!("{:?}", type_identifier)),
|
||||||
(_, None) => local_type_context.new_universal_type()
|
None => local_type_context.new_universal_type()
|
||||||
}).collect();
|
}).collect();
|
||||||
self.add_new_symbol(&signature.name, scope_name_stack, SymbolSpec::Func(types));
|
self.add_new_symbol(&signature.name, scope_name_stack, SymbolSpec::Func(types));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -369,7 +369,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
|
|
||||||
fn lambda(&mut self, params: &Vec<FormalParam>, type_anno: &Option<TypeIdentifier>, _body: &Block) -> InferResult<Type> {
|
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| {
|
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)
|
self.get_type_from_name(type_identifier)
|
||||||
} else {
|
} else {
|
||||||
Ok(Type::Var(self.fresh_type_variable()))
|
Ok(Type::Var(self.fresh_type_variable()))
|
||||||
|
Loading…
Reference in New Issue
Block a user