conlang: RIP THE EXPRKIND BANDAGE OFF

cl-ast: No more bare ExprKind: every Expr has a Span
cl-interpret: Give errors a span
cl-repl: Print eval errors in load_file, instead of returning them. These changes are relevant.
This commit is contained in:
2025-03-11 00:36:42 -05:00
parent c0ad544486
commit 7e311cb0ef
14 changed files with 213 additions and 163 deletions

View File

@@ -396,7 +396,7 @@ pub enum ExprKind {
/// A backtick-quoted subexpression-literal
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Quote {
pub quote: Box<ExprKind>,
pub quote: Box<Expr>,
}
/// A local variable declaration [Stmt]
@@ -435,14 +435,14 @@ pub struct MatchArm(pub Pattern, pub Expr);
/// An [Assign]ment expression: [`Expr`] ([`ModifyKind`] [`Expr`])\+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Assign {
pub parts: Box<(ExprKind, ExprKind)>,
pub parts: Box<(Expr, Expr)>,
}
/// A [Modify]-assignment expression: [`Expr`] ([`ModifyKind`] [`Expr`])\+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Modify {
pub kind: ModifyKind,
pub parts: Box<(ExprKind, ExprKind)>,
pub parts: Box<(Expr, Expr)>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -463,7 +463,7 @@ pub enum ModifyKind {
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Binary {
pub kind: BinaryKind,
pub parts: Box<(ExprKind, ExprKind)>,
pub parts: Box<(Expr, Expr)>,
}
/// A [Binary] operator
@@ -497,7 +497,7 @@ pub enum BinaryKind {
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Unary {
pub kind: UnaryKind,
pub tail: Box<ExprKind>,
pub tail: Box<Expr>,
}
/// A [Unary] operator
@@ -519,14 +519,14 @@ pub enum UnaryKind {
/// A cast expression: [`Expr`] `as` [`Ty`]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Cast {
pub head: Box<ExprKind>,
pub head: Box<Expr>,
pub ty: Ty,
}
/// A [Member] access expression: [`Expr`] [`MemberKind`]\*
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Member {
pub head: Box<ExprKind>,
pub head: Box<Expr>,
pub kind: MemberKind,
}
@@ -541,7 +541,7 @@ pub enum MemberKind {
/// A repeated [Index] expression: a[10, 20, 30][40, 50, 60]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Index {
pub head: Box<ExprKind>,
pub head: Box<Expr>,
pub indices: Vec<Expr>,
}
@@ -569,15 +569,15 @@ pub struct Array {
/// `[` [Expr] `;` [Literal] `]`
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ArrayRep {
pub value: Box<ExprKind>,
pub repeat: Box<ExprKind>,
pub value: Box<Expr>,
pub repeat: Box<Expr>,
}
/// An address-of expression: `&` `mut`? [`Expr`]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct AddrOf {
pub mutable: Mutability,
pub expr: Box<ExprKind>,
pub expr: Box<Expr>,
}
/// A [Block] expression: `{` [`Stmt`]\* [`Expr`]? `}`
@@ -589,7 +589,7 @@ pub struct Block {
/// A [Grouping](Group) expression `(` [`Expr`] `)`
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Group {
pub expr: Box<ExprKind>,
pub expr: Box<Expr>,
}
/// A [Tuple] expression: `(` [`Expr`] (`,` [`Expr`])+ `)`

View File

@@ -857,12 +857,12 @@ mod convert {
}
}
impl TryFrom<ExprKind> for Pattern {
type Error = ExprKind;
impl TryFrom<Expr> for Pattern {
type Error = Expr;
/// Performs the conversion. On failure, returns the *first* non-pattern subexpression.
fn try_from(value: ExprKind) -> Result<Self, Self::Error> {
Ok(match value {
fn try_from(value: Expr) -> Result<Self, Self::Error> {
Ok(match value.kind {
ExprKind::Literal(literal) => Pattern::Literal(literal),
ExprKind::Path(Path { absolute: false, ref parts }) => match parts.as_slice() {
[PathPart::Ident(name)] => Pattern::Name(*name),
@@ -873,7 +873,7 @@ mod convert {
ExprKind::Tuple(Tuple { exprs }) => Pattern::Tuple(
exprs
.into_iter()
.map(|e| Pattern::try_from(e.kind))
.map(Pattern::try_from)
.collect::<Result<_, _>>()?,
),
ExprKind::AddrOf(AddrOf { mutable, expr }) => {
@@ -882,14 +882,14 @@ mod convert {
ExprKind::Array(Array { values }) => Pattern::Array(
values
.into_iter()
.map(|e| Pattern::try_from(e.kind))
.map(Pattern::try_from)
.collect::<Result<_, _>>()?,
),
ExprKind::Binary(Binary { kind: BinaryKind::Call, parts }) => {
let (ExprKind::Path(path), args) = *parts else {
let (Expr { kind: ExprKind::Path(path), .. }, args) = *parts else {
return Err(parts.0);
};
match args {
match args.kind {
ExprKind::Empty | ExprKind::Tuple(_) => {}
_ => return Err(args),
}
@@ -905,12 +905,12 @@ mod convert {
let fields = init
.into_iter()
.map(|Fielder { name, init }| {
Ok((name, init.map(|i| Pattern::try_from(i.kind)).transpose()?))
Ok((name, init.map(|i| Pattern::try_from(*i)).transpose()?))
})
.collect::<Result<_, Self::Error>>()?;
Pattern::Struct(to, fields)
}
err => Err(err)?,
_ => Err(value)?,
})
}
}

View File

@@ -294,14 +294,14 @@ pub trait Fold {
fn fold_assign(&mut self, a: Assign) -> Assign {
let Assign { parts } = a;
let (head, tail) = *parts;
Assign { parts: Box::new((self.fold_expr_kind(head), self.fold_expr_kind(tail))) }
Assign { parts: Box::new((self.fold_expr(head), self.fold_expr(tail))) }
}
fn fold_modify(&mut self, m: Modify) -> Modify {
let Modify { kind, parts } = m;
let (head, tail) = *parts;
Modify {
kind: self.fold_modify_kind(kind),
parts: Box::new((self.fold_expr_kind(head), self.fold_expr_kind(tail))),
parts: Box::new((self.fold_expr(head), self.fold_expr(tail))),
}
}
fn fold_modify_kind(&mut self, kind: ModifyKind) -> ModifyKind {
@@ -312,7 +312,7 @@ pub trait Fold {
let (head, tail) = *parts;
Binary {
kind: self.fold_binary_kind(kind),
parts: Box::new((self.fold_expr_kind(head), self.fold_expr_kind(tail))),
parts: Box::new((self.fold_expr(head), self.fold_expr(tail))),
}
}
fn fold_binary_kind(&mut self, kind: BinaryKind) -> BinaryKind {
@@ -320,18 +320,18 @@ pub trait Fold {
}
fn fold_unary(&mut self, u: Unary) -> Unary {
let Unary { kind, tail } = u;
Unary { kind: self.fold_unary_kind(kind), tail: Box::new(self.fold_expr_kind(*tail)) }
Unary { kind: self.fold_unary_kind(kind), tail: Box::new(self.fold_expr(*tail)) }
}
fn fold_unary_kind(&mut self, kind: UnaryKind) -> UnaryKind {
kind
}
fn fold_cast(&mut self, cast: Cast) -> Cast {
let Cast { head, ty } = cast;
Cast { head: Box::new(self.fold_expr_kind(*head)), ty: self.fold_ty(ty) }
Cast { head: Box::new(self.fold_expr(*head)), ty: self.fold_ty(ty) }
}
fn fold_member(&mut self, m: Member) -> Member {
let Member { head, kind } = m;
Member { head: Box::new(self.fold_expr_kind(*head)), kind: self.fold_member_kind(kind) }
Member { head: Box::new(self.fold_expr(*head)), kind: self.fold_member_kind(kind) }
}
fn fold_member_kind(&mut self, kind: MemberKind) -> MemberKind {
or_fold_member_kind(self, kind)
@@ -339,7 +339,7 @@ pub trait Fold {
fn fold_index(&mut self, i: Index) -> Index {
let Index { head, indices } = i;
Index {
head: Box::new(self.fold_expr_kind(*head)),
head: Box::new(self.fold_expr(*head)),
indices: indices.into_iter().map(|e| self.fold_expr(e)).collect(),
}
}
@@ -363,15 +363,15 @@ pub trait Fold {
fn fold_array_rep(&mut self, a: ArrayRep) -> ArrayRep {
let ArrayRep { value, repeat } = a;
ArrayRep {
value: Box::new(self.fold_expr_kind(*value)),
repeat: Box::new(self.fold_expr_kind(*repeat)),
value: Box::new(self.fold_expr(*value)),
repeat: Box::new(self.fold_expr(*repeat)),
}
}
fn fold_addrof(&mut self, a: AddrOf) -> AddrOf {
let AddrOf { mutable, expr } = a;
AddrOf {
mutable: self.fold_mutability(mutable),
expr: Box::new(self.fold_expr_kind(*expr)),
expr: Box::new(self.fold_expr(*expr)),
}
}
fn fold_block(&mut self, b: Block) -> Block {
@@ -380,7 +380,7 @@ pub trait Fold {
}
fn fold_group(&mut self, g: Group) -> Group {
let Group { expr } = g;
Group { expr: Box::new(self.fold_expr_kind(*expr)) }
Group { expr: Box::new(self.fold_expr(*expr)) }
}
fn fold_tuple(&mut self, t: Tuple) -> Tuple {
let Tuple { exprs } = t;

View File

@@ -253,39 +253,39 @@ pub trait Visit<'a>: Sized {
fn visit_assign(&mut self, a: &'a Assign) {
let Assign { parts } = a;
let (head, tail) = parts.as_ref();
self.visit_expr_kind(head);
self.visit_expr_kind(tail);
self.visit_expr(head);
self.visit_expr(tail);
}
fn visit_modify(&mut self, m: &'a Modify) {
let Modify { kind, parts } = m;
let (head, tail) = parts.as_ref();
self.visit_modify_kind(kind);
self.visit_expr_kind(head);
self.visit_expr_kind(tail);
self.visit_expr(head);
self.visit_expr(tail);
}
fn visit_modify_kind(&mut self, _kind: &'a ModifyKind) {}
fn visit_binary(&mut self, b: &'a Binary) {
let Binary { kind, parts } = b;
let (head, tail) = parts.as_ref();
self.visit_binary_kind(kind);
self.visit_expr_kind(head);
self.visit_expr_kind(tail);
self.visit_expr(head);
self.visit_expr(tail);
}
fn visit_binary_kind(&mut self, _kind: &'a BinaryKind) {}
fn visit_unary(&mut self, u: &'a Unary) {
let Unary { kind, tail } = u;
self.visit_unary_kind(kind);
self.visit_expr_kind(tail);
self.visit_expr(tail);
}
fn visit_unary_kind(&mut self, _kind: &'a UnaryKind) {}
fn visit_cast(&mut self, cast: &'a Cast) {
let Cast { head, ty } = cast;
self.visit_expr_kind(head);
self.visit_expr(head);
self.visit_ty(ty);
}
fn visit_member(&mut self, m: &'a Member) {
let Member { head, kind } = m;
self.visit_expr_kind(head);
self.visit_expr(head);
self.visit_member_kind(kind);
}
fn visit_member_kind(&mut self, kind: &'a MemberKind) {
@@ -293,7 +293,7 @@ pub trait Visit<'a>: Sized {
}
fn visit_index(&mut self, i: &'a Index) {
let Index { head, indices } = i;
self.visit_expr_kind(head);
self.visit_expr(head);
indices.iter().for_each(|e| self.visit_expr(e));
}
fn visit_structor(&mut self, s: &'a Structor) {
@@ -314,13 +314,13 @@ pub trait Visit<'a>: Sized {
}
fn visit_array_rep(&mut self, a: &'a ArrayRep) {
let ArrayRep { value, repeat } = a;
self.visit_expr_kind(value);
self.visit_expr_kind(repeat);
self.visit_expr(value);
self.visit_expr(repeat);
}
fn visit_addrof(&mut self, a: &'a AddrOf) {
let AddrOf { mutable, expr } = a;
self.visit_mutability(mutable);
self.visit_expr_kind(expr);
self.visit_expr(expr);
}
fn visit_block(&mut self, b: &'a Block) {
let Block { stmts } = b;
@@ -328,7 +328,7 @@ pub trait Visit<'a>: Sized {
}
fn visit_group(&mut self, g: &'a Group) {
let Group { expr } = g;
self.visit_expr_kind(expr)
self.visit_expr(expr)
}
fn visit_tuple(&mut self, t: &'a Tuple) {
let Tuple { exprs } = t;

View File

@@ -7,7 +7,7 @@ pub struct SquashGroups;
impl Fold for SquashGroups {
fn fold_expr_kind(&mut self, kind: ExprKind) -> ExprKind {
match kind {
ExprKind::Group(Group { expr }) => self.fold_expr_kind(*expr),
ExprKind::Group(Group { expr }) => self.fold_expr(*expr).kind,
_ => or_fold_expr_kind(self, kind),
}
}

View File

@@ -27,7 +27,10 @@ fn desugar_while(extents: Span, kind: ExprKind) -> ExprKind {
let loop_body = If { cond, pass, fail: Else { body: Some(Box::new(break_expr)) } };
let loop_body = ExprKind::If(loop_body);
ExprKind::Unary(Unary { kind: UnaryKind::Loop, tail: Box::new(loop_body) })
ExprKind::Unary(Unary {
kind: UnaryKind::Loop,
tail: Box::new(Expr { extents, kind: loop_body }),
})
}
_ => kind,
}