rust: 'official' yanais record and pattern syntax

This commit is contained in:
Alain Emilia Anna Zscheile 2023-11-03 15:28:03 +01:00
parent adc5e07bfd
commit ab931de08f
4 changed files with 21 additions and 16 deletions

View file

@ -9,6 +9,7 @@ use miette::{Diagnostic, SourceSpan};
use std::sync::Arc; use std::sync::Arc;
pub mod lex; pub mod lex;
pub mod pat;
pub mod record; pub mod record;
#[macro_export] #[macro_export]
@ -251,8 +252,8 @@ impl<'a, Kw> Env<'a, Kw> {
} }
} }
pub trait Keywords: Sized + core::str::FromStr {} pub trait Keywords: Sized + core::cmp::PartialEq + core::str::FromStr {}
impl<T: Sized + core::str::FromStr> Keywords for T {} impl<T: Sized + core::cmp::PartialEq + core::str::FromStr> Keywords for T {}
pub trait Parse<Kw: Keywords>: Sized { pub trait Parse<Kw: Keywords>: Sized {
fn parse(env: &mut Env<'_, Kw>) -> Result<Self>; fn parse(env: &mut Env<'_, Kw>) -> Result<Self>;

View file

@ -4,27 +4,31 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
use crate::parser::{lex, Env as ParseEnv, Error, ErrorCtx, MaybeParse, ParseDefaultCtx}; use crate::{
lex, record::Record, Env as ParseEnv, Error, ErrorCtx, EvEqSourceSpan, Keywords, MaybeParse,
Parse, ParseDefaultCtx,
};
use std::sync::Arc; use std::sync::Arc;
use yanais_syntax::EvEqSourceSpan;
// infallible patterns // infallible patterns
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum Pattern { pub enum Pattern {
Ignore(EvEqSourceSpan),
Name(EvEqSourceSpan, Arc<str>), Name(EvEqSourceSpan, Arc<str>),
// Record(Record<Pattern>), Record(Record<Pattern>),
} }
impl Pattern { impl Pattern {
pub fn alloc_slots(&self) -> usize { pub fn alloc_slots(&self) -> usize {
match self { match self {
Pattern::Ignore(_) => 0,
Pattern::Name(_, x) => { Pattern::Name(_, x) => {
if x.is_empty() { assert!(!x.is_empty());
0
} else {
1 1
} }
Pattern::Record(rcd) => {
rcd.fields.iter().map(|(_, i)| i.alloc_slots()).sum()
} }
} }
} }
@ -34,8 +38,8 @@ impl ParseDefaultCtx for Pattern {
const DFL_CTX: ErrorCtx = ErrorCtx::Pattern; const DFL_CTX: ErrorCtx = ErrorCtx::Pattern;
} }
impl MaybeParse<lex::Kw> for Pattern { impl<Kw: Keywords> MaybeParse<Kw> for Pattern {
fn maybe_parse(env: &mut ParseEnv<'_>) -> Result<Option<Self>, Error> { fn maybe_parse(env: &mut ParseEnv<'_, Kw>) -> Result<Option<Self>, Error> {
let mut nxtlxr = env.lxr.clone(); let mut nxtlxr = env.lxr.clone();
let lex::Token { let lex::Token {
kind, kind,
@ -47,7 +51,9 @@ impl MaybeParse<lex::Kw> for Pattern {
use lex::TokenKind as Tk; use lex::TokenKind as Tk;
let ret = match kind { let ret = match kind {
Tk::PatOut(nam) if nam.is_empty() => Pattern::Ignore(tok_span),
Tk::PatOut(nam) => Pattern::Name(tok_span, nam), Tk::PatOut(nam) => Pattern::Name(tok_span, nam),
Tk::LBrace => return Record::parse(env).map(|i| Some(Pattern::Record(i))),
_ => return Ok(None), _ => return Ok(None),
}; };
env.lxr = nxtlxr; env.lxr = nxtlxr;

View file

@ -13,7 +13,7 @@ use crate::{
Keywords, MaybeParse, Parse, ParseDefaultCtx, Result as Pres, Keywords, MaybeParse, Parse, ParseDefaultCtx, Result as Pres,
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug, PartialEq)]
pub struct Record<V> { pub struct Record<V> {
pub span: EvEqSourceSpan, pub span: EvEqSourceSpan,
pub fields: Vec<(Option<Arc<str>>, V)>, pub fields: Vec<(Option<Arc<str>>, V)>,

View file

@ -58,12 +58,10 @@ pub mod parser {
use parser::lex::Kw; use parser::lex::Kw;
mod expr; mod expr;
mod pat;
mod record; mod record;
pub use expr::Expr; pub use expr::Expr;
pub use pat::Pattern; pub use yanais_syntax::{pat::Pattern, record::Record, EvEqSourceSpan};
pub use yanais_syntax::{record::Record, EvEqSourceSpan};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Lambda { pub struct Lambda {