mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
Allow function types in records
This commit is contained in:
parent
5e7e77dbb1
commit
7b9c8ed939
6 changed files with 339 additions and 39 deletions
|
@ -232,7 +232,7 @@ fn record_type_field<'a>(
|
|||
))
|
||||
.parse(arena, state)?;
|
||||
|
||||
let val_parser = specialize_ref(ETypeRecord::Type, term(min_indent));
|
||||
let val_parser = specialize_ref(ETypeRecord::Type, expression(min_indent));
|
||||
|
||||
match opt_loc_val {
|
||||
Some(First(_)) => {
|
||||
|
@ -353,7 +353,8 @@ fn expression<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>
|
|||
)
|
||||
.parse(arena, state)?;
|
||||
|
||||
let (p2, rest, state) = zero_or_more!(skip_first!(
|
||||
let (p2, pre_func, state) = optional(and![
|
||||
zero_or_more!(skip_first!(
|
||||
word1(b',', EType::TFunctionArgument),
|
||||
one_of![
|
||||
space0_around_ee(
|
||||
|
@ -370,20 +371,19 @@ fn expression<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>
|
|||
))
|
||||
]
|
||||
))
|
||||
.trace("type_annotation:expression:rest_args")
|
||||
.parse(arena, state)?;
|
||||
|
||||
.trace("type_annotation:expression:rest_args"),
|
||||
// TODO this space0 is dropped, so newlines just before the function arrow when there
|
||||
// is only one argument are not seen by the formatter. Can we do better?
|
||||
let (p3, is_function, state) = optional(skip_first!(
|
||||
skip_second!(
|
||||
space0_e(min_indent, EType::TSpace, EType::TIndentStart),
|
||||
word2(b'-', b'>', EType::TStart)
|
||||
))
|
||||
)
|
||||
.trace("type_annotation:expression:arrow")
|
||||
])
|
||||
.parse(arena, state)?;
|
||||
|
||||
if is_function.is_some() {
|
||||
let (p4, return_type, state) = space0_before_e(
|
||||
if let Some((rest, _dropped_spaces)) = pre_func {
|
||||
let (p3, return_type, state) = space0_before_e(
|
||||
term(min_indent),
|
||||
min_indent,
|
||||
EType::TSpace,
|
||||
|
@ -401,17 +401,11 @@ fn expression<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>
|
|||
region: return_type.region,
|
||||
value: TypeAnnotation::Function(output, arena.alloc(return_type)),
|
||||
};
|
||||
let progress = p1.or(p2).or(p3).or(p4);
|
||||
let progress = p1.or(p2).or(p3);
|
||||
Ok((progress, result, state))
|
||||
} else {
|
||||
let progress = p1.or(p2).or(p3);
|
||||
// if there is no function arrow, there cannot be more than 1 "argument"
|
||||
if rest.is_empty() {
|
||||
Ok((progress, first, state))
|
||||
} else {
|
||||
// e.g. `Int,Int` without an arrow and return type
|
||||
panic!()
|
||||
}
|
||||
// We ran into trouble parsing the function bits; just return the single term
|
||||
Ok((p1, first, state))
|
||||
}
|
||||
})
|
||||
.trace("type_annotation:expression")
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
Platform {
|
||||
header: PlatformHeader {
|
||||
name: |L 0-0, C 9-21| PackageName {
|
||||
account: "examples",
|
||||
pkg: "cli",
|
||||
},
|
||||
requires: PlatformRequires {
|
||||
rigids: [],
|
||||
signature: |L 1-1, C 17-34| TypedIdent {
|
||||
ident: |L 1-1, C 17-21| "main",
|
||||
spaces_before_colon: [],
|
||||
ann: |L 1-1, C 24-34| Apply(
|
||||
"",
|
||||
"Task",
|
||||
[
|
||||
|L 1-1, C 29-31| Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
},
|
||||
|L 1-1, C 32-34| TagUnion {
|
||||
ext: None,
|
||||
tags: [],
|
||||
},
|
||||
],
|
||||
),
|
||||
},
|
||||
},
|
||||
exposes: [],
|
||||
packages: [],
|
||||
imports: [
|
||||
|L 4-4, C 14-27| Module(
|
||||
ModuleName(
|
||||
"Task",
|
||||
),
|
||||
[
|
||||
|L 4-4, C 21-25| ExposedName(
|
||||
"Task",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
provides: [
|
||||
|L 5-5, C 15-26| ExposedName(
|
||||
"mainForHost",
|
||||
),
|
||||
],
|
||||
effects: Effects {
|
||||
spaces_before_effects_keyword: [
|
||||
Newline,
|
||||
],
|
||||
spaces_after_effects_keyword: [],
|
||||
spaces_after_type_name: [
|
||||
Newline,
|
||||
],
|
||||
effect_shortname: "fx",
|
||||
effect_type_name: "Effect",
|
||||
entries: [
|
||||
|L 8-8, C 12-32| SpaceBefore(
|
||||
TypedIdent {
|
||||
ident: |L 8-8, C 12-19| "getLine",
|
||||
spaces_before_colon: [],
|
||||
ann: |L 8-8, C 22-32| Apply(
|
||||
"",
|
||||
"Effect",
|
||||
[
|
||||
|L 8-8, C 29-32| Apply(
|
||||
"",
|
||||
"Str",
|
||||
[],
|
||||
),
|
||||
],
|
||||
),
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
|L 9-9, C 12-38| SpaceBefore(
|
||||
TypedIdent {
|
||||
ident: |L 9-9, C 12-19| "putLine",
|
||||
spaces_before_colon: [],
|
||||
ann: |L 9-9, C 29-38| Function(
|
||||
[
|
||||
|L 9-9, C 22-25| Apply(
|
||||
"",
|
||||
"Str",
|
||||
[],
|
||||
),
|
||||
],
|
||||
|L 9-9, C 29-38| Apply(
|
||||
"",
|
||||
"Effect",
|
||||
[
|
||||
|L 9-9, C 36-38| Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
},
|
||||
],
|
||||
),
|
||||
),
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
|L 10-10, C 12-48| SpaceBefore(
|
||||
SpaceAfter(
|
||||
TypedIdent {
|
||||
ident: |L 10-10, C 12-24| "twoArguments",
|
||||
spaces_before_colon: [],
|
||||
ann: |L 10-10, C 39-48| Function(
|
||||
[
|
||||
|L 10-10, C 27-30| Apply(
|
||||
"",
|
||||
"Int",
|
||||
[],
|
||||
),
|
||||
|L 10-10, C 32-35| Apply(
|
||||
"",
|
||||
"Int",
|
||||
[],
|
||||
),
|
||||
],
|
||||
|L 10-10, C 39-48| Apply(
|
||||
"",
|
||||
"Effect",
|
||||
[
|
||||
|L 10-10, C 46-48| Record {
|
||||
fields: [],
|
||||
ext: None,
|
||||
},
|
||||
],
|
||||
),
|
||||
),
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
],
|
||||
},
|
||||
before_header: [],
|
||||
after_platform_keyword: [],
|
||||
before_requires: [
|
||||
Newline,
|
||||
],
|
||||
after_requires: [],
|
||||
before_exposes: [
|
||||
LineComment(
|
||||
" TODO FIXME",
|
||||
),
|
||||
],
|
||||
after_exposes: [],
|
||||
before_packages: [
|
||||
Newline,
|
||||
],
|
||||
after_packages: [],
|
||||
before_imports: [
|
||||
Newline,
|
||||
],
|
||||
after_imports: [],
|
||||
before_provides: [
|
||||
Newline,
|
||||
],
|
||||
after_provides: [],
|
||||
},
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
platform examples/cli
|
||||
requires {}{ main : Task {} [] } # TODO FIXME
|
||||
exposes []
|
||||
packages {}
|
||||
imports [ Task.{ Task } ]
|
||||
provides [ mainForHost ]
|
||||
effects fx.Effect
|
||||
{
|
||||
getLine : Effect Str,
|
||||
putLine : Str -> Effect {},
|
||||
twoArguments : Int, Int -> Effect {}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
Defs(
|
||||
[
|
||||
|L 0-6, C 0-5| Annotation(
|
||||
|L 0-0, C 0-1| Identifier(
|
||||
"f",
|
||||
),
|
||||
|L 1-6, C 4-5| SpaceBefore(
|
||||
Record {
|
||||
fields: [
|
||||
|L 2-2, C 8-28| SpaceBefore(
|
||||
RequiredValue(
|
||||
|L 2-2, C 8-15| "getLine",
|
||||
[],
|
||||
|L 2-2, C 18-28| Apply(
|
||||
"",
|
||||
"Effect",
|
||||
[
|
||||
|L 2-2, C 25-28| Apply(
|
||||
"",
|
||||
"Str",
|
||||
[],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
|L 3-3, C 8-35| SpaceBefore(
|
||||
RequiredValue(
|
||||
|L 3-3, C 8-15| "putLine",
|
||||
[],
|
||||
|L 3-3, C 25-35| Function(
|
||||
[
|
||||
|L 3-3, C 18-21| Apply(
|
||||
"",
|
||||
"Str",
|
||||
[],
|
||||
),
|
||||
],
|
||||
|L 3-3, C 25-35| Apply(
|
||||
"",
|
||||
"Effect",
|
||||
[
|
||||
|L 3-3, C 32-35| Apply(
|
||||
"",
|
||||
"Int",
|
||||
[],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
|L 4-4, C 8-17| SpaceBefore(
|
||||
RequiredValue(
|
||||
|L 4-4, C 8-12| "text",
|
||||
[],
|
||||
|L 4-4, C 14-17| Apply(
|
||||
"",
|
||||
"Str",
|
||||
[],
|
||||
),
|
||||
),
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
|L 5-5, C 8-20| SpaceBefore(
|
||||
SpaceAfter(
|
||||
RequiredValue(
|
||||
|L 5-5, C 8-13| "value",
|
||||
[],
|
||||
|L 5-5, C 15-20| Apply(
|
||||
"",
|
||||
"Int",
|
||||
[
|
||||
|L 5-5, C 19-20| Wildcard,
|
||||
],
|
||||
),
|
||||
),
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
],
|
||||
ext: None,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|L 8-8, C 0-2| SpaceBefore(
|
||||
Num(
|
||||
"42",
|
||||
),
|
||||
[
|
||||
Newline,
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
)
|
|
@ -0,0 +1,9 @@
|
|||
f :
|
||||
{
|
||||
getLine : Effect Str,
|
||||
putLine : Str -> Effect Int,
|
||||
text: Str,
|
||||
value: Int *
|
||||
}
|
||||
|
||||
42
|
|
@ -140,6 +140,7 @@ mod test_parse {
|
|||
pass/float_with_underscores.expr,
|
||||
pass/full_app_header_trailing_commas.header,
|
||||
pass/full_app_header.header,
|
||||
pass/function_effect_types.header,
|
||||
pass/highest_float.expr,
|
||||
pass/highest_int.expr,
|
||||
pass/if_def.expr,
|
||||
|
@ -197,6 +198,7 @@ mod test_parse {
|
|||
pass/qualified_global_tag.expr,
|
||||
pass/qualified_var.expr,
|
||||
pass/record_destructure_def.expr,
|
||||
pass/record_func_type_decl.expr,
|
||||
pass/record_update.expr,
|
||||
pass/record_with_if.expr,
|
||||
pass/single_arg_closure.expr,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue