mrwy57u: some more
This commit is contained in:
parent
1a64b640d6
commit
3d35fa98ae
6 changed files with 109 additions and 75 deletions
|
@ -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>),
|
||||
}
|
||||
|
|
|
@ -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 }))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -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)",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue