put record stuff into separate file
This commit is contained in:
parent
bbebc9a518
commit
5e776b963d
|
@ -13,6 +13,9 @@ use parser::{
|
|||
mod pat;
|
||||
pub use pat::{FullPattern, Pattern};
|
||||
|
||||
mod record;
|
||||
pub use record::{Record, RecordEntry};
|
||||
|
||||
pub mod typeck;
|
||||
|
||||
use core::cmp;
|
||||
|
@ -63,12 +66,6 @@ impl<'a> From<&'a EvEqSourceSpan> for SourceSpan {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Record<V> {
|
||||
pub span: EvEqSourceSpan,
|
||||
pub fields: Vec<(Option<Box<str>>, V)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Expr {
|
||||
TyTy,
|
||||
|
@ -115,94 +112,6 @@ pub enum Expr {
|
|||
},
|
||||
}
|
||||
|
||||
impl<T: Parse> MaybeParse for Record<T> {
|
||||
const DFL_CTX: &'static str = "record";
|
||||
|
||||
fn maybe_parse(env: &mut ParseEnv<'_>) -> Result<Option<Self>, Perr> {
|
||||
let start_offset = match env.lxr.got(Tok::LBrace) {
|
||||
None => return Ok(None),
|
||||
Some(x) => x,
|
||||
};
|
||||
|
||||
let mut fields: Vec<(Option<Box<str>>, _)> = Vec::new();
|
||||
|
||||
loop {
|
||||
let lxrbak = env.lxr.clone();
|
||||
let name = {
|
||||
let Token { kind, offset } = env.lxr.next_in_noeof("record")?;
|
||||
|
||||
if let Tok::DotIdent(i) = kind {
|
||||
if env.lxr.expect(Tok::Assign, "record =").is_ok() {
|
||||
if fields
|
||||
.iter()
|
||||
.find(|(j, _)| j.as_ref() == Some(&i))
|
||||
.is_some()
|
||||
{
|
||||
env.lxr = lxrbak;
|
||||
return Err(Perr {
|
||||
offset: usize::try_from(offset).unwrap(),
|
||||
kind: Pek::RcdDupIdent(i),
|
||||
});
|
||||
}
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if let Tok::RBrace = kind {
|
||||
env.lxr = lxrbak;
|
||||
break;
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if name.is_none() {
|
||||
// backtrack
|
||||
env.lxr = lxrbak;
|
||||
}
|
||||
|
||||
let expr = T::parse(env)?;
|
||||
env.lxr.expect(Tok::SemiColon, "record ;")?;
|
||||
fields.push((name, expr));
|
||||
}
|
||||
|
||||
let end_offset = env.lxr.expect(Tok::RBrace, "record")?;
|
||||
Ok(Some(Record {
|
||||
span: (usize::try_from(start_offset).unwrap()..usize::try_from(end_offset).unwrap())
|
||||
.into(),
|
||||
fields,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum RecordEntry<'a> {
|
||||
Name(&'a str),
|
||||
Ref(usize),
|
||||
}
|
||||
|
||||
impl<T> Record<T> {
|
||||
pub fn lookup_mut(&mut self, name: RecordEntry<'_>) -> Option<&mut T> {
|
||||
match name {
|
||||
RecordEntry::Name(name) => self
|
||||
.fields
|
||||
.iter_mut()
|
||||
.find(|(j, _)| j.as_ref().map(|x| &**x) == Some(name)),
|
||||
RecordEntry::Ref(i) => self.fields.get_mut(i),
|
||||
}
|
||||
.map(|x| &mut x.1)
|
||||
}
|
||||
|
||||
pub fn lookup(&self, name: RecordEntry<'_>) -> Option<&T> {
|
||||
match name {
|
||||
RecordEntry::Name(name) => self
|
||||
.fields
|
||||
.iter()
|
||||
.find(|(j, _)| j.as_ref().map(|x| &**x) == Some(name)),
|
||||
RecordEntry::Ref(i) => self.fields.get(i),
|
||||
}
|
||||
.map(|x| &x.1)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_minexpr(env: &mut ParseEnv<'_>) -> Result<Expr, Perr> {
|
||||
let Token {
|
||||
offset: fi_offset,
|
||||
|
|
104
crates/yn-qgy4hbz-core/src/record.rs
Normal file
104
crates/yn-qgy4hbz-core/src/record.rs
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Alain Zscheile <fogti+devel@ytrizja.de>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
use crate::parser::{
|
||||
Env as ParseEnv, Error as Perr, ErrorKind as Pek, MaybeParse, Parse, Token, TokenKind as Tok,
|
||||
};
|
||||
use crate::EvEqSourceSpan;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Record<V> {
|
||||
pub span: EvEqSourceSpan,
|
||||
pub fields: Vec<(Option<Box<str>>, V)>,
|
||||
}
|
||||
|
||||
impl<T: Parse> MaybeParse for Record<T> {
|
||||
const DFL_CTX: &'static str = "record";
|
||||
|
||||
fn maybe_parse(env: &mut ParseEnv<'_>) -> Result<Option<Self>, Perr> {
|
||||
let start_offset = match env.lxr.got(Tok::LBrace) {
|
||||
None => return Ok(None),
|
||||
Some(x) => x,
|
||||
};
|
||||
|
||||
let mut fields: Vec<(Option<Box<str>>, _)> = Vec::new();
|
||||
|
||||
loop {
|
||||
let lxrbak = env.lxr.clone();
|
||||
let name = {
|
||||
let Token { kind, offset } = env.lxr.next_in_noeof("record")?;
|
||||
|
||||
if let Tok::DotIdent(i) = kind {
|
||||
if env.lxr.expect(Tok::Assign, "record =").is_ok() {
|
||||
if fields
|
||||
.iter()
|
||||
.find(|(j, _)| j.as_ref() == Some(&i))
|
||||
.is_some()
|
||||
{
|
||||
env.lxr = lxrbak;
|
||||
return Err(Perr {
|
||||
offset: usize::try_from(offset).unwrap(),
|
||||
kind: Pek::RcdDupIdent(i),
|
||||
});
|
||||
}
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if let Tok::RBrace = kind {
|
||||
env.lxr = lxrbak;
|
||||
break;
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if name.is_none() {
|
||||
// backtrack
|
||||
env.lxr = lxrbak;
|
||||
}
|
||||
|
||||
let expr = T::parse(env)?;
|
||||
env.lxr.expect(Tok::SemiColon, "record ;")?;
|
||||
fields.push((name, expr));
|
||||
}
|
||||
|
||||
let end_offset = env.lxr.expect(Tok::RBrace, "record")?;
|
||||
Ok(Some(Record {
|
||||
span: (usize::try_from(start_offset).unwrap()..usize::try_from(end_offset).unwrap())
|
||||
.into(),
|
||||
fields,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum RecordEntry<'a> {
|
||||
Name(&'a str),
|
||||
Ref(usize),
|
||||
}
|
||||
|
||||
impl<T> Record<T> {
|
||||
pub fn lookup_mut(&mut self, name: RecordEntry<'_>) -> Option<&mut T> {
|
||||
match name {
|
||||
RecordEntry::Name(name) => self
|
||||
.fields
|
||||
.iter_mut()
|
||||
.find(|(j, _)| j.as_ref().map(|x| &**x) == Some(name)),
|
||||
RecordEntry::Ref(i) => self.fields.get_mut(i),
|
||||
}
|
||||
.map(|x| &mut x.1)
|
||||
}
|
||||
|
||||
pub fn lookup(&self, name: RecordEntry<'_>) -> Option<&T> {
|
||||
match name {
|
||||
RecordEntry::Name(name) => self
|
||||
.fields
|
||||
.iter()
|
||||
.find(|(j, _)| j.as_ref().map(|x| &**x) == Some(name)),
|
||||
RecordEntry::Ref(i) => self.fields.get(i),
|
||||
}
|
||||
.map(|x| &x.1)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue