mrwy57u: some more

This commit is contained in:
Alain Zscheile 2023-10-16 04:39:22 +02:00
parent 1a64b640d6
commit 3d35fa98ae
6 changed files with 109 additions and 75 deletions

View file

@ -4,15 +4,30 @@
* SPDX-License-Identifier: Apache-2.0
*/
use crate::Lambda;
use crate::{Lambda, Record, Use};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TyLit {
Type,
Bool,
U8,
I8,
Usize,
Isize,
}
#[derive(Clone, Debug)]
pub enum Expr {
TyLit(TyLit),
Integer(usize),
Use(Use),
RefUse(Use),
Lambda(Lambda),
TyLambda(Lambda),
Apply {
lam: Box<Expr>,
args: Vec<Expr>,
},
Apply { lam: Box<Expr>, args: Vec<Expr> },
Record(Record<Expr>),
TyRecord(Record<Expr>),
}

View file

@ -5,7 +5,15 @@
*/
use std::sync::Arc;
use parser::{
lex::{self, Token, TokenKind as Tok},
Env as ParseEnv, Error as Perr, ErrorCtx as PeCtx, ErrorKind as Pek, MaybeParse, Parse,
Result as Pres,
};
pub use yn_mrwy57u_parser as parser;
use yn_utils::none_up;
mod expr;
mod pat;
mod record;
@ -27,3 +35,48 @@ pub struct TaggedIdent {
pub span: EvEqSourceSpan,
pub name: Arc<str>,
}
#[derive(Clone, Debug)]
pub struct Use {
pub root: TaggedIdent,
pub dots: Vec<TaggedIdent>,
}
impl parser::MaybeParse for Use {
const DFL_CTX: PeCtx = PeCtx::Use;
fn maybe_parse(env: &mut ParseEnv<'_>) -> Pres<Option<Self>> {
let mut lxrnxt = env.lxr.clone();
let root = {
let Token { span, kind } = none_up!(lxrnxt.next())?;
if let Tok::Ident(name) = kind {
TaggedIdent { span, name }
} else {
return Ok(None);
}
};
env.lxr = lxrnxt.clone();
let mut dots = Vec::new();
loop {
let Token { span, kind } = match lxrnxt.next() {
None => break,
Some(Err(e)) => {
env.lxr = lxrnxt;
return Err(e);
}
Some(Ok(x)) => x,
};
if let Tok::DotIdent(name) = kind {
dots.push(TaggedIdent { span, name });
env.lxr = lxrnxt.clone();
} else {
break;
}
}
Ok(Some(Use { root, dots }))
}
}

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
use crate::parser::{MaybeParse, Error, ErrorKind as Ek, ErrorCtx, Env as ParseEnv, lex};
use crate::parser::{lex, Env as ParseEnv, Error, ErrorCtx, ErrorKind as Ek, MaybeParse};
use std::sync::Arc;
use yn_utils::EvEqSourceSpan;
@ -19,7 +19,13 @@ pub enum Pattern {
impl Pattern {
pub fn alloc_slots(&self) -> usize {
match self {
Pattern::Name(_, x) => if x.is_empty() { 0 } else { 1 },
Pattern::Name(_, x) => {
if x.is_empty() {
0
} else {
1
}
}
}
}
}

View file

@ -4,11 +4,15 @@
* SPDX-License-Identifier: Apache-2.0
*/
use crate::parser::{Env as ParseEnv, Result as Pres, Error as Perr, ErrorCtx as PeCtx, ErrorKind as Pek, MaybeParse, Parse, lex::{self, Token, TokenKind as Tok}};
use crate::parser::{
lex::{self, Token, TokenKind as Tok},
Env as ParseEnv, Error as Perr, ErrorCtx as PeCtx, ErrorKind as Pek, MaybeParse, Parse,
Result as Pres,
};
use crate::{Expr, TaggedIdent};
use std::collections::BTreeMap;
use std::sync::Arc;
use yn_utils::{EvEqSourceSpan, none_up};
use yn_utils::{none_up, EvEqSourceSpan};
#[derive(Clone, Debug)]
pub struct Record<V> {
@ -16,11 +20,7 @@ pub struct Record<V> {
pub fields: Vec<(Option<Arc<str>>, V)>,
}
#[derive(Clone, Debug)]
pub struct ModSelect {
pub root: TaggedIdent,
pub dots: Vec<TaggedIdent>,
}
pub type ModSelect = crate::Use;
#[derive(Clone, Debug)]
pub enum MFieldContent {
@ -46,48 +46,6 @@ pub struct Module {
pub registers: Vec<RegisterEnt>,
}
impl MaybeParse for ModSelect {
const DFL_CTX: PeCtx = PeCtx::ModSelect;
fn maybe_parse(env: &mut ParseEnv<'_>) -> Pres<Option<Self>> {
let mut lxrnxt = env.lxr.clone();
let root = {
let Token { span, kind } = none_up!(lxrnxt.next())?;
if let Tok::Ident(name) = kind {
TaggedIdent {
span,
name,
}
} else {
return Ok(None);
}
};
env.lxr = lxrnxt.clone();
let mut dots = Vec::new();
loop {
let Token { span, kind } = match lxrnxt.next() {
None => break,
Some(Err(e)) => {
env.lxr = lxrnxt;
return Err(e);
}
Some(Ok(x)) => x,
};
if let Tok::DotIdent(name) = kind {
dots.push(TaggedIdent { span, name });
env.lxr = lxrnxt.clone();
} else {
break;
}
}
Ok(Some(ModSelect { root, dots }))
}
}
impl<V: Parse> MaybeParse for Record<V> {
const DFL_CTX: PeCtx = PeCtx::Record;
@ -108,19 +66,19 @@ impl<V: Parse> MaybeParse for Record<V> {
match kind {
Tok::DotIdent(i) => {
if env.lxr.expect(Tok::Assign, PeCtx::Record).is_ok() {
if fields.iter().any(|(j, _)| j.as_ref() == Some(&i)) {
return Err(Perr {
span,
kind: Pek::RecordDupIdent(i),
});
if env.lxr.expect(Tok::Assign, PeCtx::Record).is_ok() {
if fields.iter().any(|(j, _)| j.as_ref() == Some(&i)) {
return Err(Perr {
span,
kind: Pek::RecordDupIdent(i),
});
}
// "fronttrack"
env.lxr = lxrnxt;
Some(i)
} else {
None
}
// "fronttrack"
env.lxr = lxrnxt;
Some(i)
} else {
None
}
}
Tok::RBrace => break,
_ => None,
@ -133,7 +91,7 @@ impl<V: Parse> MaybeParse for Record<V> {
let end_span = env.lxr.expect(Tok::RBrace, PeCtx::Record)?;
Ok(Some(Record {
span: (start_span.offset() .. end_span.offset() + end_span.len()).into(),
span: (start_span.offset()..end_span.offset() + end_span.len()).into(),
fields,
}))
}

View file

@ -125,7 +125,7 @@ pub enum ErrorCtx {
String,
Pattern,
Record,
ModSelect,
Use,
}
impl fmt::Display for ErrorCtx {
@ -135,7 +135,7 @@ impl fmt::Display for ErrorCtx {
ErrorCtx::String => "string",
ErrorCtx::Pattern => "pattern",
ErrorCtx::Record => "record",
ErrorCtx::ModSelect => "module-field-select",
ErrorCtx::Use => "use (selection)",
})
}
}

View file

@ -89,8 +89,10 @@ pub fn try_consume_ident(slb: &mut StrLexerBase<'_>) -> Option<Arc<str>> {
#[macro_export]
macro_rules! none_up {
($x:expr) => { match $x {
None => return Ok(None),
Some(x) => x,
} }
($x:expr) => {
match $x {
None => return Ok(None),
Some(x) => x,
}
};
}