cl-ast: Move let
into Expr
This commit is contained in:
parent
a3e383b53f
commit
b0341f06fd
@ -323,7 +323,6 @@ pub struct Stmt {
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum StmtKind {
|
pub enum StmtKind {
|
||||||
Empty,
|
Empty,
|
||||||
Local(Let),
|
|
||||||
Item(Box<Item>),
|
Item(Box<Item>),
|
||||||
Expr(Box<Expr>),
|
Expr(Box<Expr>),
|
||||||
}
|
}
|
||||||
@ -342,6 +341,7 @@ pub struct Let {
|
|||||||
pub name: Sym,
|
pub name: Sym,
|
||||||
pub ty: Option<Box<Ty>>,
|
pub ty: Option<Box<Ty>>,
|
||||||
pub init: Option<Box<Expr>>,
|
pub init: Option<Box<Expr>>,
|
||||||
|
pub tail: Option<Box<Expr>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An expression, the beating heart of the language
|
/// An expression, the beating heart of the language
|
||||||
@ -357,6 +357,8 @@ pub enum ExprKind {
|
|||||||
/// An empty expression: `(` `)`
|
/// An empty expression: `(` `)`
|
||||||
#[default]
|
#[default]
|
||||||
Empty,
|
Empty,
|
||||||
|
/// A local bind instruction, `let` [`Sym`] `=` [`Expr`]
|
||||||
|
Let(Let),
|
||||||
/// An [Assign]ment expression: [`Expr`] (`=` [`Expr`])\+
|
/// An [Assign]ment expression: [`Expr`] (`=` [`Expr`])\+
|
||||||
Assign(Assign),
|
Assign(Assign),
|
||||||
/// A [Modify]-assignment expression: [`Expr`] ([`ModifyKind`] [`Expr`])\+
|
/// A [Modify]-assignment expression: [`Expr`] ([`ModifyKind`] [`Expr`])\+
|
||||||
|
@ -389,7 +389,6 @@ mod display {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
StmtKind::Empty => Ok(()),
|
StmtKind::Empty => Ok(()),
|
||||||
StmtKind::Local(v) => v.fmt(f),
|
|
||||||
StmtKind::Item(v) => v.fmt(f),
|
StmtKind::Item(v) => v.fmt(f),
|
||||||
StmtKind::Expr(v) => v.fmt(f),
|
StmtKind::Expr(v) => v.fmt(f),
|
||||||
}
|
}
|
||||||
@ -407,7 +406,7 @@ mod display {
|
|||||||
|
|
||||||
impl Display for Let {
|
impl Display for Let {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { mutable, name, ty, init } = self;
|
let Self { mutable, name, ty, init, tail } = self;
|
||||||
write!(f, "let {mutable}{name}")?;
|
write!(f, "let {mutable}{name}")?;
|
||||||
if let Some(value) = ty {
|
if let Some(value) = ty {
|
||||||
write!(f, ": {value}")?;
|
write!(f, ": {value}")?;
|
||||||
@ -415,6 +414,9 @@ mod display {
|
|||||||
if let Some(value) = init {
|
if let Some(value) = init {
|
||||||
write!(f, " = {value}")?;
|
write!(f, " = {value}")?;
|
||||||
}
|
}
|
||||||
|
if let Some(value) = tail {
|
||||||
|
write!(f, ";\n{value}")?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -429,6 +431,7 @@ mod display {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ExprKind::Empty => "()".fmt(f),
|
ExprKind::Empty => "()".fmt(f),
|
||||||
|
ExprKind::Let(v) => v.fmt(f),
|
||||||
ExprKind::Assign(v) => v.fmt(f),
|
ExprKind::Assign(v) => v.fmt(f),
|
||||||
ExprKind::Modify(v) => v.fmt(f),
|
ExprKind::Modify(v) => v.fmt(f),
|
||||||
ExprKind::Binary(v) => v.fmt(f),
|
ExprKind::Binary(v) => v.fmt(f),
|
||||||
@ -763,11 +766,11 @@ mod convert {
|
|||||||
TyFn => TyKind::Fn,
|
TyFn => TyKind::Fn,
|
||||||
}
|
}
|
||||||
impl From for StmtKind {
|
impl From for StmtKind {
|
||||||
Let => StmtKind::Local,
|
|
||||||
Item => StmtKind::Item,
|
Item => StmtKind::Item,
|
||||||
Expr => StmtKind::Expr,
|
Expr => StmtKind::Expr,
|
||||||
}
|
}
|
||||||
impl From for ExprKind {
|
impl From for ExprKind {
|
||||||
|
Let => ExprKind::Let,
|
||||||
Assign => ExprKind::Assign,
|
Assign => ExprKind::Assign,
|
||||||
Modify => ExprKind::Modify,
|
Modify => ExprKind::Modify,
|
||||||
Binary => ExprKind::Binary,
|
Binary => ExprKind::Binary,
|
||||||
|
@ -227,12 +227,13 @@ pub trait Fold {
|
|||||||
s
|
s
|
||||||
}
|
}
|
||||||
fn fold_let(&mut self, l: Let) -> Let {
|
fn fold_let(&mut self, l: Let) -> Let {
|
||||||
let Let { mutable, name, ty, init } = l;
|
let Let { mutable, name, ty, init, tail } = l;
|
||||||
Let {
|
Let {
|
||||||
mutable: self.fold_mutability(mutable),
|
mutable: self.fold_mutability(mutable),
|
||||||
name: self.fold_sym(name),
|
name: self.fold_sym(name),
|
||||||
ty: ty.map(|t| Box::new(self.fold_ty(*t))),
|
ty: ty.map(|t| Box::new(self.fold_ty(*t))),
|
||||||
init: init.map(|e| Box::new(self.fold_expr(*e))),
|
init: init.map(|e| Box::new(self.fold_expr(*e))),
|
||||||
|
tail: tail.map(|e| Box::new(self.fold_expr(*e))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||||
@ -525,7 +526,6 @@ pub fn or_fold_ty_kind<F: Fold + ?Sized>(folder: &mut F, kind: TyKind) -> TyKind
|
|||||||
pub fn or_fold_stmt_kind<F: Fold + ?Sized>(folder: &mut F, kind: StmtKind) -> StmtKind {
|
pub fn or_fold_stmt_kind<F: Fold + ?Sized>(folder: &mut F, kind: StmtKind) -> StmtKind {
|
||||||
match kind {
|
match kind {
|
||||||
StmtKind::Empty => StmtKind::Empty,
|
StmtKind::Empty => StmtKind::Empty,
|
||||||
StmtKind::Local(l) => StmtKind::Local(folder.fold_let(l)),
|
|
||||||
StmtKind::Item(i) => StmtKind::Item(Box::new(folder.fold_item(*i))),
|
StmtKind::Item(i) => StmtKind::Item(Box::new(folder.fold_item(*i))),
|
||||||
StmtKind::Expr(e) => StmtKind::Expr(Box::new(folder.fold_expr(*e))),
|
StmtKind::Expr(e) => StmtKind::Expr(Box::new(folder.fold_expr(*e))),
|
||||||
}
|
}
|
||||||
@ -535,6 +535,7 @@ pub fn or_fold_stmt_kind<F: Fold + ?Sized>(folder: &mut F, kind: StmtKind) -> St
|
|||||||
pub fn or_fold_expr_kind<F: Fold + ?Sized>(folder: &mut F, kind: ExprKind) -> ExprKind {
|
pub fn or_fold_expr_kind<F: Fold + ?Sized>(folder: &mut F, kind: ExprKind) -> ExprKind {
|
||||||
match kind {
|
match kind {
|
||||||
ExprKind::Empty => ExprKind::Empty,
|
ExprKind::Empty => ExprKind::Empty,
|
||||||
|
ExprKind::Let(l) => ExprKind::Let(folder.fold_let(l)),
|
||||||
ExprKind::Assign(a) => ExprKind::Assign(folder.fold_assign(a)),
|
ExprKind::Assign(a) => ExprKind::Assign(folder.fold_assign(a)),
|
||||||
ExprKind::Modify(m) => ExprKind::Modify(folder.fold_modify(m)),
|
ExprKind::Modify(m) => ExprKind::Modify(folder.fold_modify(m)),
|
||||||
ExprKind::Binary(b) => ExprKind::Binary(folder.fold_binary(b)),
|
ExprKind::Binary(b) => ExprKind::Binary(folder.fold_binary(b)),
|
||||||
|
@ -192,7 +192,7 @@ pub trait Visit<'a>: Sized {
|
|||||||
}
|
}
|
||||||
fn visit_semi(&mut self, _s: &'a Semi) {}
|
fn visit_semi(&mut self, _s: &'a Semi) {}
|
||||||
fn visit_let(&mut self, l: &'a Let) {
|
fn visit_let(&mut self, l: &'a Let) {
|
||||||
let Let { mutable, name, ty, init } = l;
|
let Let { mutable, name, ty, init, tail } = l;
|
||||||
self.visit_mutability(mutable);
|
self.visit_mutability(mutable);
|
||||||
self.visit_sym(name);
|
self.visit_sym(name);
|
||||||
if let Some(ty) = ty {
|
if let Some(ty) = ty {
|
||||||
@ -201,6 +201,9 @@ pub trait Visit<'a>: Sized {
|
|||||||
if let Some(init) = init {
|
if let Some(init) = init {
|
||||||
self.visit_expr(init)
|
self.visit_expr(init)
|
||||||
}
|
}
|
||||||
|
if let Some(tail) = tail {
|
||||||
|
self.visit_expr(tail)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn visit_expr(&mut self, e: &'a Expr) {
|
fn visit_expr(&mut self, e: &'a Expr) {
|
||||||
let Expr { extents, kind } = e;
|
let Expr { extents, kind } = e;
|
||||||
@ -448,7 +451,6 @@ pub fn or_visit_ty_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a TyKind) {
|
|||||||
pub fn or_visit_stmt_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a StmtKind) {
|
pub fn or_visit_stmt_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a StmtKind) {
|
||||||
match kind {
|
match kind {
|
||||||
StmtKind::Empty => {}
|
StmtKind::Empty => {}
|
||||||
StmtKind::Local(l) => visitor.visit_let(l),
|
|
||||||
StmtKind::Item(i) => visitor.visit_item(i),
|
StmtKind::Item(i) => visitor.visit_item(i),
|
||||||
StmtKind::Expr(e) => visitor.visit_expr(e),
|
StmtKind::Expr(e) => visitor.visit_expr(e),
|
||||||
}
|
}
|
||||||
@ -457,6 +459,7 @@ pub fn or_visit_stmt_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a StmtKind)
|
|||||||
pub fn or_visit_expr_kind<'a, V: Visit<'a>>(visitor: &mut V, e: &'a ExprKind) {
|
pub fn or_visit_expr_kind<'a, V: Visit<'a>>(visitor: &mut V, e: &'a ExprKind) {
|
||||||
match e {
|
match e {
|
||||||
ExprKind::Empty => {}
|
ExprKind::Empty => {}
|
||||||
|
ExprKind::Let(l) => visitor.visit_let(l),
|
||||||
ExprKind::Assign(a) => visitor.visit_assign(a),
|
ExprKind::Assign(a) => visitor.visit_assign(a),
|
||||||
ExprKind::Modify(m) => visitor.visit_modify(m),
|
ExprKind::Modify(m) => visitor.visit_modify(m),
|
||||||
ExprKind::Binary(b) => visitor.visit_binary(b),
|
ExprKind::Binary(b) => visitor.visit_binary(b),
|
||||||
|
@ -105,7 +105,6 @@ impl Interpret for Stmt {
|
|||||||
let Self { extents: _, kind, semi } = self;
|
let Self { extents: _, kind, semi } = self;
|
||||||
let out = match kind {
|
let out = match kind {
|
||||||
StmtKind::Empty => ConValue::Empty,
|
StmtKind::Empty => ConValue::Empty,
|
||||||
StmtKind::Local(stmt) => stmt.interpret(env)?,
|
|
||||||
StmtKind::Item(stmt) => stmt.interpret(env)?,
|
StmtKind::Item(stmt) => stmt.interpret(env)?,
|
||||||
StmtKind::Expr(stmt) => stmt.interpret(env)?,
|
StmtKind::Expr(stmt) => stmt.interpret(env)?,
|
||||||
};
|
};
|
||||||
@ -117,9 +116,10 @@ impl Interpret for Stmt {
|
|||||||
}
|
}
|
||||||
impl Interpret for Let {
|
impl Interpret for Let {
|
||||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
let Let { mutable: _, name, ty: _, init } = self;
|
let Let { mutable: _, name, ty: _, init, tail } = self;
|
||||||
let init = init.as_ref().map(|i| i.interpret(env)).transpose()?;
|
let init = init.as_ref().map(|i| i.interpret(env)).transpose()?;
|
||||||
env.insert(*name, init);
|
env.insert(*name, init);
|
||||||
|
tail.as_ref().map(|e| e.interpret(env)).transpose()?;
|
||||||
Ok(ConValue::Empty)
|
Ok(ConValue::Empty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,6 +134,7 @@ impl Interpret for ExprKind {
|
|||||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
match self {
|
match self {
|
||||||
ExprKind::Empty => Ok(ConValue::Empty),
|
ExprKind::Empty => Ok(ConValue::Empty),
|
||||||
|
ExprKind::Let(v) => v.interpret(env),
|
||||||
ExprKind::Assign(v) => v.interpret(env),
|
ExprKind::Assign(v) => v.interpret(env),
|
||||||
ExprKind::Modify(v) => v.interpret(env),
|
ExprKind::Modify(v) => v.interpret(env),
|
||||||
ExprKind::Binary(v) => v.interpret(env),
|
ExprKind::Binary(v) => v.interpret(env),
|
||||||
|
@ -815,31 +815,10 @@ impl<'t> Parser<'t> {
|
|||||||
pub fn stmtkind(&mut self) -> PResult<StmtKind> {
|
pub fn stmtkind(&mut self) -> PResult<StmtKind> {
|
||||||
Ok(match self.peek_kind(Parsing::StmtKind)? {
|
Ok(match self.peek_kind(Parsing::StmtKind)? {
|
||||||
TokenKind::Semi => StmtKind::Empty,
|
TokenKind::Semi => StmtKind::Empty,
|
||||||
TokenKind::Let => self.parse_let()?.into(),
|
|
||||||
item_like!() => self.item()?.into(),
|
item_like!() => self.item()?.into(),
|
||||||
_ => self.expr()?.into(),
|
_ => self.expr()?.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_let(&mut self) -> PResult<Let> {
|
|
||||||
self.consume_peeked();
|
|
||||||
Ok(Let {
|
|
||||||
mutable: self.mutability(),
|
|
||||||
name: self.identifier()?,
|
|
||||||
ty: if Ok(TokenKind::Colon) == self.peek_kind(Parsing::Let) {
|
|
||||||
self.consume_peeked();
|
|
||||||
Some(self.ty()?.into())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
init: if Ok(TokenKind::Eq) == self.peek_kind(Parsing::Let) {
|
|
||||||
self.consume_peeked();
|
|
||||||
Some(self.expr()?.into())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Expression parsing
|
/// # Expression parsing
|
||||||
@ -863,6 +842,7 @@ impl<'t> Parser<'t> {
|
|||||||
TokenKind::LCurly => self.block()?.into(),
|
TokenKind::LCurly => self.block()?.into(),
|
||||||
TokenKind::LBrack => self.exprkind_arraylike()?,
|
TokenKind::LBrack => self.exprkind_arraylike()?,
|
||||||
TokenKind::LParen => self.exprkind_tuplelike()?,
|
TokenKind::LParen => self.exprkind_tuplelike()?,
|
||||||
|
TokenKind::Let => self.parse_let()?.into(),
|
||||||
TokenKind::Loop => {
|
TokenKind::Loop => {
|
||||||
self.consume_peeked();
|
self.consume_peeked();
|
||||||
Loop { body: self.expr()?.into() }.into()
|
Loop { body: self.expr()?.into() }.into()
|
||||||
@ -1157,6 +1137,29 @@ impl<'t> Parser<'t> {
|
|||||||
const A_BLOCK: Parsing = Parsing::Block;
|
const A_BLOCK: Parsing = Parsing::Block;
|
||||||
Ok(Block { stmts: delim(rep(Self::stmt, CURLIES.1, A_BLOCK), CURLIES, A_BLOCK)(self)? })
|
Ok(Block { stmts: delim(rep(Self::stmt, CURLIES.1, A_BLOCK), CURLIES, A_BLOCK)(self)? })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_let(&mut self) -> PResult<Let> {
|
||||||
|
self.consume_peeked();
|
||||||
|
Ok(Let {
|
||||||
|
mutable: self.mutability(),
|
||||||
|
name: self.identifier()?,
|
||||||
|
ty: if self.match_type(TokenKind::Colon, Parsing::Let).is_ok() {
|
||||||
|
Some(self.ty()?.into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
init: if self.match_type(TokenKind::Eq, Parsing::Let).is_ok() {
|
||||||
|
Some(self.expr()?.into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
tail: if self.match_type(TokenKind::Semi, Parsing::Let).is_ok() {
|
||||||
|
Some(self.expr()?.into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// ## Control flow subexpressions
|
/// ## Control flow subexpressions
|
||||||
impl<'t> Parser<'t> {
|
impl<'t> Parser<'t> {
|
||||||
|
@ -363,7 +363,6 @@ pub mod yamlify {
|
|||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
match self {
|
match self {
|
||||||
StmtKind::Empty => y,
|
StmtKind::Empty => y,
|
||||||
StmtKind::Local(s) => y.yaml(s),
|
|
||||||
StmtKind::Item(s) => y.yaml(s),
|
StmtKind::Item(s) => y.yaml(s),
|
||||||
StmtKind::Expr(s) => y.yaml(s),
|
StmtKind::Expr(s) => y.yaml(s),
|
||||||
};
|
};
|
||||||
@ -371,12 +370,13 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
impl Yamlify for Let {
|
impl Yamlify for Let {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { mutable, name, ty, init } = self;
|
let Self { mutable, name, ty, init, tail } = self;
|
||||||
y.key("Let")
|
y.key("Let")
|
||||||
.pair("name", name)
|
.pair("name", name)
|
||||||
.yaml(mutable)
|
.yaml(mutable)
|
||||||
.pair("ty", ty)
|
.pair("ty", ty)
|
||||||
.pair("init", init);
|
.pair("init", init)
|
||||||
|
.pair("tail", tail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for Expr {
|
impl Yamlify for Expr {
|
||||||
@ -388,6 +388,7 @@ pub mod yamlify {
|
|||||||
impl Yamlify for ExprKind {
|
impl Yamlify for ExprKind {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
match self {
|
match self {
|
||||||
|
ExprKind::Let(k) => k.yaml(y),
|
||||||
ExprKind::Assign(k) => k.yaml(y),
|
ExprKind::Assign(k) => k.yaml(y),
|
||||||
ExprKind::Modify(k) => k.yaml(y),
|
ExprKind::Modify(k) => k.yaml(y),
|
||||||
ExprKind::Binary(k) => k.yaml(y),
|
ExprKind::Binary(k) => k.yaml(y),
|
||||||
|
@ -145,35 +145,25 @@ impl<'a> Visit<'a> for Populator<'_, 'a> {
|
|||||||
self.visit_use_tree(tree);
|
self.visit_use_tree(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_stmt(&mut self, s: &'a cl_ast::Stmt) {
|
|
||||||
let cl_ast::Stmt { extents, kind, semi } = s;
|
|
||||||
let cl_ast::StmtKind::Local(local) = kind else {
|
|
||||||
self.visit_span(extents);
|
|
||||||
self.visit_stmt_kind(kind);
|
|
||||||
self.visit_semi(semi);
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut entry = self.new_entry(NodeKind::Local);
|
|
||||||
entry.inner.set_span(*extents);
|
|
||||||
entry.visit_let(local);
|
|
||||||
|
|
||||||
if let (Some(name), child) = (entry.name, entry.inner.id()) {
|
|
||||||
self.inner.add_child(name, child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_let(&mut self, l: &'a cl_ast::Let) {
|
fn visit_let(&mut self, l: &'a cl_ast::Let) {
|
||||||
let cl_ast::Let { mutable, name, ty, init } = l;
|
let cl_ast::Let { mutable, name, ty, init, tail } = l;
|
||||||
self.inner.set_source(Source::Local(l));
|
let mut entry = self.new_entry(NodeKind::Local);
|
||||||
self.set_name(*name);
|
|
||||||
|
|
||||||
self.visit_mutability(mutable);
|
entry.inner.set_source(Source::Local(l));
|
||||||
|
entry.set_name(*name);
|
||||||
|
|
||||||
|
entry.visit_mutability(mutable);
|
||||||
if let Some(ty) = ty {
|
if let Some(ty) = ty {
|
||||||
self.visit_ty(ty);
|
entry.visit_ty(ty);
|
||||||
}
|
}
|
||||||
if let Some(init) = init {
|
if let Some(init) = init {
|
||||||
self.visit_expr(init)
|
entry.visit_expr(init)
|
||||||
}
|
}
|
||||||
|
if let Some(tail) = tail {
|
||||||
|
entry.visit_expr(tail)
|
||||||
|
}
|
||||||
|
|
||||||
|
let child = entry.inner.id();
|
||||||
|
self.inner.add_child(*name, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user