rust: 'official' yanais record and pattern syntax

This commit is contained in:
Alain 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;
pub mod lex;
pub mod pat;
pub mod record;
#[macro_export]
@ -251,8 +252,8 @@ impl<'a, Kw> Env<'a, Kw> {
}
}
pub trait Keywords: Sized + core::str::FromStr {}
impl<T: Sized + core::str::FromStr> Keywords for T {}
pub trait Keywords: Sized + core::cmp::PartialEq + core::str::FromStr {}
impl<T: Sized + core::cmp::PartialEq + core::str::FromStr> Keywords for T {}
pub trait Parse<Kw: Keywords>: Sized {
fn parse(env: &mut Env<'_, Kw>) -> Result<Self>;

View file

@ -4,27 +4,31 @@
* 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 yanais_syntax::EvEqSourceSpan;
// infallible patterns
#[derive(Clone, Debug, PartialEq)]
pub enum Pattern {
Ignore(EvEqSourceSpan),
Name(EvEqSourceSpan, Arc<str>),
// Record(Record<Pattern>),
Record(Record<Pattern>),
}
impl Pattern {
pub fn alloc_slots(&self) -> usize {
match self {
Pattern::Ignore(_) => 0,
Pattern::Name(_, x) => {
if x.is_empty() {
0
} else {
1
}
assert!(!x.is_empty());
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;
}
impl MaybeParse<lex::Kw> for Pattern {
fn maybe_parse(env: &mut ParseEnv<'_>) -> Result<Option<Self>, Error> {
impl<Kw: Keywords> MaybeParse<Kw> for Pattern {
fn maybe_parse(env: &mut ParseEnv<'_, Kw>) -> Result<Option<Self>, Error> {
let mut nxtlxr = env.lxr.clone();
let lex::Token {
kind,
@ -47,7 +51,9 @@ impl MaybeParse<lex::Kw> for Pattern {
use lex::TokenKind as Tk;
let ret = match kind {
Tk::PatOut(nam) if nam.is_empty() => Pattern::Ignore(tok_span),
Tk::PatOut(nam) => Pattern::Name(tok_span, nam),
Tk::LBrace => return Record::parse(env).map(|i| Some(Pattern::Record(i))),
_ => return Ok(None),
};
env.lxr = nxtlxr;

View file

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

View file

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