Fix a pattern desugaring bug

This commit is contained in:
Shunsuke Shibayama 2022-12-19 22:44:54 +09:00
parent 6e839d6f03
commit 24b8f3f63d
2 changed files with 24 additions and 6 deletions

View file

@ -76,7 +76,7 @@ impl Context {
ast::VarPattern::Discard(_) => { ast::VarPattern::Discard(_) => {
return Ok(()); return Ok(());
} }
_ => todo!(), other => unreachable!("{other}"),
}; };
let vis = ident.vis(); let vis = ident.vis();
let kind = id.map_or(VarKind::Declared, VarKind::Defined); let kind = id.map_or(VarKind::Declared, VarKind::Defined);

View file

@ -43,7 +43,7 @@ impl Desugarer {
pub fn desugar(&mut self, module: Module) -> Module { pub fn desugar(&mut self, module: Module) -> Module {
log!(info "the desugaring process has started."); log!(info "the desugaring process has started.");
let module = self.desugar_multiple_pattern_def(module); let module = self.desugar_multiple_pattern_def(module);
let module = self.desugar_pattern(module); let module = self.desugar_pattern_in_module(module);
let module = Self::desugar_shortened_record(module); let module = Self::desugar_shortened_record(module);
let module = Self::desugar_acc(module); let module = Self::desugar_acc(module);
log!(info "AST (desugared):\n{module}"); log!(info "AST (desugared):\n{module}");
@ -437,21 +437,33 @@ impl Desugarer {
for param in non_defaults { for param in non_defaults {
self.desugar_nd_param(param, &mut lambda.body); self.desugar_nd_param(param, &mut lambda.body);
} }
lambda.body = self.desugar_pattern_in_block(lambda.body);
Expr::Lambda(lambda) Expr::Lambda(lambda)
} }
expr => Self::perform_desugar(|ex| self.rec_desugar_lambda_pattern(ex), expr), expr => Self::perform_desugar(|ex| self.rec_desugar_lambda_pattern(ex), expr),
} }
} }
fn desugar_pattern_in_module(&mut self, module: Module) -> Module {
Module::new(self.desugar_pattern(module.into_iter()))
}
fn desugar_pattern_in_block(&mut self, block: Block) -> Block {
Block::new(self.desugar_pattern(block.into_iter()))
}
// TODO: nested function pattern // TODO: nested function pattern
/// `[i, j] = [1, 2]` -> `i = 1; j = 2` /// `[i, j] = [1, 2]` -> `i = 1; j = 2`
/// `[i, j] = l` -> `i = l[0]; j = l[1]` /// `[i, j] = l` -> `i = l[0]; j = l[1]`
/// `[i, [j, k]] = l` -> `i = l[0]; j = l[1][0]; k = l[1][1]` /// `[i, [j, k]] = l` -> `i = l[0]; j = l[1][0]; k = l[1][1]`
/// `(i, j) = t` -> `i = t.0; j = t.1` /// `(i, j) = t` -> `i = t.0; j = t.1`
/// `{i; j} = s` -> `i = s.i; j = s.j` /// `{i; j} = s` -> `i = s.i; j = s.j`
fn desugar_pattern(&mut self, mut module: Module) -> Module { fn desugar_pattern<I>(&mut self, chunks: I) -> Vec<Expr>
let mut new = Module::with_capacity(module.len()); where
while let Some(chunk) = module.lpop() { I: IntoIterator<Item = Expr> + ExactSizeIterator,
{
let mut new = Vec::with_capacity(chunks.len());
for chunk in chunks.into_iter() {
match chunk { match chunk {
Expr::Def(Def { Expr::Def(Def {
sig: Signature::Var(v), sig: Signature::Var(v),
@ -465,6 +477,7 @@ impl Desugarer {
.into_iter() .into_iter()
.map(|ex| self.rec_desugar_lambda_pattern(ex)) .map(|ex| self.rec_desugar_lambda_pattern(ex))
.collect(); .collect();
let block = self.desugar_pattern_in_block(block);
let buf_def = Def::new(buf_sig, DefBody::new(body.op, block, body.id)); let buf_def = Def::new(buf_sig, DefBody::new(body.op, block, body.id));
new.push(Expr::Def(buf_def)); new.push(Expr::Def(buf_def));
for (n, elem) in tup.elems.iter().enumerate() { for (n, elem) in tup.elems.iter().enumerate() {
@ -484,6 +497,7 @@ impl Desugarer {
.into_iter() .into_iter()
.map(|ex| self.rec_desugar_lambda_pattern(ex)) .map(|ex| self.rec_desugar_lambda_pattern(ex))
.collect(); .collect();
let block = self.desugar_pattern_in_block(block);
let buf_def = Def::new(buf_sig, DefBody::new(body.op, block, body.id)); let buf_def = Def::new(buf_sig, DefBody::new(body.op, block, body.id));
new.push(Expr::Def(buf_def)); new.push(Expr::Def(buf_def));
for (n, elem) in arr.elems.iter().enumerate() { for (n, elem) in arr.elems.iter().enumerate() {
@ -503,6 +517,7 @@ impl Desugarer {
.into_iter() .into_iter()
.map(|ex| self.rec_desugar_lambda_pattern(ex)) .map(|ex| self.rec_desugar_lambda_pattern(ex))
.collect(); .collect();
let block = self.desugar_pattern_in_block(block);
let buf_def = Def::new(buf_sig, DefBody::new(body.op, block, body.id)); let buf_def = Def::new(buf_sig, DefBody::new(body.op, block, body.id));
new.push(Expr::Def(buf_def)); new.push(Expr::Def(buf_def));
for VarRecordAttr { lhs, rhs } in rec.attrs.iter() { for VarRecordAttr { lhs, rhs } in rec.attrs.iter() {
@ -524,6 +539,7 @@ impl Desugarer {
.into_iter() .into_iter()
.map(|ex| self.rec_desugar_lambda_pattern(ex)) .map(|ex| self.rec_desugar_lambda_pattern(ex))
.collect(); .collect();
let block = self.desugar_pattern_in_block(block);
let buf_def = Def::new(buf_sig, DefBody::new(body.op, block, body.id)); let buf_def = Def::new(buf_sig, DefBody::new(body.op, block, body.id));
new.push(Expr::Def(buf_def)); new.push(Expr::Def(buf_def));
for VarRecordAttr { lhs, rhs } in pack.args.attrs.iter() { for VarRecordAttr { lhs, rhs } in pack.args.attrs.iter() {
@ -541,6 +557,7 @@ impl Desugarer {
.into_iter() .into_iter()
.map(|ex| self.rec_desugar_lambda_pattern(ex)) .map(|ex| self.rec_desugar_lambda_pattern(ex))
.collect(); .collect();
let block = self.desugar_pattern_in_block(block);
let body = DefBody::new(body.op, block, body.id); let body = DefBody::new(body.op, block, body.id);
let def = Def::new(Signature::Var(v), body); let def = Def::new(Signature::Var(v), body);
new.push(Expr::Def(def)); new.push(Expr::Def(def));
@ -559,6 +576,7 @@ impl Desugarer {
.into_iter() .into_iter()
.map(|ex| self.rec_desugar_lambda_pattern(ex)) .map(|ex| self.rec_desugar_lambda_pattern(ex))
.collect(); .collect();
let block = self.desugar_pattern_in_block(block);
let body = DefBody::new(body.op, block, body.id); let body = DefBody::new(body.op, block, body.id);
let def = Def::new(Signature::Subr(subr), body); let def = Def::new(Signature::Subr(subr), body);
new.push(Expr::Def(def)); new.push(Expr::Def(def));
@ -573,7 +591,7 @@ impl Desugarer {
fn desugar_nested_var_pattern( fn desugar_nested_var_pattern(
&mut self, &mut self,
new_module: &mut Module, new_module: &mut Vec<Expr>,
sig: &VarSignature, sig: &VarSignature,
buf_name: &str, buf_name: &str,
buf_index: BufIndex, buf_index: BufIndex,