doughlang: Preserve errors through entire pipeline
lexer: - Un-stringify errors - Reserve more words - Doc the comments parser: - MASSIVE changes to peek, peek_if, next_if, consume_if=>expect. - Keep track of when EOF is allowable - TKind is stupidly cheap with >100 niches, so we can fit like 4 of them in a single ParseError lmao - TODO: make sure EOF/UnexpectedEOF propagation is correct. It seems... Kinda Not correct. - Add meta-expressions
This commit is contained in:
140
src/ast.rs
140
src/ast.rs
@@ -23,7 +23,7 @@ impl<T: Clone + std::fmt::Debug + std::fmt::Display + PartialEq + Eq> Annotation
|
||||
pub struct FqPath {
|
||||
// TODO: Identifier interning
|
||||
pub parts: Vec<String>,
|
||||
// TODO:
|
||||
// TODO: generic parameters
|
||||
}
|
||||
|
||||
impl From<&str> for FqPath {
|
||||
@@ -251,6 +251,7 @@ pub enum Op {
|
||||
ArRep, // [ Expr ; Expr ]
|
||||
Group, // ( Expr ,?)
|
||||
Tuple, // Expr (, Expr)*
|
||||
Meta, // #[ Expr ]
|
||||
|
||||
Try, // Expr '?'
|
||||
Index, // Expr [ Expr,* ]
|
||||
@@ -298,7 +299,17 @@ pub enum Op {
|
||||
LogXor, // Expr ^^ Expr
|
||||
LogOr, // Expr || Expr
|
||||
|
||||
Set, // Expr = Expr
|
||||
Set, // Expr = Expr
|
||||
MulSet, // Expr *= Expr
|
||||
DivSet, // Expr /= Expr
|
||||
RemSet, // Expr %= Expr
|
||||
AddSet, // Expr += Expr
|
||||
SubSet, // Expr -= Expr
|
||||
ShlSet, // Expr <<= Expr
|
||||
ShrSet, // Expr >>= Expr
|
||||
AndSet, // Expr &= Expr
|
||||
XorSet, // Expr ^= Expr
|
||||
OrSet, // Expr |= Expr
|
||||
}
|
||||
|
||||
use crate::{fmt::FmtAdapter, span::Span};
|
||||
@@ -381,19 +392,19 @@ impl<A: Annotation> Display for Mod<A> {
|
||||
impl Display for Typedef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Self(kind, pat) = self;
|
||||
let kind = match kind {
|
||||
TypedefKind::Alias => "type",
|
||||
TypedefKind::Struct => "struct",
|
||||
TypedefKind::Enum => "enum",
|
||||
};
|
||||
f.write_str(match kind {
|
||||
TypedefKind::Alias => "type ",
|
||||
TypedefKind::Struct => "struct ",
|
||||
TypedefKind::Enum => "enum ",
|
||||
})?;
|
||||
match pat {
|
||||
Pat::Struct(name, bind) => match bind.as_ref() {
|
||||
Pat::Op(PatOp::Tuple, parts) => f
|
||||
.delimit_indented(fmt!("{kind} {name} {{"), "}")
|
||||
.delimit_indented(fmt!("{name} {{"), "}")
|
||||
.list_wrap("\n", parts, ",\n", ",\n"),
|
||||
other => write!(f, "{name} {{ {other} }}"),
|
||||
},
|
||||
_ => write!(f, "{kind} {pat}"),
|
||||
_ => pat.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,6 +437,10 @@ impl<A: Annotation> Display for Expr<A> {
|
||||
.list_wrap("\n", exprs, "\n", "\n"),
|
||||
Self::Op(Op::Tuple, exprs) => f.delimit("(", ")").list(exprs, ", "),
|
||||
Self::Op(Op::Group, exprs) => f.list(exprs, ", "),
|
||||
Self::Op(Op::Meta, exprs) => match exprs.as_slice() {
|
||||
[meta, expr @ ..] => f.delimit(fmt!("#[{meta}]\n"), "").list(expr, ","),
|
||||
[] => write!(f, "#[]"),
|
||||
},
|
||||
|
||||
Self::Op(op @ Op::Call, exprs) => match exprs.as_slice() {
|
||||
[callee, args @ ..] => f.delimit(fmt!("{callee}("), ")").list(args, ", "),
|
||||
@@ -436,7 +451,7 @@ impl<A: Annotation> Display for Expr<A> {
|
||||
[] => write!(f, "{op}"),
|
||||
},
|
||||
|
||||
Self::Op(Op::Do, exprs) => f.list(exprs, ";\n"),
|
||||
Self::Op(op @ Op::Do, exprs) => f.list(exprs, op),
|
||||
Self::Op(op @ Op::Macro, exprs) => f.delimit(op, "").list(exprs, " => "),
|
||||
Self::Op(op @ Op::Try, exprs) => f.delimit("(", fmt!("){op}")).list(exprs, ", "),
|
||||
Self::Op(op, exprs) => match exprs.as_slice() {
|
||||
@@ -449,53 +464,64 @@ impl<A: Annotation> Display for Expr<A> {
|
||||
|
||||
impl Display for Op {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Op::Do => "; ".fmt(f),
|
||||
Op::As => " as ".fmt(f),
|
||||
Op::Macro => "macro ".fmt(f),
|
||||
Op::Block => "{}".fmt(f),
|
||||
Op::Array => "[]".fmt(f),
|
||||
Op::ArRep => "[;]".fmt(f),
|
||||
Op::Group => "()".fmt(f),
|
||||
Op::Tuple => "()".fmt(f),
|
||||
Op::Try => "?".fmt(f),
|
||||
Op::Index => "".fmt(f),
|
||||
Op::Call => "".fmt(f),
|
||||
Op::Pub => "pub ".fmt(f),
|
||||
Op::Loop => "loop ".fmt(f),
|
||||
Op::If => "if ".fmt(f),
|
||||
Op::While => "while ".fmt(f),
|
||||
Op::Break => "break ".fmt(f),
|
||||
Op::Return => "return ".fmt(f),
|
||||
Op::Dot => ".".fmt(f),
|
||||
Op::RangeEx => "..".fmt(f),
|
||||
Op::RangeIn => "..=".fmt(f),
|
||||
Op::Neg => "-".fmt(f),
|
||||
Op::Not => "!".fmt(f),
|
||||
Op::Identity => "!!".fmt(f),
|
||||
Op::Refer => "&".fmt(f),
|
||||
Op::Deref => "*".fmt(f),
|
||||
Op::Mul => " * ".fmt(f),
|
||||
Op::Div => " / ".fmt(f),
|
||||
Op::Rem => " % ".fmt(f),
|
||||
Op::Add => " + ".fmt(f),
|
||||
Op::Sub => " - ".fmt(f),
|
||||
Op::Shl => " << ".fmt(f),
|
||||
Op::Shr => " >> ".fmt(f),
|
||||
Op::And => " & ".fmt(f),
|
||||
Op::Xor => " ^ ".fmt(f),
|
||||
Op::Or => " | ".fmt(f),
|
||||
Op::Lt => " < ".fmt(f),
|
||||
Op::Leq => " <= ".fmt(f),
|
||||
Op::Eq => " == ".fmt(f),
|
||||
Op::Neq => " != ".fmt(f),
|
||||
Op::Geq => " >= ".fmt(f),
|
||||
Op::Gt => " > ".fmt(f),
|
||||
Op::LogAnd => " && ".fmt(f),
|
||||
Op::LogXor => " ^^ ".fmt(f),
|
||||
Op::LogOr => " || ".fmt(f),
|
||||
Op::Set => " = ".fmt(f),
|
||||
}
|
||||
f.write_str(match self {
|
||||
Op::Do => "; ",
|
||||
Op::As => " as ",
|
||||
Op::Macro => "macro ",
|
||||
Op::Block => "{}",
|
||||
Op::Array => "[]",
|
||||
Op::ArRep => "[;]",
|
||||
Op::Group => "()",
|
||||
Op::Tuple => "()",
|
||||
Op::Meta => "#[]",
|
||||
Op::Try => "?",
|
||||
Op::Index => "",
|
||||
Op::Call => "",
|
||||
Op::Pub => "pub ",
|
||||
Op::Loop => "loop ",
|
||||
Op::If => "if ",
|
||||
Op::While => "while ",
|
||||
Op::Break => "break ",
|
||||
Op::Return => "return ",
|
||||
Op::Dot => ".",
|
||||
Op::RangeEx => "..",
|
||||
Op::RangeIn => "..=",
|
||||
Op::Neg => "-",
|
||||
Op::Not => "!",
|
||||
Op::Identity => "!!",
|
||||
Op::Refer => "&",
|
||||
Op::Deref => "*",
|
||||
Op::Mul => " * ",
|
||||
Op::Div => " / ",
|
||||
Op::Rem => " % ",
|
||||
Op::Add => " + ",
|
||||
Op::Sub => " - ",
|
||||
Op::Shl => " << ",
|
||||
Op::Shr => " >> ",
|
||||
Op::And => " & ",
|
||||
Op::Xor => " ^ ",
|
||||
Op::Or => " | ",
|
||||
Op::Lt => " < ",
|
||||
Op::Leq => " <= ",
|
||||
Op::Eq => " == ",
|
||||
Op::Neq => " != ",
|
||||
Op::Geq => " >= ",
|
||||
Op::Gt => " > ",
|
||||
Op::LogAnd => " && ",
|
||||
Op::LogXor => " ^^ ",
|
||||
Op::LogOr => " || ",
|
||||
Op::Set => " = ",
|
||||
Op::MulSet => " *= ",
|
||||
Op::DivSet => " /= ",
|
||||
Op::RemSet => " %= ",
|
||||
Op::AddSet => " += ",
|
||||
Op::SubSet => " -= ",
|
||||
Op::ShlSet => " <<= ",
|
||||
Op::ShrSet => " >>= ",
|
||||
Op::AndSet => " &= ",
|
||||
Op::XorSet => " ^= ",
|
||||
Op::OrSet => " |= ",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user