ast: Add use, tackle remaining low-hanging fruit
This commit is contained in:
46
src/ast.rs
46
src/ast.rs
@@ -45,6 +45,19 @@ pub enum Literal {
|
|||||||
Str(String),
|
Str(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A compound import declaration
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum Use {
|
||||||
|
/// "*"
|
||||||
|
Glob,
|
||||||
|
/// Identifier
|
||||||
|
Name(String),
|
||||||
|
/// Identifier :: Use
|
||||||
|
Path(String, Box<Use>),
|
||||||
|
/// { Use, * }
|
||||||
|
Tree(Vec<Use>),
|
||||||
|
}
|
||||||
|
|
||||||
/// Binding patterns for each kind of matchable value.
|
/// Binding patterns for each kind of matchable value.
|
||||||
///
|
///
|
||||||
/// This covers both patterns in Match expressions, and type annotations.
|
/// This covers both patterns in Match expressions, and type annotations.
|
||||||
@@ -71,6 +84,8 @@ pub enum Pat {
|
|||||||
/// Operators on lists of patterns
|
/// Operators on lists of patterns
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum PatOp {
|
pub enum PatOp {
|
||||||
|
/// Changes the binding mode to "mutable"
|
||||||
|
Mut,
|
||||||
/// Matches the dereference of a pointer (`&pat`)
|
/// Matches the dereference of a pointer (`&pat`)
|
||||||
Ref,
|
Ref,
|
||||||
/// Matches a partial decomposition (`..rest`) or upper-bounded range (`..100`)
|
/// Matches a partial decomposition (`..rest`) or upper-bounded range (`..100`)
|
||||||
@@ -83,6 +98,8 @@ pub enum PatOp {
|
|||||||
Tuple,
|
Tuple,
|
||||||
/// Matches the elements of a slice or array
|
/// Matches the elements of a slice or array
|
||||||
Slice,
|
Slice,
|
||||||
|
/// Matches a constant-size slice with repeating elements
|
||||||
|
Arrep,
|
||||||
/// Matches a type annotation or struct member
|
/// Matches a type annotation or struct member
|
||||||
Typed,
|
Typed,
|
||||||
/// Matches a function signature
|
/// Matches a function signature
|
||||||
@@ -96,6 +113,7 @@ pub enum PatOp {
|
|||||||
/// let Pat (= Expr (else Expr)?)?
|
/// let Pat (= Expr (else Expr)?)?
|
||||||
/// const Pat (= Expr (else Expr)?)?
|
/// const Pat (= Expr (else Expr)?)?
|
||||||
/// static Pat (= Expr (else Expr)?)?
|
/// static Pat (= Expr (else Expr)?)?
|
||||||
|
/// type Pat (= Expr)?
|
||||||
/// fn Pat Expr
|
/// fn Pat Expr
|
||||||
/// mod Pat Expr
|
/// mod Pat Expr
|
||||||
/// impl Pat Expr
|
/// impl Pat Expr
|
||||||
@@ -112,6 +130,8 @@ pub enum BindKind {
|
|||||||
Const,
|
Const,
|
||||||
/// A `static Pat = Expr` binding
|
/// A `static Pat = Expr` binding
|
||||||
Static,
|
Static,
|
||||||
|
/// A type-alias binding
|
||||||
|
Type,
|
||||||
/// A `fn Pat Expr` binding
|
/// A `fn Pat Expr` binding
|
||||||
Fn,
|
Fn,
|
||||||
/// A `mod Pat Expr` binding
|
/// A `mod Pat Expr` binding
|
||||||
@@ -143,7 +163,6 @@ pub struct Typedef(pub TypedefKind, pub Pat);
|
|||||||
/// The type of type being defined
|
/// The type of type being defined
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum TypedefKind {
|
pub enum TypedefKind {
|
||||||
Alias,
|
|
||||||
Struct,
|
Struct,
|
||||||
Enum,
|
Enum,
|
||||||
}
|
}
|
||||||
@@ -157,6 +176,8 @@ pub enum Expr<A: Annotation = Span> {
|
|||||||
MetId(String),
|
MetId(String),
|
||||||
/// A literal bool, string, char, or int
|
/// A literal bool, string, char, or int
|
||||||
Lit(Literal),
|
Lit(Literal),
|
||||||
|
/// use Use
|
||||||
|
Use(Use),
|
||||||
/// `(let | const | static) Pat::NoTopAlt (= expr (else expr)?)?` |
|
/// `(let | const | static) Pat::NoTopAlt (= expr (else expr)?)?` |
|
||||||
/// `(fn | mod | impl) Pat::Fn Expr`
|
/// `(fn | mod | impl) Pat::Fn Expr`
|
||||||
Bind(Box<Bind<A>>),
|
Bind(Box<Bind<A>>),
|
||||||
@@ -310,6 +331,23 @@ impl<T: Display + Annotation, A: Annotation> Display for Anno<T, A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Use {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Glob => "*".fmt(f),
|
||||||
|
Self::Name(name) => name.fmt(f),
|
||||||
|
Self::Path(segment, rest) => write!(f, "{segment}::{rest}"),
|
||||||
|
Self::Tree(items) => match items.len() {
|
||||||
|
0 => "{}".fmt(f),
|
||||||
|
1..=3 => f.delimit("{ ", " }").list(items, ", "),
|
||||||
|
_ => f
|
||||||
|
.delimit_indented("{", "}")
|
||||||
|
.list_wrap("\n", items, ",\n", ",\n"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<A: Annotation> Display for Bind<A> {
|
impl<A: Annotation> Display for Bind<A> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self(op, pat, exprs) = self;
|
let Self(op, pat, exprs) = self;
|
||||||
@@ -335,6 +373,7 @@ impl Display for BindKind {
|
|||||||
Self::Let => "let ",
|
Self::Let => "let ",
|
||||||
Self::Const => "const ",
|
Self::Const => "const ",
|
||||||
Self::Static => "static ",
|
Self::Static => "static ",
|
||||||
|
Self::Type => "type ",
|
||||||
Self::Fn => "fn ",
|
Self::Fn => "fn ",
|
||||||
Self::Mod => "mod ",
|
Self::Mod => "mod ",
|
||||||
Self::Impl => "impl ",
|
Self::Impl => "impl ",
|
||||||
@@ -354,7 +393,6 @@ impl Display for Typedef {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self(kind, pat) = self;
|
let Self(kind, pat) = self;
|
||||||
f.write_str(match kind {
|
f.write_str(match kind {
|
||||||
TypedefKind::Alias => "type ",
|
|
||||||
TypedefKind::Struct => "struct ",
|
TypedefKind::Struct => "struct ",
|
||||||
TypedefKind::Enum => "enum ",
|
TypedefKind::Enum => "enum ",
|
||||||
})?;
|
})?;
|
||||||
@@ -376,6 +414,7 @@ impl<A: Annotation> Display for Expr<A> {
|
|||||||
Self::Id(id) => id.fmt(f),
|
Self::Id(id) => id.fmt(f),
|
||||||
Self::MetId(id) => write!(f, "`{id}"),
|
Self::MetId(id) => write!(f, "`{id}"),
|
||||||
Self::Lit(literal) => literal.fmt(f),
|
Self::Lit(literal) => literal.fmt(f),
|
||||||
|
Self::Use(v) => write!(f, "use {v}"),
|
||||||
Self::Bind(v) => v.fmt(f),
|
Self::Bind(v) => v.fmt(f),
|
||||||
Self::Struct(v) => v.fmt(f),
|
Self::Struct(v) => v.fmt(f),
|
||||||
Self::Make(v) => v.fmt(f),
|
Self::Make(v) => v.fmt(f),
|
||||||
@@ -515,6 +554,7 @@ impl Display for Pat {
|
|||||||
Self::NamedTuple(name, bind) => write!(f, "{name} {bind}"),
|
Self::NamedTuple(name, bind) => write!(f, "{name} {bind}"),
|
||||||
Self::Op(PatOp::Tuple, pats) => f.delimit("(", ")").list(pats, ", "),
|
Self::Op(PatOp::Tuple, pats) => f.delimit("(", ")").list(pats, ", "),
|
||||||
Self::Op(PatOp::Slice, pats) => f.delimit("[", "]").list(pats, ", "),
|
Self::Op(PatOp::Slice, pats) => f.delimit("[", "]").list(pats, ", "),
|
||||||
|
Self::Op(op @ PatOp::Arrep, pats) => f.delimit("[", "]").list(pats, op),
|
||||||
Self::Op(op @ (PatOp::Typed | PatOp::Fn), pats) => f.list(pats, op),
|
Self::Op(op @ (PatOp::Typed | PatOp::Fn), pats) => f.list(pats, op),
|
||||||
Self::Op(op @ PatOp::Alt, pats) => f.delimit("<", ">").list(pats, op),
|
Self::Op(op @ PatOp::Alt, pats) => f.delimit("<", ">").list(pats, op),
|
||||||
Self::Op(op, pats) => match pats.as_slice() {
|
Self::Op(op, pats) => match pats.as_slice() {
|
||||||
@@ -529,12 +569,14 @@ impl Display for Pat {
|
|||||||
impl Display for PatOp {
|
impl Display for PatOp {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_str(match self {
|
f.write_str(match self {
|
||||||
|
Self::Mut => "mut ",
|
||||||
Self::Ref => "&",
|
Self::Ref => "&",
|
||||||
Self::Rest => "..",
|
Self::Rest => "..",
|
||||||
Self::RangeEx => "..",
|
Self::RangeEx => "..",
|
||||||
Self::RangeIn => "..=",
|
Self::RangeIn => "..=",
|
||||||
Self::Tuple => ", ",
|
Self::Tuple => ", ",
|
||||||
Self::Slice => ", ",
|
Self::Slice => ", ",
|
||||||
|
Self::Arrep => "; ",
|
||||||
Self::Typed => ": ",
|
Self::Typed => ": ",
|
||||||
Self::Fn => " -> ",
|
Self::Fn => " -> ",
|
||||||
Self::Alt => " | ",
|
Self::Alt => " | ",
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ impl<A: Annotation> Match<A> for Expr<A> {
|
|||||||
(Expr::Id(_), _) => false,
|
(Expr::Id(_), _) => false,
|
||||||
(Expr::Lit(pat), Expr::Lit(expr)) => pat == expr,
|
(Expr::Lit(pat), Expr::Lit(expr)) => pat == expr,
|
||||||
(Expr::Lit(_), _) => false,
|
(Expr::Lit(_), _) => false,
|
||||||
|
(Expr::Use(_), Expr::Use(_)) => true,
|
||||||
|
(Expr::Use(_), _) => false,
|
||||||
(Expr::Bind(pat), Expr::Bind(expr)) => Match::recurse(sub, pat, expr),
|
(Expr::Bind(pat), Expr::Bind(expr)) => Match::recurse(sub, pat, expr),
|
||||||
(Expr::Bind(..), _) => false,
|
(Expr::Bind(..), _) => false,
|
||||||
(Expr::Struct(pat), Expr::Struct(expr)) => Match::recurse(sub, pat, expr),
|
(Expr::Struct(pat), Expr::Struct(expr)) => Match::recurse(sub, pat, expr),
|
||||||
@@ -147,7 +149,7 @@ impl<A: Annotation> Match<A> for Expr<A> {
|
|||||||
*self = expr.clone()
|
*self = expr.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Id(_) | Expr::Lit(_) => {}
|
Expr::Id(_) | Expr::Lit(_) | Expr::Use(_) => {}
|
||||||
Expr::Bind(expr) => expr.apply(sub),
|
Expr::Bind(expr) => expr.apply(sub),
|
||||||
Expr::Struct(expr) => expr.apply(sub),
|
Expr::Struct(expr) => expr.apply(sub),
|
||||||
Expr::Make(expr) => expr.apply(sub),
|
Expr::Make(expr) => expr.apply(sub),
|
||||||
|
|||||||
@@ -307,13 +307,16 @@ impl<'t> Lexer<'t> {
|
|||||||
"macro" => TKind::Macro,
|
"macro" => TKind::Macro,
|
||||||
"match" => TKind::Match,
|
"match" => TKind::Match,
|
||||||
"mod" => TKind::Module,
|
"mod" => TKind::Module,
|
||||||
|
"mut" => TKind::Mut,
|
||||||
"or" => TKind::Or,
|
"or" => TKind::Or,
|
||||||
"pub" => TKind::Public,
|
"pub" => TKind::Public,
|
||||||
"return" => TKind::Return,
|
"return" => TKind::Return,
|
||||||
"static" => TKind::Const, // TODO: Static
|
"static" => TKind::Static,
|
||||||
"struct" => TKind::Struct,
|
"struct" => TKind::Struct,
|
||||||
"then" => TKind::Do,
|
"then" => TKind::Do,
|
||||||
"true" => TKind::True,
|
"true" => TKind::True,
|
||||||
|
"type" => TKind::Type,
|
||||||
|
"use" => TKind::Use,
|
||||||
"while" => TKind::While,
|
"while" => TKind::While,
|
||||||
_ => token.kind,
|
_ => token.kind,
|
||||||
},
|
},
|
||||||
|
|||||||
112
src/parser.rs
112
src/parser.rs
@@ -16,6 +16,7 @@ pub enum ParseError {
|
|||||||
FromLexer(LexError),
|
FromLexer(LexError),
|
||||||
Expected(TKind, TKind, Span),
|
Expected(TKind, TKind, Span),
|
||||||
NotLiteral(TKind, Span),
|
NotLiteral(TKind, Span),
|
||||||
|
NotUse(TKind, Span),
|
||||||
NotPattern(TKind, Span),
|
NotPattern(TKind, Span),
|
||||||
NotType(TKind, Span),
|
NotType(TKind, Span),
|
||||||
NotPrefix(TKind, Span),
|
NotPrefix(TKind, Span),
|
||||||
@@ -34,6 +35,7 @@ impl Display for ParseError {
|
|||||||
Self::FromLexer(e) => e.fmt(f),
|
Self::FromLexer(e) => e.fmt(f),
|
||||||
Self::Expected(e, tk, loc) => write!(f, "{loc}: Expected {e:?}, got {tk:?}."),
|
Self::Expected(e, tk, loc) => write!(f, "{loc}: Expected {e:?}, got {tk:?}."),
|
||||||
Self::NotLiteral(tk, loc) => write!(f, "{loc}: {tk:?} is not valid in a literal."),
|
Self::NotLiteral(tk, loc) => write!(f, "{loc}: {tk:?} is not valid in a literal."),
|
||||||
|
Self::NotUse(tk, loc) => write!(f, "{loc}: {tk:?} is no use!"),
|
||||||
Self::NotPattern(tk, loc) => write!(f, "{loc}: {tk:?} is not valid in a pattern."),
|
Self::NotPattern(tk, loc) => write!(f, "{loc}: {tk:?} is not valid in a pattern."),
|
||||||
Self::NotType(tk, loc) => write!(f, "{loc}: {tk:?} is not valid in a type."),
|
Self::NotType(tk, loc) => write!(f, "{loc}: {tk:?} is not valid in a type."),
|
||||||
Self::NotPrefix(tk, loc) => write!(f, "{loc}: {tk:?} is not a prefix operator."),
|
Self::NotPrefix(tk, loc) => write!(f, "{loc}: {tk:?} is not a prefix operator."),
|
||||||
@@ -283,6 +285,26 @@ impl<'t> Parse<'t> for Literal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'t> Parse<'t> for Use {
|
||||||
|
type Prec = ();
|
||||||
|
|
||||||
|
fn parse(p: &mut Parser<'t>, _level: Self::Prec) -> PResult<Self> {
|
||||||
|
let tok = p.next()?;
|
||||||
|
Ok(match tok.kind {
|
||||||
|
TKind::Star => p.then(Use::Glob),
|
||||||
|
TKind::Identifier => {
|
||||||
|
let name = tok.lexeme.string().expect("should have String");
|
||||||
|
match p.next_if(TKind::ColonColon).allow_eof()? {
|
||||||
|
Some(Ok(_)) => Use::Path(name, p.parse(())?),
|
||||||
|
_ => Use::Name(name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TKind::LCurly => Use::Tree(p.list(vec![], (), TKind::Comma, TKind::RCurly)?),
|
||||||
|
_ => Err(ParseError::NotUse(tok.kind, tok.span))?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum PPrec {
|
pub enum PPrec {
|
||||||
Min,
|
Min,
|
||||||
@@ -338,6 +360,7 @@ impl<'t> Parse<'t> for Pat {
|
|||||||
}
|
}
|
||||||
TKind::Bar => p.consume().parse(level)?,
|
TKind::Bar => p.consume().parse(level)?,
|
||||||
TKind::Amp => Pat::Op(PatOp::Ref, vec![p.consume().parse(PPrec::Max)?]),
|
TKind::Amp => Pat::Op(PatOp::Ref, vec![p.consume().parse(PPrec::Max)?]),
|
||||||
|
TKind::Mut => Pat::Op(PatOp::Mut, vec![p.consume().parse(level)?]),
|
||||||
TKind::AmpAmp => Pat::Op(
|
TKind::AmpAmp => Pat::Op(
|
||||||
PatOp::Ref,
|
PatOp::Ref,
|
||||||
vec![Pat::Op(PatOp::Ref, vec![p.consume().parse(PPrec::Max)?])],
|
vec![Pat::Op(PatOp::Ref, vec![p.consume().parse(PPrec::Max)?])],
|
||||||
@@ -349,10 +372,10 @@ impl<'t> Parse<'t> for Pat {
|
|||||||
// TODO: make these postfix.
|
// TODO: make these postfix.
|
||||||
match p.peek().map(|t| t.kind) {
|
match p.peek().map(|t| t.kind) {
|
||||||
Ok(TKind::LParen) => Pat::NamedTuple(path, p.parse(PPrec::Typed)?),
|
Ok(TKind::LParen) => Pat::NamedTuple(path, p.parse(PPrec::Typed)?),
|
||||||
Ok(TKind::LCurly) if level <= PPrec::Tuple => Pat::NamedStruct(
|
Ok(TKind::LCurly) if level <= PPrec::Tuple.next() => Pat::NamedStruct(
|
||||||
path,
|
path,
|
||||||
p.consume()
|
p.consume()
|
||||||
.opt(PPrec::Alt, TKind::RCurly)?
|
.opt(PPrec::Tuple, TKind::RCurly)?
|
||||||
.unwrap_or_else(|| Box::new(Pat::Op(PatOp::Tuple, vec![]))),
|
.unwrap_or_else(|| Box::new(Pat::Op(PatOp::Tuple, vec![]))),
|
||||||
),
|
),
|
||||||
Ok(_) | Err(ParseError::EOF(_)) => match path.parts.len() {
|
Ok(_) | Err(ParseError::EOF(_)) => match path.parts.len() {
|
||||||
@@ -390,11 +413,7 @@ impl<'t> Parse<'t> for Pat {
|
|||||||
p.consume()
|
p.consume()
|
||||||
.list(vec![], PPrec::Typed, TKind::Comma, TKind::RParen)?,
|
.list(vec![], PPrec::Typed, TKind::Comma, TKind::RParen)?,
|
||||||
),
|
),
|
||||||
TKind::LBrack => Pat::Op(
|
TKind::LBrack => parse_array_pat(p)?,
|
||||||
PatOp::Slice,
|
|
||||||
p.consume()
|
|
||||||
.list(vec![], PPrec::Typed, TKind::Comma, TKind::RBrack)?,
|
|
||||||
),
|
|
||||||
_ => Err(ParseError::NotPattern(tok.kind, tok.span))?,
|
_ => Err(ParseError::NotPattern(tok.kind, tok.span))?,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -426,59 +445,22 @@ impl<'t> Parse<'t> for Pat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl<'t> Parse<'t> for Ty {
|
fn parse_array_pat<'t>(p: &mut Parser<'t>) -> PResult<Pat> {
|
||||||
// type Prec = ();
|
if p.consume().peek()?.kind == TKind::RBrack {
|
||||||
|
p.consume();
|
||||||
|
return Ok(Pat::Op(PatOp::Slice, vec![]));
|
||||||
|
}
|
||||||
|
|
||||||
// fn parse(p: &mut Parser<'t>, level: Self::Prec) -> PResult<Self>
|
let item = p.parse(PPrec::Tuple)?;
|
||||||
// where Self: Sized {
|
let repeat = p.opt_if(PPrec::Tuple, TKind::Semi)?;
|
||||||
// let &Token { kind, span, .. } = p.peek()?;
|
p.expect(TKind::RBrack)?;
|
||||||
|
|
||||||
// // TODO: this is a kinda jank way of error reporting
|
Ok(match (repeat, item) {
|
||||||
// let head = match kind {
|
(Some(repeat), item) => Pat::Op(PatOp::Arrep, vec![item, repeat]),
|
||||||
// TKind::Identifier => match p.peek()?.lexeme.str() {
|
(None, Pat::Op(PatOp::Tuple, items)) => Pat::Op(PatOp::Slice, items),
|
||||||
// Some("_") => p.consume().then(Ty::Infer),
|
(None, item) => Pat::Op(PatOp::Slice, vec![item]),
|
||||||
// _ => Ty::Named(p.parse(())?),
|
})
|
||||||
// },
|
}
|
||||||
// TKind::Amp => Ty::Ref(p.consume().parse(())?),
|
|
||||||
// TKind::AmpAmp => Ty::Ref(Box::new(Ty::Ref(p.consume().parse(())?))),
|
|
||||||
// TKind::LBrack => {
|
|
||||||
// let ty = p.consume().parse(level)?;
|
|
||||||
// match p.next()? {
|
|
||||||
// Token { kind: TKind::Semi, .. } => {
|
|
||||||
// let ty = Ty::Array(ty, p.parse(Prec::Binary.next())?);
|
|
||||||
// p.expect(TKind::RBrack)?;
|
|
||||||
// ty
|
|
||||||
// }
|
|
||||||
// Token { kind: TKind::RBrack, .. } => Ty::Slice(ty),
|
|
||||||
// tok => Err(ParseError::NotType(tok.kind, tok.span))?,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// TKind::Fn => {
|
|
||||||
// p.consume();
|
|
||||||
// match p.parse(())? {
|
|
||||||
// Ty::Fn(args) => Ty::Fn(args),
|
|
||||||
// other @ Ty::Tuple(_) => Ty::Fn(vec![other, Ty::Tuple(vec![])]),
|
|
||||||
// other => Ty::Fn(vec![other, Ty::Tuple(vec![])]),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// TKind::LParen => {
|
|
||||||
// Ty::Tuple(p.consume().list(vec![], (), TKind::Comma, TKind::RParen)?)
|
|
||||||
// }
|
|
||||||
// _ => Err(ParseError::NotType(kind, span))?,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok(match p.next_if(TKind::Arrow).allow_eof()? {
|
|
||||||
// Some(Ok(_)) => Ty::Fn(vec![
|
|
||||||
// match head {
|
|
||||||
// args @ Ty::Tuple(_) => args,
|
|
||||||
// arg => Ty::Tuple(vec![arg]),
|
|
||||||
// },
|
|
||||||
// p.parse(())?,
|
|
||||||
// ]),
|
|
||||||
// _ => head,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// Organizes the precedence hierarchy for syntactic elements
|
/// Organizes the precedence hierarchy for syntactic elements
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
@@ -549,9 +531,11 @@ pub enum Ps {
|
|||||||
Id, // Identifier
|
Id, // Identifier
|
||||||
Mid, // MetaIdentifier
|
Mid, // MetaIdentifier
|
||||||
Lit, // Literal
|
Lit, // Literal
|
||||||
|
Use, // use Use
|
||||||
Let, // let Pat = Expr (else Expr)?
|
Let, // let Pat = Expr (else Expr)?
|
||||||
Const, // const Pat = Expr
|
Const, // const Pat = Expr
|
||||||
Static, // static Pat = Expr
|
Static, // static Pat = Expr
|
||||||
|
Type, // type Pat = Expr
|
||||||
Typedef, // struct { Pat } | struct ( Pat )
|
Typedef, // struct { Pat } | struct ( Pat )
|
||||||
For, // for Pat in Expr Expr else Expr
|
For, // for Pat in Expr Expr else Expr
|
||||||
Fn, // fn ( Pat,* ) Expr
|
Fn, // fn ( Pat,* ) Expr
|
||||||
@@ -559,7 +543,8 @@ pub enum Ps {
|
|||||||
Lambda, // | Pat,* | Expr
|
Lambda, // | Pat,* | Expr
|
||||||
DoubleRef, // && Expr
|
DoubleRef, // && Expr
|
||||||
Make, // Expr{ Expr,* }
|
Make, // Expr{ Expr,* }
|
||||||
Mod, // mod Ty Expr
|
Mod, // mod Pat Expr
|
||||||
|
Impl, // impl Pat Expr
|
||||||
ImplicitDo, // An implicit semicolon
|
ImplicitDo, // An implicit semicolon
|
||||||
ExplicitDo, // An explicit leading semicolon
|
ExplicitDo, // An explicit leading semicolon
|
||||||
End, // Produces an empty value.
|
End, // Produces an empty value.
|
||||||
@@ -576,6 +561,7 @@ fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
|
|||||||
TKind::True | TKind::False | TKind::Character | TKind::Integer | TKind::String => {
|
TKind::True | TKind::False | TKind::Character | TKind::Integer | TKind::String => {
|
||||||
(Ps::Lit, Prec::Max)
|
(Ps::Lit, Prec::Max)
|
||||||
}
|
}
|
||||||
|
TKind::Use => (Ps::Use, Prec::Max),
|
||||||
|
|
||||||
TKind::Public => (Ps::Op(Op::Pub), Prec::Body),
|
TKind::Public => (Ps::Op(Op::Pub), Prec::Body),
|
||||||
TKind::For => (Ps::For, Prec::Body),
|
TKind::For => (Ps::For, Prec::Body),
|
||||||
@@ -583,8 +569,11 @@ fn from_prefix(token: &Token) -> PResult<(Ps, Prec)> {
|
|||||||
TKind::Match => (Ps::Op(Op::Match), Prec::Body),
|
TKind::Match => (Ps::Op(Op::Match), Prec::Body),
|
||||||
TKind::Macro => (Ps::Op(Op::Macro), Prec::Assign),
|
TKind::Macro => (Ps::Op(Op::Macro), Prec::Assign),
|
||||||
TKind::Module => (Ps::Mod, Prec::Body),
|
TKind::Module => (Ps::Mod, Prec::Body),
|
||||||
|
TKind::Impl => (Ps::Impl, Prec::Body),
|
||||||
TKind::Let => (Ps::Let, Prec::Tuple),
|
TKind::Let => (Ps::Let, Prec::Tuple),
|
||||||
TKind::Const => (Ps::Const, Prec::Body),
|
TKind::Const => (Ps::Const, Prec::Body),
|
||||||
|
TKind::Static => (Ps::Static, Prec::Body),
|
||||||
|
TKind::Type => (Ps::Type, Prec::Body),
|
||||||
TKind::Struct | TKind::Enum => (Ps::Typedef, Prec::Body),
|
TKind::Struct | TKind::Enum => (Ps::Typedef, Prec::Body),
|
||||||
TKind::Loop => (Ps::Op(Op::Loop), Prec::Body),
|
TKind::Loop => (Ps::Op(Op::Loop), Prec::Body),
|
||||||
TKind::If => (Ps::Op(Op::If), Prec::Body),
|
TKind::If => (Ps::Op(Op::If), Prec::Body),
|
||||||
@@ -693,7 +682,7 @@ impl<'t> Parse<'t> for Bind {
|
|||||||
vec![p.expect(TKind::FatArrow)?.parse(Prec::Body.next())?],
|
vec![p.expect(TKind::FatArrow)?.parse(Prec::Body.next())?],
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
BindKind::Mod => Ok(Self(
|
BindKind::Mod | BindKind::Impl => Ok(Self(
|
||||||
level,
|
level,
|
||||||
p.consume().parse(PPrec::Max)?,
|
p.consume().parse(PPrec::Max)?,
|
||||||
vec![p.parse(Prec::Body.next())?],
|
vec![p.parse(Prec::Body.next())?],
|
||||||
@@ -853,11 +842,14 @@ impl<'t> Parse<'t> for Expr {
|
|||||||
Ps::Id => Expr::Id(p.parse(())?),
|
Ps::Id => Expr::Id(p.parse(())?),
|
||||||
Ps::Mid => Expr::MetId(p.consume().next()?.lexeme.to_string()),
|
Ps::Mid => Expr::MetId(p.consume().next()?.lexeme.to_string()),
|
||||||
Ps::Lit => Expr::Lit(p.parse(())?),
|
Ps::Lit => Expr::Lit(p.parse(())?),
|
||||||
|
Ps::Use => Expr::Use(p.consume().parse(())?),
|
||||||
Ps::Typedef => Expr::Struct(p.parse(())?),
|
Ps::Typedef => Expr::Struct(p.parse(())?),
|
||||||
Ps::Let => Expr::Bind(p.parse(BindKind::Let)?),
|
Ps::Let => Expr::Bind(p.parse(BindKind::Let)?),
|
||||||
Ps::Const => Expr::Bind(p.parse(BindKind::Const)?),
|
Ps::Const => Expr::Bind(p.parse(BindKind::Const)?),
|
||||||
Ps::Static => Expr::Bind(p.parse(BindKind::Static)?),
|
Ps::Static => Expr::Bind(p.parse(BindKind::Static)?),
|
||||||
|
Ps::Type => Expr::Bind(p.parse(BindKind::Type)?),
|
||||||
Ps::Mod => Expr::Bind(p.parse(BindKind::Mod)?),
|
Ps::Mod => Expr::Bind(p.parse(BindKind::Mod)?),
|
||||||
|
Ps::Impl => Expr::Bind(p.parse(BindKind::Impl)?),
|
||||||
Ps::Fn => Expr::Bind(p.parse(BindKind::Fn)?),
|
Ps::Fn => Expr::Bind(p.parse(BindKind::Fn)?),
|
||||||
Ps::Lambda | Ps::Lambda0 => {
|
Ps::Lambda | Ps::Lambda0 => {
|
||||||
p.consume();
|
p.consume();
|
||||||
|
|||||||
@@ -82,12 +82,15 @@ pub enum TKind {
|
|||||||
Macro,
|
Macro,
|
||||||
Match,
|
Match,
|
||||||
Module,
|
Module,
|
||||||
|
Mut,
|
||||||
Or,
|
Or,
|
||||||
Public,
|
Public,
|
||||||
Return,
|
Return,
|
||||||
Static,
|
Static,
|
||||||
Struct,
|
Struct,
|
||||||
True,
|
True,
|
||||||
|
Type,
|
||||||
|
Use,
|
||||||
While,
|
While,
|
||||||
|
|
||||||
Identifier, // or Keyword
|
Identifier, // or Keyword
|
||||||
|
|||||||
Reference in New Issue
Block a user