mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
Finish introducing new header keywords
This commit is contained in:
parent
ab1be6e394
commit
a78434fd48
6 changed files with 404 additions and 210 deletions
|
@ -1,8 +1,7 @@
|
||||||
use crate::spaces::{fmt_spaces, INDENT};
|
use crate::spaces::{fmt_spaces, INDENT};
|
||||||
use bumpalo::collections::{String, Vec};
|
use bumpalo::collections::{String, Vec};
|
||||||
use roc_parse::ast::{
|
use roc_parse::ast::Module;
|
||||||
AppHeader, ExposesEntry, ImportsEntry, InterfaceHeader, Module, PlatformHeader,
|
use roc_parse::header::{AppHeader, ExposesEntry, ImportsEntry, InterfaceHeader, PlatformHeader};
|
||||||
};
|
|
||||||
use roc_region::all::Located;
|
use roc_region::all::Located;
|
||||||
|
|
||||||
pub fn fmt_module<'a>(buf: &mut String<'a>, module: &'a Module<'a>) {
|
pub fn fmt_module<'a>(buf: &mut String<'a>, module: &'a Module<'a>) {
|
||||||
|
@ -113,7 +112,7 @@ fn fmt_imports<'a>(
|
||||||
|
|
||||||
fn fmt_exposes<'a>(
|
fn fmt_exposes<'a>(
|
||||||
buf: &mut String<'a>,
|
buf: &mut String<'a>,
|
||||||
loc_entries: &'a Vec<'a, Located<ExposesEntry<'a>>>,
|
loc_entries: &'a Vec<'a, Located<ExposesEntry<'a, &'a str>>>,
|
||||||
indent: u16,
|
indent: u16,
|
||||||
) {
|
) {
|
||||||
buf.push('[');
|
buf.push('[');
|
||||||
|
@ -137,11 +136,11 @@ fn fmt_exposes<'a>(
|
||||||
buf.push(']');
|
buf.push(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_exposes_entry<'a>(buf: &mut String<'a>, entry: &'a ExposesEntry<'a>, indent: u16) {
|
fn fmt_exposes_entry<'a>(buf: &mut String<'a>, entry: &'a ExposesEntry<'a, &'a str>, indent: u16) {
|
||||||
use roc_parse::ast::ExposesEntry::*;
|
use roc_parse::header::ExposesEntry::*;
|
||||||
|
|
||||||
match entry {
|
match entry {
|
||||||
Ident(ident) => buf.push_str(ident),
|
Exposed(ident) => buf.push_str(ident),
|
||||||
|
|
||||||
SpaceBefore(sub_entry, spaces) => {
|
SpaceBefore(sub_entry, spaces) => {
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
fmt_spaces(buf, spaces.iter(), indent);
|
||||||
|
@ -155,7 +154,7 @@ fn fmt_exposes_entry<'a>(buf: &mut String<'a>, entry: &'a ExposesEntry<'a>, inde
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_imports_entry<'a>(buf: &mut String<'a>, entry: &'a ImportsEntry<'a>, indent: u16) {
|
fn fmt_imports_entry<'a>(buf: &mut String<'a>, entry: &'a ImportsEntry<'a>, indent: u16) {
|
||||||
use roc_parse::ast::ImportsEntry::*;
|
use roc_parse::header::ImportsEntry::*;
|
||||||
|
|
||||||
match entry {
|
match entry {
|
||||||
Module(module, loc_exposes_entries) => {
|
Module(module, loc_exposes_entries) => {
|
||||||
|
@ -176,6 +175,10 @@ fn fmt_imports_entry<'a>(buf: &mut String<'a>, entry: &'a ImportsEntry<'a>, inde
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Package(_name, _entries) => {
|
||||||
|
todo!("TODO Format imported package");
|
||||||
|
}
|
||||||
|
|
||||||
SpaceBefore(sub_entry, spaces) => {
|
SpaceBefore(sub_entry, spaces) => {
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
fmt_spaces(buf, spaces.iter(), indent);
|
||||||
fmt_imports_entry(buf, sub_entry, indent);
|
fmt_imports_entry(buf, sub_entry, indent);
|
||||||
|
|
|
@ -19,9 +19,8 @@ use roc_mono::ir::{
|
||||||
CapturedSymbols, ExternalSpecializations, PartialProc, PendingSpecialization, Proc, Procs,
|
CapturedSymbols, ExternalSpecializations, PartialProc, PendingSpecialization, Proc, Procs,
|
||||||
};
|
};
|
||||||
use roc_mono::layout::{Layout, LayoutCache};
|
use roc_mono::layout::{Layout, LayoutCache};
|
||||||
use roc_parse::ast::{
|
use roc_parse::ast::{self, Attempting, TypeAnnotation};
|
||||||
self, Attempting, ExposesEntry, ImportsEntry, PlatformHeader, TypeAnnotation, TypedIdent,
|
use roc_parse::header::{ExposesEntry, ImportsEntry, PlatformHeader, TypedIdent};
|
||||||
};
|
|
||||||
use roc_parse::module::module_defs;
|
use roc_parse::module::module_defs;
|
||||||
use roc_parse::parser::{self, Fail, Parser};
|
use roc_parse::parser::{self, Fail, Parser};
|
||||||
use roc_region::all::{Located, Region};
|
use roc_region::all::{Located, Region};
|
||||||
|
@ -2087,7 +2086,7 @@ fn load_from_str<'a>(
|
||||||
fn send_header<'a>(
|
fn send_header<'a>(
|
||||||
name: Located<roc_parse::header::ModuleName<'a>>,
|
name: Located<roc_parse::header::ModuleName<'a>>,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
exposes: &'a [Located<ExposesEntry<'a>>],
|
exposes: &'a [Located<ExposesEntry<'a, &'a str>>],
|
||||||
imports: &'a [Located<ImportsEntry<'a>>],
|
imports: &'a [Located<ImportsEntry<'a>>],
|
||||||
parse_state: parser::State<'a>,
|
parse_state: parser::State<'a>,
|
||||||
module_ids: Arc<Mutex<ModuleIds>>,
|
module_ids: Arc<Mutex<ModuleIds>>,
|
||||||
|
@ -2737,7 +2736,7 @@ fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, Loadi
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exposed_from_import(entry: &ImportsEntry<'_>) -> (ModuleName, Vec<Ident>) {
|
fn exposed_from_import(entry: &ImportsEntry<'_>) -> (ModuleName, Vec<Ident>) {
|
||||||
use roc_parse::ast::ImportsEntry::*;
|
use roc_parse::header::ImportsEntry::*;
|
||||||
|
|
||||||
match entry {
|
match entry {
|
||||||
Module(module_name, exposes) => {
|
Module(module_name, exposes) => {
|
||||||
|
@ -2757,11 +2756,11 @@ fn exposed_from_import(entry: &ImportsEntry<'_>) -> (ModuleName, Vec<Ident>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ident_from_exposed(entry: &ExposesEntry<'_>) -> Ident {
|
fn ident_from_exposed(entry: &ExposesEntry<'_, &str>) -> Ident {
|
||||||
use roc_parse::ast::ExposesEntry::*;
|
use roc_parse::header::ExposesEntry::*;
|
||||||
|
|
||||||
match entry {
|
match entry {
|
||||||
Ident(ident) => (*ident).into(),
|
Exposed(ident) => (*ident).into(),
|
||||||
SpaceBefore(sub_entry, _) | SpaceAfter(sub_entry, _) => ident_from_exposed(sub_entry),
|
SpaceBefore(sub_entry, _) | SpaceAfter(sub_entry, _) => ident_from_exposed(sub_entry),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::header::{ModuleName, PackageName};
|
use crate::header::{AppHeader, ImportsEntry, InterfaceHeader, PlatformHeader, TypedIdent};
|
||||||
use crate::ident::Ident;
|
use crate::ident::Ident;
|
||||||
use bumpalo::collections::String;
|
use bumpalo::collections::String;
|
||||||
use bumpalo::collections::Vec;
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use roc_module::operator::{BinOp, CalledVia, UnaryOp};
|
use roc_module::operator::{BinOp, CalledVia, UnaryOp};
|
||||||
use roc_region::all::{Loc, Region};
|
use roc_region::all::{Loc, Region};
|
||||||
|
@ -13,20 +12,6 @@ pub enum Module<'a> {
|
||||||
Platform { header: PlatformHeader<'a> },
|
Platform { header: PlatformHeader<'a> },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct InterfaceHeader<'a> {
|
|
||||||
pub name: Loc<ModuleName<'a>>,
|
|
||||||
pub exposes: Vec<'a, Loc<ExposesEntry<'a>>>,
|
|
||||||
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
|
||||||
|
|
||||||
// Potential comments and newlines - these will typically all be empty.
|
|
||||||
pub after_interface_keyword: &'a [CommentOrNewline<'a>],
|
|
||||||
pub before_exposes: &'a [CommentOrNewline<'a>],
|
|
||||||
pub after_exposes: &'a [CommentOrNewline<'a>],
|
|
||||||
pub before_imports: &'a [CommentOrNewline<'a>],
|
|
||||||
pub after_imports: &'a [CommentOrNewline<'a>],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct WhenBranch<'a> {
|
pub struct WhenBranch<'a> {
|
||||||
pub patterns: &'a [Loc<Pattern<'a>>],
|
pub patterns: &'a [Loc<Pattern<'a>>],
|
||||||
|
@ -34,94 +19,6 @@ pub struct WhenBranch<'a> {
|
||||||
pub guard: Option<Loc<Expr<'a>>>,
|
pub guard: Option<Loc<Expr<'a>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct AppHeader<'a> {
|
|
||||||
pub name: Loc<ModuleName<'a>>,
|
|
||||||
pub provides: Vec<'a, Loc<ExposesEntry<'a>>>,
|
|
||||||
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
|
||||||
|
|
||||||
// Potential comments and newlines - these will typically all be empty.
|
|
||||||
pub after_app_keyword: &'a [CommentOrNewline<'a>],
|
|
||||||
pub before_provides: &'a [CommentOrNewline<'a>],
|
|
||||||
pub after_provides: &'a [CommentOrNewline<'a>],
|
|
||||||
pub before_imports: &'a [CommentOrNewline<'a>],
|
|
||||||
pub after_imports: &'a [CommentOrNewline<'a>],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct PlatformHeader<'a> {
|
|
||||||
pub name: Loc<PackageName<'a>>,
|
|
||||||
pub provides: Vec<'a, Loc<ExposesEntry<'a>>>,
|
|
||||||
pub requires: Vec<'a, Loc<TypedIdent<'a>>>,
|
|
||||||
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
|
||||||
pub effects: Effects<'a>,
|
|
||||||
|
|
||||||
// Potential comments and newlines - these will typically all be empty.
|
|
||||||
pub after_platform_keyword: &'a [CommentOrNewline<'a>],
|
|
||||||
pub before_provides: &'a [CommentOrNewline<'a>],
|
|
||||||
pub after_provides: &'a [CommentOrNewline<'a>],
|
|
||||||
pub before_requires: &'a [CommentOrNewline<'a>],
|
|
||||||
pub after_requires: &'a [CommentOrNewline<'a>],
|
|
||||||
pub before_imports: &'a [CommentOrNewline<'a>],
|
|
||||||
pub after_imports: &'a [CommentOrNewline<'a>],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct Effects<'a> {
|
|
||||||
pub spaces_before_effects_keyword: &'a [CommentOrNewline<'a>],
|
|
||||||
pub spaces_after_effects_keyword: &'a [CommentOrNewline<'a>],
|
|
||||||
pub spaces_after_type_name: &'a [CommentOrNewline<'a>],
|
|
||||||
pub type_name: &'a str,
|
|
||||||
pub entries: Vec<'a, Loc<TypedIdent<'a>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum TypedIdent<'a> {
|
|
||||||
/// e.g.
|
|
||||||
///
|
|
||||||
/// printLine : Str -> Effect {}
|
|
||||||
Entry {
|
|
||||||
ident: Loc<&'a str>,
|
|
||||||
spaces_before_colon: &'a [CommentOrNewline<'a>],
|
|
||||||
ann: Loc<TypeAnnotation<'a>>,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Spaces
|
|
||||||
SpaceBefore(&'a TypedIdent<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
SpaceAfter(&'a TypedIdent<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum ExposesEntry<'a> {
|
|
||||||
/// e.g. `Task`
|
|
||||||
Ident(&'a str),
|
|
||||||
|
|
||||||
// Spaces
|
|
||||||
SpaceBefore(&'a ExposesEntry<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
SpaceAfter(&'a ExposesEntry<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum ImportsEntry<'a> {
|
|
||||||
/// e.g. `Task` or `Task.{ Task, after }`
|
|
||||||
Module(ModuleName<'a>, Vec<'a, Loc<ExposesEntry<'a>>>),
|
|
||||||
|
|
||||||
// Spaces
|
|
||||||
SpaceBefore(&'a ImportsEntry<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
SpaceAfter(&'a ImportsEntry<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ExposesEntry<'a> {
|
|
||||||
pub fn as_str(&'a self) -> &'a str {
|
|
||||||
use ExposesEntry::*;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
Ident(string) => string,
|
|
||||||
SpaceBefore(sub_entry, _) | SpaceAfter(sub_entry, _) => sub_entry.as_str(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct WhenPattern<'a> {
|
pub struct WhenPattern<'a> {
|
||||||
pub pattern: Loc<Pattern<'a>>,
|
pub pattern: Loc<Pattern<'a>>,
|
||||||
|
@ -633,15 +530,6 @@ impl<'a> Spaceable<'a> for TypeAnnotation<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Spaceable<'a> for ExposesEntry<'a> {
|
|
||||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
ExposesEntry::SpaceBefore(self, spaces)
|
|
||||||
}
|
|
||||||
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
ExposesEntry::SpaceAfter(self, spaces)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Spaceable<'a> for ImportsEntry<'a> {
|
impl<'a> Spaceable<'a> for ImportsEntry<'a> {
|
||||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
ImportsEntry::SpaceBefore(self, spaces)
|
ImportsEntry::SpaceBefore(self, spaces)
|
||||||
|
|
|
@ -1,15 +1,43 @@
|
||||||
use crate::ast::CommentOrNewline;
|
use crate::ast::{CommentOrNewline, Spaceable, StrLiteral, TypeAnnotation};
|
||||||
|
use crate::blankspace::space0;
|
||||||
|
use crate::ident::lowercase_ident;
|
||||||
|
use crate::module::package_name;
|
||||||
|
use crate::parser::{ascii_char, optional, Either, Parser};
|
||||||
|
use crate::string_literal;
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
use inlinable_string::InlinableString;
|
use inlinable_string::InlinableString;
|
||||||
use roc_region::all::Loc;
|
use roc_region::all::Loc;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub struct PackageName<'a> {
|
pub struct PackageName<'a> {
|
||||||
pub account: &'a str,
|
pub account: &'a str,
|
||||||
pub pkg: &'a str,
|
pub pkg: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
|
pub enum Version<'a> {
|
||||||
|
Exact(&'a str),
|
||||||
|
Range {
|
||||||
|
min: &'a str,
|
||||||
|
min_comparison: VersionComparison,
|
||||||
|
max: &'a str,
|
||||||
|
max_comparison: VersionComparison,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
|
pub enum VersionComparison {
|
||||||
|
AllowsEqual,
|
||||||
|
DisallowsEqual,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
pub enum PackageOrPath<'a> {
|
||||||
|
Package(PackageName<'a>, Version<'a>),
|
||||||
|
Path(StrLiteral<'a>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub struct ModuleName<'a>(&'a str);
|
pub struct ModuleName<'a>(&'a str);
|
||||||
|
|
||||||
impl<'a> Into<&'a str> for ModuleName<'a> {
|
impl<'a> Into<&'a str> for ModuleName<'a> {
|
||||||
|
@ -34,15 +62,14 @@ impl<'a> ModuleName<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO is this all duplicated from parse::ast?
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct InterfaceHeader<'a> {
|
pub struct InterfaceHeader<'a> {
|
||||||
pub name: Loc<ModuleName<'a>>,
|
pub name: Loc<ModuleName<'a>>,
|
||||||
pub exposes: Vec<'a, Loc<Exposes<'a>>>,
|
pub exposes: Vec<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
||||||
pub imports: Vec<'a, (ModuleName<'a>, Vec<'a, Loc<Imports<'a>>>)>,
|
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
||||||
|
|
||||||
// Potential comments and newlines - these will typically all be empty.
|
// Potential comments and newlines - these will typically all be empty.
|
||||||
pub after_interface: &'a [CommentOrNewline<'a>],
|
pub after_interface_keyword: &'a [CommentOrNewline<'a>],
|
||||||
pub before_exposes: &'a [CommentOrNewline<'a>],
|
pub before_exposes: &'a [CommentOrNewline<'a>],
|
||||||
pub after_exposes: &'a [CommentOrNewline<'a>],
|
pub after_exposes: &'a [CommentOrNewline<'a>],
|
||||||
pub before_imports: &'a [CommentOrNewline<'a>],
|
pub before_imports: &'a [CommentOrNewline<'a>],
|
||||||
|
@ -51,29 +78,202 @@ pub struct InterfaceHeader<'a> {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct AppHeader<'a> {
|
pub struct AppHeader<'a> {
|
||||||
pub imports: Vec<'a, (ModuleName<'a>, Loc<Imports<'a>>)>,
|
pub name: Loc<StrLiteral<'a>>,
|
||||||
|
pub packages: Vec<'a, Loc<PackageEntry<'a>>>,
|
||||||
|
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
||||||
|
pub provides: Vec<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
||||||
|
pub to: Loc<&'a str>,
|
||||||
|
|
||||||
// Potential comments and newlines - these will typically all be empty.
|
// Potential comments and newlines - these will typically all be empty.
|
||||||
|
pub after_app_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_packages: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_packages: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_imports: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_imports: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_provides: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_provides: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_to: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_to: &'a [CommentOrNewline<'a>],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct PackageHeader<'a> {
|
||||||
|
pub name: Loc<PackageName<'a>>,
|
||||||
|
pub exposes: Vec<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
||||||
|
pub packages: Vec<'a, (Loc<&'a str>, Loc<PackageOrPath<'a>>)>,
|
||||||
|
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
||||||
|
|
||||||
|
// Potential comments and newlines - these will typically all be empty.
|
||||||
|
pub after_package_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_exposes: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_exposes: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_packages: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_packages: &'a [CommentOrNewline<'a>],
|
||||||
pub before_imports: &'a [CommentOrNewline<'a>],
|
pub before_imports: &'a [CommentOrNewline<'a>],
|
||||||
pub after_imports: &'a [CommentOrNewline<'a>],
|
pub after_imports: &'a [CommentOrNewline<'a>],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Exposes<'a> {
|
pub struct PlatformHeader<'a> {
|
||||||
/// e.g. `Task`
|
pub name: Loc<PackageName<'a>>,
|
||||||
Ident(&'a str),
|
pub requires: Vec<'a, Loc<TypedIdent<'a>>>,
|
||||||
|
pub exposes: Vec<'a, Loc<ExposesEntry<'a, ModuleName<'a>>>>,
|
||||||
|
pub packages: Vec<'a, Loc<PackageEntry<'a>>>,
|
||||||
|
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
||||||
|
pub provides: Vec<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
||||||
|
pub effects: Effects<'a>,
|
||||||
|
|
||||||
// Spaces
|
// Potential comments and newlines - these will typically all be empty.
|
||||||
SpaceBefore(&'a Exposes<'a>, &'a [CommentOrNewline<'a>]),
|
pub after_platform_keyword: &'a [CommentOrNewline<'a>],
|
||||||
SpaceAfter(&'a Exposes<'a>, &'a [CommentOrNewline<'a>]),
|
pub before_requires: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_requires: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_exposes: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_exposes: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_packages: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_packages: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_imports: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_imports: &'a [CommentOrNewline<'a>],
|
||||||
|
pub before_provides: &'a [CommentOrNewline<'a>],
|
||||||
|
pub after_provides: &'a [CommentOrNewline<'a>],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Imports<'a> {
|
pub struct Effects<'a> {
|
||||||
/// e.g. `Task` or `Task.{ Task, after }`
|
pub spaces_before_effects_keyword: &'a [CommentOrNewline<'a>],
|
||||||
Ident(&'a str, Vec<'a, &'a str>),
|
pub spaces_after_effects_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
pub spaces_after_type_name: &'a [CommentOrNewline<'a>],
|
||||||
|
pub type_name: &'a str,
|
||||||
|
pub entries: Vec<'a, Loc<TypedIdent<'a>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum ExposesEntry<'a, T> {
|
||||||
|
/// e.g. `Task`
|
||||||
|
Exposed(T),
|
||||||
|
|
||||||
// Spaces
|
// Spaces
|
||||||
SpaceBefore(&'a Imports<'a>, &'a [CommentOrNewline<'a>]),
|
SpaceBefore(&'a ExposesEntry<'a, T>, &'a [CommentOrNewline<'a>]),
|
||||||
SpaceAfter(&'a Imports<'a>, &'a [CommentOrNewline<'a>]),
|
SpaceAfter(&'a ExposesEntry<'a, T>, &'a [CommentOrNewline<'a>]),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Spaceable<'a> for ExposesEntry<'a, T> {
|
||||||
|
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
|
ExposesEntry::SpaceBefore(self, spaces)
|
||||||
|
}
|
||||||
|
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
|
ExposesEntry::SpaceAfter(self, spaces)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum ImportsEntry<'a> {
|
||||||
|
/// e.g. `Task` or `Task.{ Task, after }`
|
||||||
|
Module(ModuleName<'a>, Vec<'a, Loc<ExposesEntry<'a, &'a str>>>),
|
||||||
|
|
||||||
|
/// e.g. `base.Task` or `base.Task.{ after }` or `base.{ Task.{ Task, after } }`
|
||||||
|
Package(&'a str, Vec<'a, Loc<&'a ImportsEntry<'a>>>),
|
||||||
|
|
||||||
|
// Spaces
|
||||||
|
SpaceBefore(&'a ImportsEntry<'a>, &'a [CommentOrNewline<'a>]),
|
||||||
|
SpaceAfter(&'a ImportsEntry<'a>, &'a [CommentOrNewline<'a>]),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExposesEntry<'a, &'a str> {
|
||||||
|
pub fn as_str(&'a self) -> &'a str {
|
||||||
|
use ExposesEntry::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Exposed(string) => string,
|
||||||
|
SpaceBefore(sub_entry, _) | SpaceAfter(sub_entry, _) => sub_entry.as_str(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum TypedIdent<'a> {
|
||||||
|
/// e.g.
|
||||||
|
///
|
||||||
|
/// printLine : Str -> Effect {}
|
||||||
|
Entry {
|
||||||
|
ident: Loc<&'a str>,
|
||||||
|
spaces_before_colon: &'a [CommentOrNewline<'a>],
|
||||||
|
ann: Loc<TypeAnnotation<'a>>,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Spaces
|
||||||
|
SpaceBefore(&'a TypedIdent<'a>, &'a [CommentOrNewline<'a>]),
|
||||||
|
SpaceAfter(&'a TypedIdent<'a>, &'a [CommentOrNewline<'a>]),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum PackageEntry<'a> {
|
||||||
|
Entry {
|
||||||
|
shorthand: &'a str,
|
||||||
|
spaces_after_shorthand: &'a [CommentOrNewline<'a>],
|
||||||
|
package_or_path: Loc<PackageOrPath<'a>>,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Spaces
|
||||||
|
SpaceBefore(&'a PackageEntry<'a>, &'a [CommentOrNewline<'a>]),
|
||||||
|
SpaceAfter(&'a PackageEntry<'a>, &'a [CommentOrNewline<'a>]),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Spaceable<'a> for PackageEntry<'a> {
|
||||||
|
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
|
PackageEntry::SpaceBefore(self, spaces)
|
||||||
|
}
|
||||||
|
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
|
PackageEntry::SpaceAfter(self, spaces)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn package_entry<'a>() -> impl Parser<'a, PackageEntry<'a>> {
|
||||||
|
move |arena, state| {
|
||||||
|
// You may optionally have a package shorthand,
|
||||||
|
// e.g. "uc" in `uc: roc/unicode 1.0.0`
|
||||||
|
//
|
||||||
|
// (Indirect dependencies don't have a shorthand.)
|
||||||
|
let (opt_shorthand, state) = optional(and!(
|
||||||
|
skip_second!(lowercase_ident(), ascii_char(b':')),
|
||||||
|
space0(1)
|
||||||
|
))
|
||||||
|
.parse(arena, state)?;
|
||||||
|
let (package_or_path, state) = loc!(package_or_path()).parse(arena, state)?;
|
||||||
|
let entry = match opt_shorthand {
|
||||||
|
Some((shorthand, spaces_after_shorthand)) => PackageEntry::Entry {
|
||||||
|
shorthand,
|
||||||
|
spaces_after_shorthand,
|
||||||
|
package_or_path,
|
||||||
|
},
|
||||||
|
None => PackageEntry::Entry {
|
||||||
|
shorthand: "",
|
||||||
|
spaces_after_shorthand: &[],
|
||||||
|
package_or_path,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((entry, state))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn package_or_path<'a>() -> impl Parser<'a, PackageOrPath<'a>> {
|
||||||
|
map!(
|
||||||
|
either!(
|
||||||
|
string_literal::parse(),
|
||||||
|
and!(
|
||||||
|
package_name(),
|
||||||
|
skip_first!(one_or_more!(ascii_char(b' ')), package_version())
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|answer| {
|
||||||
|
match answer {
|
||||||
|
Either::First(str_literal) => PackageOrPath::Path(str_literal),
|
||||||
|
Either::Second((name, version)) => PackageOrPath::Package(name, version),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn package_version<'a>() -> impl Parser<'a, Version<'a>> {
|
||||||
|
move |_, _| todo!("TODO parse package version")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
use crate::ast::{
|
use crate::ast::{Attempting, CommentOrNewline, Def, Module};
|
||||||
AppHeader, Attempting, CommentOrNewline, Def, Effects, ExposesEntry, ImportsEntry,
|
|
||||||
InterfaceHeader, Module, PlatformHeader, TypedIdent,
|
|
||||||
};
|
|
||||||
use crate::blankspace::{space0, space0_around, space0_before, space1};
|
use crate::blankspace::{space0, space0_around, space0_before, space1};
|
||||||
use crate::expr::def;
|
use crate::expr::def;
|
||||||
use crate::header::{ModuleName, PackageName};
|
use crate::header::{
|
||||||
|
package_entry, AppHeader, Effects, ExposesEntry, ImportsEntry, InterfaceHeader, ModuleName,
|
||||||
|
PackageEntry, PackageName, PlatformHeader, TypedIdent,
|
||||||
|
};
|
||||||
use crate::ident::{lowercase_ident, unqualified_ident, uppercase_ident};
|
use crate::ident::{lowercase_ident, unqualified_ident, uppercase_ident};
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
self, ascii_char, ascii_string, loc, optional, peek_utf8_char, peek_utf8_char_at, unexpected,
|
self, ascii_char, ascii_string, loc, optional, peek_utf8_char, peek_utf8_char_at, unexpected,
|
||||||
unexpected_eof, ParseResult, Parser, State,
|
unexpected_eof, ParseResult, Parser, State,
|
||||||
};
|
};
|
||||||
|
use crate::string_literal;
|
||||||
use crate::type_annotation;
|
use crate::type_annotation;
|
||||||
use bumpalo::collections::{String, Vec};
|
use bumpalo::collections::{String, Vec};
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
@ -44,7 +45,7 @@ pub fn interface_header<'a>() -> impl Parser<'a, InterfaceHeader<'a>> {
|
||||||
ascii_string("interface"),
|
ascii_string("interface"),
|
||||||
and!(space1(1), loc!(module_name()))
|
and!(space1(1), loc!(module_name()))
|
||||||
),
|
),
|
||||||
and!(exposes(), imports())
|
and!(exposes_values(), imports())
|
||||||
),
|
),
|
||||||
|(
|
|(
|
||||||
(after_interface_keyword, name),
|
(after_interface_keyword, name),
|
||||||
|
@ -176,25 +177,31 @@ pub fn module_name<'a>() -> impl Parser<'a, ModuleName<'a>> {
|
||||||
fn app_header<'a>() -> impl Parser<'a, AppHeader<'a>> {
|
fn app_header<'a>() -> impl Parser<'a, AppHeader<'a>> {
|
||||||
parser::map(
|
parser::map(
|
||||||
and!(
|
and!(
|
||||||
skip_first!(ascii_string("app"), and!(space1(1), loc!(module_name()))),
|
skip_first!(
|
||||||
and!(provides(), imports())
|
ascii_string("app"),
|
||||||
|
and!(space1(1), loc!(string_literal::parse()))
|
||||||
|
),
|
||||||
|
and!(packages(), and!(imports(), provides_to()))
|
||||||
),
|
),
|
||||||
|(
|
|(
|
||||||
(after_app_keyword, name),
|
(after_app_keyword, name),
|
||||||
(
|
(packages, (((before_imports, after_imports), imports), provides)),
|
||||||
((before_provides, after_provides), provides),
|
|
||||||
((before_imports, after_imports), imports),
|
|
||||||
),
|
|
||||||
)| {
|
)| {
|
||||||
AppHeader {
|
AppHeader {
|
||||||
name,
|
name,
|
||||||
provides,
|
packages: packages.entries,
|
||||||
imports,
|
imports,
|
||||||
|
provides: provides.entries,
|
||||||
|
to: provides.to,
|
||||||
after_app_keyword,
|
after_app_keyword,
|
||||||
before_provides,
|
before_packages: packages.before_packages_keyword,
|
||||||
after_provides,
|
after_packages: packages.after_packages_keyword,
|
||||||
before_imports,
|
before_imports,
|
||||||
after_imports,
|
after_imports,
|
||||||
|
before_provides: provides.before_provides_keyword,
|
||||||
|
after_provides: provides.after_provides_keyword,
|
||||||
|
before_to: provides.before_to_keyword,
|
||||||
|
after_to: provides.after_to_keyword,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -208,31 +215,49 @@ fn platform_header<'a>() -> impl Parser<'a, PlatformHeader<'a>> {
|
||||||
ascii_string("platform"),
|
ascii_string("platform"),
|
||||||
and!(space1(1), loc!(package_name()))
|
and!(space1(1), loc!(package_name()))
|
||||||
),
|
),
|
||||||
and!(provides(), and!(requires(), and!(imports(), effects())))
|
and!(
|
||||||
|
and!(
|
||||||
|
and!(requires(), and!(exposes_modules(), packages())),
|
||||||
|
and!(imports(), provides_without_to())
|
||||||
|
),
|
||||||
|
effects()
|
||||||
|
)
|
||||||
),
|
),
|
||||||
|(
|
|(
|
||||||
(after_platform_keyword, name),
|
(after_platform_keyword, name),
|
||||||
(
|
(
|
||||||
((before_provides, after_provides), provides),
|
|
||||||
(
|
(
|
||||||
((before_requires, after_requires), requires),
|
(
|
||||||
(((before_imports, after_imports), imports), effects),
|
((before_requires, after_requires), requires),
|
||||||
|
(((before_exposes, after_exposes), exposes), packages),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
((before_imports, after_imports), imports),
|
||||||
|
((before_provides, after_provides), provides),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
effects,
|
||||||
),
|
),
|
||||||
)| {
|
)| {
|
||||||
PlatformHeader {
|
PlatformHeader {
|
||||||
name,
|
name,
|
||||||
provides,
|
|
||||||
requires,
|
requires,
|
||||||
|
exposes,
|
||||||
|
packages: packages.entries,
|
||||||
imports,
|
imports,
|
||||||
|
provides,
|
||||||
effects,
|
effects,
|
||||||
after_platform_keyword,
|
after_platform_keyword,
|
||||||
before_provides,
|
|
||||||
after_provides,
|
|
||||||
before_requires,
|
before_requires,
|
||||||
after_requires,
|
after_requires,
|
||||||
|
before_exposes,
|
||||||
|
after_exposes,
|
||||||
|
before_packages: packages.before_packages_keyword,
|
||||||
|
after_packages: packages.after_packages_keyword,
|
||||||
before_imports,
|
before_imports,
|
||||||
after_imports,
|
after_imports,
|
||||||
|
before_provides,
|
||||||
|
after_provides,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -243,39 +268,69 @@ pub fn module_defs<'a>() -> impl Parser<'a, Vec<'a, Located<Def<'a>>>> {
|
||||||
zero_or_more!(space0_around(loc(def(0)), 0))
|
zero_or_more!(space0_around(loc(def(0)), 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ProvidesTo<'a> {
|
||||||
|
entries: Vec<'a, Located<ExposesEntry<'a, &'a str>>>,
|
||||||
|
to: Located<&'a str>,
|
||||||
|
|
||||||
|
before_provides_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
after_provides_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
before_to_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
after_to_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn provides<'a>() -> impl Parser<
|
fn provides_to<'a>() -> impl Parser<'a, ProvidesTo<'a>> {
|
||||||
|
map!(
|
||||||
|
and!(
|
||||||
|
and!(skip_second!(space1(1), ascii_string("provides")), space1(1)),
|
||||||
|
and!(
|
||||||
|
collection!(
|
||||||
|
ascii_char(b'['),
|
||||||
|
loc!(map!(unqualified_ident(), ExposesEntry::Exposed)),
|
||||||
|
ascii_char(b','),
|
||||||
|
ascii_char(b']'),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
and!(
|
||||||
|
space1(1),
|
||||||
|
skip_first!(ascii_string("to"), and!(space1(1), loc!(lowercase_ident())))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|(
|
||||||
|
(before_provides_keyword, after_provides_keyword),
|
||||||
|
(entries, (before_to_keyword, (after_to_keyword, to))),
|
||||||
|
)| {
|
||||||
|
ProvidesTo {
|
||||||
|
entries,
|
||||||
|
to,
|
||||||
|
before_provides_keyword,
|
||||||
|
after_provides_keyword,
|
||||||
|
before_to_keyword,
|
||||||
|
after_to_keyword,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn provides_without_to<'a>() -> impl Parser<
|
||||||
'a,
|
'a,
|
||||||
(
|
(
|
||||||
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||||
Vec<'a, Located<ExposesEntry<'a>>>,
|
Vec<'a, Located<ExposesEntry<'a, &'a str>>>,
|
||||||
),
|
),
|
||||||
> {
|
> {
|
||||||
map!(
|
and!(
|
||||||
and!(
|
and!(skip_second!(space1(1), ascii_string("provides")), space1(1)),
|
||||||
and!(skip_second!(space1(1), ascii_string("provides")), space1(1)),
|
collection!(
|
||||||
collection!(
|
ascii_char(b'['),
|
||||||
ascii_char(b'['),
|
loc!(map!(unqualified_ident(), ExposesEntry::Exposed)),
|
||||||
loc!(exposes_entry()),
|
ascii_char(b','),
|
||||||
ascii_char(b','),
|
ascii_char(b']'),
|
||||||
ascii_char(b']'),
|
1
|
||||||
1
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
,
|
|
||||||
|((before_provides_keyword, after_provides_keyword), provides_entries| {
|
|
||||||
Provides {
|
|
||||||
provides_entries,
|
|
||||||
to,
|
|
||||||
before_provides_keyword,
|
|
||||||
after_provides_keyword,
|
|
||||||
before_to_keyword,
|
|
||||||
after_to_keyword,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -299,18 +354,18 @@ fn requires<'a>() -> impl Parser<
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn exposes<'a>() -> impl Parser<
|
fn exposes_values<'a>() -> impl Parser<
|
||||||
'a,
|
'a,
|
||||||
(
|
(
|
||||||
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||||
Vec<'a, Located<ExposesEntry<'a>>>,
|
Vec<'a, Located<ExposesEntry<'a, &'a str>>>,
|
||||||
),
|
),
|
||||||
> {
|
> {
|
||||||
and!(
|
and!(
|
||||||
and!(skip_second!(space1(1), ascii_string("exposes")), space1(1)),
|
and!(skip_second!(space1(1), ascii_string("exposes")), space1(1)),
|
||||||
collection!(
|
collection!(
|
||||||
ascii_char(b'['),
|
ascii_char(b'['),
|
||||||
loc!(exposes_entry()),
|
loc!(map!(unqualified_ident(), ExposesEntry::Exposed)),
|
||||||
ascii_char(b','),
|
ascii_char(b','),
|
||||||
ascii_char(b']'),
|
ascii_char(b']'),
|
||||||
1
|
1
|
||||||
|
@ -318,6 +373,56 @@ fn exposes<'a>() -> impl Parser<
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn exposes_modules<'a>() -> impl Parser<
|
||||||
|
'a,
|
||||||
|
(
|
||||||
|
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||||
|
Vec<'a, Located<ExposesEntry<'a, ModuleName<'a>>>>,
|
||||||
|
),
|
||||||
|
> {
|
||||||
|
and!(
|
||||||
|
and!(skip_second!(space1(1), ascii_string("exposes")), space1(1)),
|
||||||
|
collection!(
|
||||||
|
ascii_char(b'['),
|
||||||
|
loc!(map!(module_name(), ExposesEntry::Exposed)),
|
||||||
|
ascii_char(b','),
|
||||||
|
ascii_char(b']'),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Packages<'a> {
|
||||||
|
entries: Vec<'a, Located<PackageEntry<'a>>>,
|
||||||
|
|
||||||
|
before_packages_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
after_packages_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn packages<'a>() -> impl Parser<'a, Packages<'a>> {
|
||||||
|
map!(
|
||||||
|
and!(
|
||||||
|
and!(skip_second!(space1(1), ascii_string("packages")), space1(1)),
|
||||||
|
collection!(
|
||||||
|
ascii_char(b'{'),
|
||||||
|
loc!(package_entry()),
|
||||||
|
ascii_char(b','),
|
||||||
|
ascii_char(b'}'),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|((before_packages_keyword, after_packages_keyword), entries)| {
|
||||||
|
Packages {
|
||||||
|
entries,
|
||||||
|
before_packages_keyword,
|
||||||
|
after_packages_keyword,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn imports<'a>() -> impl Parser<
|
fn imports<'a>() -> impl Parser<
|
||||||
'a,
|
'a,
|
||||||
|
@ -397,11 +502,6 @@ fn typed_ident<'a>() -> impl Parser<'a, TypedIdent<'a>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn exposes_entry<'a>() -> impl Parser<'a, ExposesEntry<'a>> {
|
|
||||||
map!(unqualified_ident(), ExposesEntry::Ident)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
|
fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena!(
|
||||||
|
@ -413,7 +513,7 @@ fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
|
||||||
ascii_char(b'.'),
|
ascii_char(b'.'),
|
||||||
collection!(
|
collection!(
|
||||||
ascii_char(b'{'),
|
ascii_char(b'{'),
|
||||||
loc!(exposes_entry()),
|
loc!(map!(unqualified_ident(), ExposesEntry::Exposed)),
|
||||||
ascii_char(b','),
|
ascii_char(b','),
|
||||||
ascii_char(b'}'),
|
ascii_char(b'}'),
|
||||||
1
|
1
|
||||||
|
@ -423,7 +523,7 @@ fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
|
||||||
|arena,
|
|arena,
|
||||||
(module_name, opt_values): (
|
(module_name, opt_values): (
|
||||||
ModuleName<'a>,
|
ModuleName<'a>,
|
||||||
Option<Vec<'a, Located<ExposesEntry<'a>>>>
|
Option<Vec<'a, Located<ExposesEntry<'a, &'a str>>>>
|
||||||
)| {
|
)| {
|
||||||
let exposed_values = opt_values.unwrap_or_else(|| Vec::new_in(arena));
|
let exposed_values = opt_values.unwrap_or_else(|| Vec::new_in(arena));
|
||||||
|
|
||||||
|
|
|
@ -1037,7 +1037,11 @@ macro_rules! one_or_more {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err((_, new_state)) => Err(unexpected_eof(0, new_state.attempting, new_state)),
|
Err((_, new_state)) => Err($crate::parser::unexpected_eof(
|
||||||
|
0,
|
||||||
|
new_state.attempting,
|
||||||
|
new_state,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1083,9 +1087,9 @@ macro_rules! either {
|
||||||
let original_attempting = state.attempting;
|
let original_attempting = state.attempting;
|
||||||
|
|
||||||
match $p1.parse(arena, state) {
|
match $p1.parse(arena, state) {
|
||||||
Ok((output, state)) => Ok((Either::First(output), state)),
|
Ok((output, state)) => Ok(($crate::parser::Either::First(output), state)),
|
||||||
Err((_, state)) => match $p2.parse(arena, state) {
|
Err((_, state)) => match $p2.parse(arena, state) {
|
||||||
Ok((output, state)) => Ok((Either::Second(output), state)),
|
Ok((output, state)) => Ok(($crate::parser::Either::Second(output), state)),
|
||||||
Err((fail, state)) => Err((
|
Err((fail, state)) => Err((
|
||||||
Fail {
|
Fail {
|
||||||
attempting: original_attempting,
|
attempting: original_attempting,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue