mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +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)?;
|
.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 {
|
match opt_loc_val {
|
||||||
Some(First(_)) => {
|
Some(First(_)) => {
|
||||||
|
@ -353,7 +353,8 @@ fn expression<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>
|
||||||
)
|
)
|
||||||
.parse(arena, state)?;
|
.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),
|
word1(b',', EType::TFunctionArgument),
|
||||||
one_of![
|
one_of![
|
||||||
space0_around_ee(
|
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")
|
.trace("type_annotation:expression:rest_args"),
|
||||||
.parse(arena, state)?;
|
|
||||||
|
|
||||||
// TODO this space0 is dropped, so newlines just before the function arrow when there
|
// 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?
|
// 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),
|
space0_e(min_indent, EType::TSpace, EType::TIndentStart),
|
||||||
word2(b'-', b'>', EType::TStart)
|
word2(b'-', b'>', EType::TStart)
|
||||||
))
|
)
|
||||||
.trace("type_annotation:expression:arrow")
|
.trace("type_annotation:expression:arrow")
|
||||||
|
])
|
||||||
.parse(arena, state)?;
|
.parse(arena, state)?;
|
||||||
|
|
||||||
if is_function.is_some() {
|
if let Some((rest, _dropped_spaces)) = pre_func {
|
||||||
let (p4, return_type, state) = space0_before_e(
|
let (p3, return_type, state) = space0_before_e(
|
||||||
term(min_indent),
|
term(min_indent),
|
||||||
min_indent,
|
min_indent,
|
||||||
EType::TSpace,
|
EType::TSpace,
|
||||||
|
@ -401,17 +401,11 @@ fn expression<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>
|
||||||
region: return_type.region,
|
region: return_type.region,
|
||||||
value: TypeAnnotation::Function(output, arena.alloc(return_type)),
|
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))
|
Ok((progress, result, state))
|
||||||
} else {
|
} else {
|
||||||
let progress = p1.or(p2).or(p3);
|
// We ran into trouble parsing the function bits; just return the single term
|
||||||
// if there is no function arrow, there cannot be more than 1 "argument"
|
Ok((p1, first, state))
|
||||||
if rest.is_empty() {
|
|
||||||
Ok((progress, first, state))
|
|
||||||
} else {
|
|
||||||
// e.g. `Int,Int` without an arrow and return type
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.trace("type_annotation:expression")
|
.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/float_with_underscores.expr,
|
||||||
pass/full_app_header_trailing_commas.header,
|
pass/full_app_header_trailing_commas.header,
|
||||||
pass/full_app_header.header,
|
pass/full_app_header.header,
|
||||||
|
pass/function_effect_types.header,
|
||||||
pass/highest_float.expr,
|
pass/highest_float.expr,
|
||||||
pass/highest_int.expr,
|
pass/highest_int.expr,
|
||||||
pass/if_def.expr,
|
pass/if_def.expr,
|
||||||
|
@ -197,6 +198,7 @@ mod test_parse {
|
||||||
pass/qualified_global_tag.expr,
|
pass/qualified_global_tag.expr,
|
||||||
pass/qualified_var.expr,
|
pass/qualified_var.expr,
|
||||||
pass/record_destructure_def.expr,
|
pass/record_destructure_def.expr,
|
||||||
|
pass/record_func_type_decl.expr,
|
||||||
pass/record_update.expr,
|
pass/record_update.expr,
|
||||||
pass/record_with_if.expr,
|
pass/record_with_if.expr,
|
||||||
pass/single_arg_closure.expr,
|
pass/single_arg_closure.expr,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue