cl-ast: Fix AddrOf misbehavior

This commit is contained in:
John 2025-01-29 03:31:24 -06:00
parent bc955c6409
commit 518fbe74a1
7 changed files with 24 additions and 28 deletions

View File

@ -546,7 +546,6 @@ pub struct ArrayRep {
/// An address-of expression: `&` `mut`? [`Expr`]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct AddrOf {
pub count: usize,
pub mutable: Mutability,
pub expr: Box<ExprKind>,
}

View File

@ -616,11 +616,8 @@ mod display {
impl Display for AddrOf {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { count, mutable, expr } = self;
for _ in 0..*count {
f.write_char('&')?;
}
write!(f, "{mutable}{expr}")
let Self { mutable, expr } = self;
write!(f, "&{mutable}{expr}")
}
}

View File

@ -322,9 +322,8 @@ pub trait Fold {
}
}
fn fold_addrof(&mut self, a: AddrOf) -> AddrOf {
let AddrOf { count, mutable, expr } = a;
let AddrOf { mutable, expr } = a;
AddrOf {
count,
mutable: self.fold_mutability(mutable),
expr: Box::new(self.fold_expr_kind(*expr)),
}

View File

@ -279,7 +279,7 @@ pub trait Visit<'a>: Sized {
self.visit_expr_kind(repeat);
}
fn visit_addrof(&mut self, a: &'a AddrOf) {
let AddrOf { count: _, mutable, expr } = a;
let AddrOf { mutable, expr } = a;
self.visit_mutability(mutable);
self.visit_expr_kind(expr);
}

View File

@ -681,13 +681,9 @@ impl Interpret for ArrayRep {
}
impl Interpret for AddrOf {
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
let Self { count: _, mutable: _, expr } = self;
let Self { mutable: _, expr } = self;
match expr.as_ref() {
ExprKind::Index(_) => todo!("AddrOf array index"),
// ExprKind::Path(Path { absolute: false, parts }) => match parts.as_slice() {
// [PathPart::Ident(id)] => env.get_ref(id),
// _ => todo!("Path traversal in addrof"),
// },
ExprKind::Path(_) => todo!("Path traversal in addrof"),
_ => Ok(ConValue::Ref(Rc::new(expr.interpret(env)?))),
}

View File

@ -962,16 +962,24 @@ impl Parse<'_> for AddrOf {
/// [AddrOf] = (`&`|`&&`)* [Expr]
fn parse(p: &mut Parser) -> PResult<AddrOf> {
const P: Parsing = Parsing::AddrOf;
let mut count = 0;
loop {
count += match p.peek_kind(P)? {
TokenKind::Amp => 1,
TokenKind::AmpAmp => 2,
_ => break,
};
p.consume_peeked();
match p.peek_kind(P)? {
TokenKind::Amp => {
p.consume_peeked();
Ok(AddrOf { mutable: Mutability::parse(p)?, expr: ExprKind::parse(p)?.into() })
}
TokenKind::AmpAmp => {
p.consume_peeked();
Ok(AddrOf {
mutable: Mutability::Not,
expr: ExprKind::AddrOf(AddrOf {
mutable: Mutability::parse(p)?,
expr: ExprKind::parse(p)?.into(),
})
.into(),
})
}
got => Err(p.error(ExpectedToken { want: TokenKind::Amp, got }, P)),
}
Ok(AddrOf { count, mutable: Mutability::parse(p)?, expr: ExprKind::parse(p)?.into() })
}
}

View File

@ -525,11 +525,8 @@ pub mod yamlify {
}
impl Yamlify for AddrOf {
fn yaml(&self, y: &mut Yamler) {
let Self { count, mutable, expr } = self;
y.key("AddrOf")
.pair("count", count)
.yaml(mutable)
.pair("expr", expr);
let Self { mutable, expr } = self;
y.key("AddrOf").yaml(mutable).pair("expr", expr);
}
}
impl Yamlify for Group {