diff --git a/schala-lang/language/src/parser.rs b/schala-lang/language/src/parser.rs index d0b9548..6a3cff7 100644 --- a/schala-lang/language/src/parser.rs +++ b/schala-lang/language/src/parser.rs @@ -457,8 +457,10 @@ fn formal_params(text: &str) -> ParseResult> { } fn formal_param(text: &str) -> ParseResult { - let p = tuple((identifier, opt(type_anno))); - //TODO handle default arg + let default = opt(preceded(ws(tag("=")), expression)); + let p = tuple((ws(identifier), opt(ws(type_anno)), default)); + map(p, |(name, anno, default)| + FormalParam { name, anno, default })(text) } fn type_declaration(text: &str) -> ParseResult { @@ -466,7 +468,7 @@ fn type_declaration(text: &str) -> ParseResult { } fn type_declaration_body(text: &str) -> ParseResult { - let t = tuple((opt(tag("mut"))), ws(type_singleton_name), ws(tag("=")), ws(type_body)); + let t = tuple((opt(tag("mut")), ws(type_singleton_name), ws(tag("=")), ws(type_body))); alt(( preceded(tag("alias"), ws(type_alias)), map(t, |(mut_kw, name, _, body)| { @@ -475,10 +477,29 @@ fn type_declaration_body(text: &str) -> ParseResult { ))(text) } +fn type_body(text: &str) -> ParseResult { + let p = separated_nonempty_list(ws(tag("|")), variant_specifier); + map(p, TypeBody)(text) +} + +fn variant_specifier(text: &str) -> ParseResult { + use self::Variant::*; + let tuple_struct = + delimited(tag("("), separated_nonempty_list(ws(tag(",")), type_name), ws(tag(")"))); + //TODO record + + let p = tuple((identifier, opt(tuple_struct))); + map(p, |(name, maybe_tuple_members)| match maybe_tuple_members { + Some(members) => TupleStruct(name, members), + None => UnitStruct(name), + })(text) +} + fn type_singleton_name(text: &str) -> ParseResult { - tuple((identifier, opt(delimited(tag("<"), + let p = tuple((identifier, opt(delimited(tag("<"), separated_nonempty_list(tag(","), ws(type_name)), - tag(">")))))(text) + tag(">"))))); + map(p, |(name, params)| TypeSingletonName { name, params: params.unwrap_or(vec![]) })(text) } fn type_alias(text: &str) -> ParseResult {