mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
basic parsing
This commit is contained in:
parent
063c039003
commit
64bc92c746
7 changed files with 140 additions and 20 deletions
|
@ -8,6 +8,7 @@ use crate::parser::{
|
|||
use crate::string_literal;
|
||||
use bumpalo::collections::Vec;
|
||||
use inlinable_string::InlinableString;
|
||||
use roc_module::ident::{Lowercase, Uppercase};
|
||||
use roc_region::all::Loc;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
|
@ -124,10 +125,34 @@ pub struct PackageHeader<'a> {
|
|||
pub after_imports: &'a [CommentOrNewline<'a>],
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum PlatformRigid<'a> {
|
||||
Entry { rigid: &'a str, alias: &'a str },
|
||||
|
||||
// Spaces
|
||||
SpaceBefore(&'a PlatformRigid<'a>, &'a [CommentOrNewline<'a>]),
|
||||
SpaceAfter(&'a PlatformRigid<'a>, &'a [CommentOrNewline<'a>]),
|
||||
}
|
||||
|
||||
impl<'a> Spaceable<'a> for PlatformRigid<'a> {
|
||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||
PlatformRigid::SpaceBefore(self, spaces)
|
||||
}
|
||||
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||
PlatformRigid::SpaceAfter(self, spaces)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PlatformRequires<'a> {
|
||||
pub rigids: Vec<'a, Loc<PlatformRigid<'a>>>,
|
||||
pub signature: Loc<TypedIdent<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PlatformHeader<'a> {
|
||||
pub name: Loc<PackageName<'a>>,
|
||||
pub requires: Vec<'a, Loc<TypedIdent<'a>>>,
|
||||
pub requires: PlatformRequires<'a>,
|
||||
pub exposes: Vec<'a, Loc<ExposesEntry<'a, ModuleName<'a>>>>,
|
||||
pub packages: Vec<'a, Loc<PackageEntry<'a>>>,
|
||||
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
||||
|
|
|
@ -2,12 +2,13 @@ use crate::ast::{CommentOrNewline, Def, Module};
|
|||
use crate::blankspace::{space0_before_e, space0_e};
|
||||
use crate::header::{
|
||||
package_entry, package_name, package_or_path, AppHeader, Effects, ExposesEntry, ImportsEntry,
|
||||
InterfaceHeader, ModuleName, PackageEntry, PlatformHeader, To, TypedIdent,
|
||||
InterfaceHeader, ModuleName, PackageEntry, PlatformHeader, PlatformRequires, PlatformRigid, To,
|
||||
TypedIdent,
|
||||
};
|
||||
use crate::ident::{lowercase_ident, unqualified_ident, uppercase_ident};
|
||||
use crate::parser::Progress::{self, *};
|
||||
use crate::parser::{
|
||||
backtrackable, specialize, word1, Col, EEffects, EExposes, EHeader, EImports, EPackages,
|
||||
backtrackable, specialize, word1, word2, Col, EEffects, EExposes, EHeader, EImports, EPackages,
|
||||
EProvides, ERequires, ETypedIdent, Parser, Row, State, SyntaxError,
|
||||
};
|
||||
use crate::string_literal;
|
||||
|
@ -406,12 +407,12 @@ fn requires<'a>() -> impl Parser<
|
|||
'a,
|
||||
(
|
||||
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||
Vec<'a, Located<TypedIdent<'a>>>,
|
||||
PlatformRequires<'a>,
|
||||
),
|
||||
ERequires<'a>,
|
||||
> {
|
||||
let min_indent = 1;
|
||||
and!(
|
||||
let min_indent = 0;
|
||||
debug!(and!(
|
||||
spaces_around_keyword(
|
||||
min_indent,
|
||||
"requires",
|
||||
|
@ -420,14 +421,53 @@ fn requires<'a>() -> impl Parser<
|
|||
ERequires::IndentRequires,
|
||||
ERequires::IndentListStart
|
||||
),
|
||||
collection_e!(
|
||||
word1(b'{', ERequires::ListStart),
|
||||
platform_requires()
|
||||
))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn platform_requires<'a>() -> impl Parser<'a, PlatformRequires<'a>, ERequires<'a>> {
|
||||
map!(and!(requires_rigids(0), requires_typed_ident()), |(
|
||||
rigids,
|
||||
signature,
|
||||
)| {
|
||||
PlatformRequires { rigids, signature }
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn requires_rigids<'a>(
|
||||
min_indent: u16,
|
||||
) -> impl Parser<'a, Vec<'a, Located<PlatformRigid<'a>>>, ERequires<'a>> {
|
||||
collection_e!(
|
||||
word1(b'[', ERequires::ListStart),
|
||||
specialize(|_, r, c| ERequires::Rigid(r, c), loc!(requires_rigid())),
|
||||
word1(b',', ERequires::ListEnd),
|
||||
word1(b']', ERequires::ListEnd),
|
||||
min_indent,
|
||||
ERequires::Space,
|
||||
ERequires::IndentListEnd
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn requires_rigid<'a>() -> impl Parser<'a, PlatformRigid<'a>, ()> {
|
||||
map!(
|
||||
and!(
|
||||
lowercase_ident(),
|
||||
skip_first!(word2(b'=', b'>', |_, _| ()), uppercase_ident())
|
||||
),
|
||||
|(rigid, alias)| PlatformRigid::Entry { rigid, alias }
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn requires_typed_ident<'a>() -> impl Parser<'a, Located<TypedIdent<'a>>, ERequires<'a>> {
|
||||
skip_first!(
|
||||
word1(b'{', ERequires::ListStart),
|
||||
skip_second!(
|
||||
specialize(ERequires::TypedIdent, loc!(typed_ident())),
|
||||
word1(b',', ERequires::ListEnd),
|
||||
word1(b'}', ERequires::ListEnd),
|
||||
min_indent,
|
||||
ERequires::Space,
|
||||
ERequires::IndentListEnd
|
||||
word1(b'}', ERequires::ListStart)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -621,10 +661,10 @@ fn effects<'a>() -> impl Parser<'a, Effects<'a>, EEffects<'a>> {
|
|||
.parse(arena, state)?;
|
||||
|
||||
// e.g. `fx.`
|
||||
let (_, type_shortname, state) = skip_second!(
|
||||
let (_, type_shortname, state) = debug!(skip_second!(
|
||||
specialize(|_, r, c| EEffects::Shorthand(r, c), lowercase_ident()),
|
||||
word1(b'.', EEffects::ShorthandDot)
|
||||
)
|
||||
))
|
||||
.parse(arena, state)?;
|
||||
|
||||
// the type name, e.g. Effects
|
||||
|
|
|
@ -248,6 +248,7 @@ pub enum ERequires<'a> {
|
|||
ListStart(Row, Col),
|
||||
ListEnd(Row, Col),
|
||||
TypedIdent(ETypedIdent<'a>, Row, Col),
|
||||
Rigid(Row, Col),
|
||||
Space(BadInputError, Row, Col),
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue