parse records inside patterns and add REUSE headers

This commit is contained in:
Alain Emilia Anna Zscheile 2023-09-25 16:23:03 +02:00
parent 23fcbb4e14
commit 2935baf77f
4 changed files with 63 additions and 44 deletions

View file

@ -1,3 +1,9 @@
/*
* SPDX-FileCopyrightText: 2023 Alain Zscheile <fogti+devel@ytrizja.de>
*
* SPDX-License-Identifier: Apache-2.0
*/
//use bitflags::bitflags;
pub mod parser;
use parser::{
@ -7,36 +13,14 @@ use parser::{
#[derive(Clone, Debug)]
pub enum Pattern {
Ident(Box<str>),
Record(Record<Pattern>),
TyRecord(Record<Pattern>),
Ignore,
}
/*
bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct DefinFlags: u8 {
const PUBLIC = 0b00000001;
const MUTABLE = 0b00000010;
}
}
#[derive(Clone, Debug)]
pub struct Defin {
pub flags: DefinFlags,
pub value: Expr,
pub name: Box<str>,
}
#[derive(Clone, Debug)]
pub struct Block {
pub defs: Box<[Defin]>,
pub res: Box<Expr>,
}
*/
#[derive(Clone, Debug)]
pub struct Record {
pub fields: Vec<(Option<Box<str>>, Expr)>,
pub struct Record<V> {
pub fields: Vec<(Option<Box<str>>, V)>,
}
#[derive(Clone, Debug)]
@ -71,20 +55,22 @@ pub enum Expr {
Ref(usize),
Record(Record),
TyRecord(Record),
Record(Record<Expr>),
TyRecord(Record<Expr>),
Select {
prim: Box<Expr>,
then: Vec<Box<str>>,
},
//Block(Block),
}
impl Pattern {
pub fn push_to(&self, env: &mut ParseEnv<'_>) {
match self {
Pattern::Ident(i) => env.names.push(i.clone()),
Pattern::Record(xs) | Pattern::TyRecord(xs) => {
xs.fields[..].iter().for_each(|i| i.1.push_to(env));
}
Pattern::Ignore => {}
}
}
@ -94,16 +80,21 @@ impl Pattern {
Pattern::Ident(_) => {
env.names.pop();
}
Pattern::Record(xs) | Pattern::TyRecord(xs) => {
xs.fields[..].iter().for_each(|i| i.1.pop_from(env));
}
Pattern::Ignore => {}
}
}
pub fn in_this<T>(&self, env: &mut ParseEnv<'_>, f: impl FnOnce(&mut ParseEnv<'_>) -> T) -> T {
let orig_height = env.names.len();
self.push_to(env);
let height = env.names.len();
let ret = f(env);
assert_eq!(env.names.len(), height);
self.pop_from(env);
assert_eq!(env.names.len(), orig_height);
ret
}
}
@ -117,14 +108,27 @@ impl MaybeParse for Pattern {
None => return Ok(None),
Some(x) => x,
};
Ok(match kind {
Tok::PatOut(i) => Some(Pattern::Ident(i)),
Tok::PatIgnore => Some(Pattern::Ignore),
Ok(Some(match kind {
Tok::PatOut(i) => Pattern::Ident(i),
Tok::PatIgnore => Pattern::Ignore,
Tok::Caret | Tok::Dot => {
let is_tylvl = kind == Tok::Caret;
if let Some(r) = Record::<Pattern>::maybe_parse(env)? {
if is_tylvl {
Pattern::TyRecord(r)
} else {
Pattern::Record(r)
}
} else {
let Token { kind, offset } = env.lxr.next_in_noeof("[^.]pattern")?;
return Err(parser::unexpected_token(offset, kind, "[^.]pattern"));
}
}
_ => {
env.lxr = backup;
None
return Ok(None);
}
})
}))
}
}
@ -147,7 +151,7 @@ impl MaybeParse for FullPattern {
}
}
impl MaybeParse for Record {
impl<T: Parse> MaybeParse for Record<T> {
const DFL_CTX: &'static str = "record";
fn maybe_parse(env: &mut ParseEnv<'_>) -> Result<Option<Self>, Perr> {
@ -180,7 +184,7 @@ impl MaybeParse for Record {
env.lxr = lxrbak;
}
let expr = Expr::parse(env)?;
let expr = T::parse(env)?;
env.lxr.expect(Tok::SemiColon, "record ;")?;
fields.push((name, expr));
}

View file

@ -1,3 +1,9 @@
/*
* SPDX-FileCopyrightText: 2023 Alain Zscheile <fogti+devel@ytrizja.de>
*
* SPDX-License-Identifier: Apache-2.0
*/
use super::{Error, ErrorKind};
use core::fmt;

View file

@ -1,3 +1,9 @@
/*
* SPDX-FileCopyrightText: 2023 Alain Zscheile <fogti+devel@ytrizja.de>
*
* SPDX-License-Identifier: Apache-2.0
*/
use core::fmt;
use miette::Diagnostic;

View file

@ -1,8 +1,11 @@
λ $blti → λ $maybe → μ $simpl → .{
.stack_ds = λ $T → μ $sdst → maybe ^{ T; sdst; };
.stack = λ $T → μ $simpl2 → .{
.sdst = simpl.stack_ds T;
.nil = simpl2.sdst.none blti.unit;
.push = λ $xs → λ $x → simpl2.sdst.some (blti.box .{ x; xs; });
};
}
λ $blti → λ $maybe →
let $stack_ds = λ $T → μ $sdst → maybe ^{ T; sdst; };
.{
.stack = λ $T →
let $sdst = stack_ds T;
.{
.sdst = sdst;
.nil = sdst.none blti.unit;
.push = λ $xs → λ $x → sdst.some (blti.box .{ x; xs; });
};
}