Fix some panics on parsing error paths

This commit is contained in:
Nick Fitzgerald
2021-09-28 16:12:07 -07:00
committed by Chris Fallin
parent 6a523938de
commit f2b6244b9c

View File

@@ -51,8 +51,10 @@ impl<'a> Parser<'a> {
}
}
fn pos(&self) -> Option<Pos> {
self.lexer.peek().map(|(pos, _)| *pos)
fn pos(&self) -> Pos {
self.lexer
.peek()
.map_or_else(|| self.lexer.pos(), |(pos, _)| *pos)
}
fn is_lparen(&self) -> bool {
@@ -137,7 +139,7 @@ impl<'a> Parser<'a> {
"extractor" => Def::Extractor(self.parse_etor()?),
"extern" => Def::Extern(self.parse_extern()?),
s => {
return Err(self.error(pos.unwrap(), format!("Unexpected identifier: {}", s)));
return Err(self.error(pos, format!("Unexpected identifier: {}", s)));
}
};
self.rparen()?;
@@ -170,7 +172,7 @@ impl<'a> Parser<'a> {
fn parse_ident(&mut self) -> ParseResult<Ident> {
let pos = self.pos();
let s = self.symbol()?;
self.str_to_ident(pos.unwrap(), &s)
self.str_to_ident(pos, &s)
}
fn parse_const(&mut self) -> ParseResult<Ident> {
@@ -181,7 +183,7 @@ impl<'a> Parser<'a> {
Ok(Ident(s.to_string(), ident.1))
} else {
Err(self.error(
pos.unwrap(),
pos,
"Not a constant identifier; must start with a '$'".to_string(),
))
}
@@ -200,7 +202,7 @@ impl<'a> Parser<'a> {
name,
is_extern,
ty,
pos: pos.unwrap(),
pos,
})
}
@@ -211,7 +213,6 @@ impl<'a> Parser<'a> {
self.symbol()?;
let primitive_ident = self.parse_ident()?;
self.rparen()?;
let pos = pos.unwrap();
Ok(TypeValue::Primitive(primitive_ident, pos))
} else if self.is_sym_str("enum") {
self.symbol()?;
@@ -221,16 +222,15 @@ impl<'a> Parser<'a> {
variants.push(variant);
}
self.rparen()?;
let pos = pos.unwrap();
Ok(TypeValue::Enum(variants, pos))
} else {
Err(self.error(pos.unwrap(), "Unknown type definition".to_string()))
Err(self.error(pos, "Unknown type definition".to_string()))
}
}
fn parse_type_variant(&mut self) -> ParseResult<Variant> {
if self.is_sym() {
let pos = self.pos().unwrap();
let pos = self.pos();
let name = self.parse_ident()?;
Ok(Variant {
name,
@@ -246,7 +246,6 @@ impl<'a> Parser<'a> {
fields.push(self.parse_type_field()?);
}
self.rparen()?;
let pos = pos.unwrap();
Ok(Variant { name, fields, pos })
}
}
@@ -257,7 +256,6 @@ impl<'a> Parser<'a> {
let name = self.parse_ident()?;
let ty = self.parse_ident()?;
self.rparen()?;
let pos = pos.unwrap();
Ok(Field { name, ty, pos })
}
@@ -278,7 +276,7 @@ impl<'a> Parser<'a> {
term,
arg_tys,
ret_ty,
pos: pos.unwrap(),
pos,
})
}
@@ -288,11 +286,7 @@ impl<'a> Parser<'a> {
self.symbol()?;
let term = self.parse_ident()?;
let func = self.parse_ident()?;
Ok(Extern::Constructor {
term,
func,
pos: pos.unwrap(),
})
Ok(Extern::Constructor { term, func, pos })
} else if self.is_sym_str("extractor") {
self.symbol()?;
@@ -317,9 +311,7 @@ impl<'a> Parser<'a> {
self.symbol()?;
pol.push(ArgPolarity::Output);
} else {
return Err(
self.error(pos.unwrap(), "Invalid argument polarity".to_string())
);
return Err(self.error(pos, "Invalid argument polarity".to_string()));
}
}
self.rparen()?;
@@ -330,7 +322,7 @@ impl<'a> Parser<'a> {
Ok(Extern::Extractor {
term,
func,
pos: pos.unwrap(),
pos,
arg_polarity,
infallible,
})
@@ -339,14 +331,10 @@ impl<'a> Parser<'a> {
let pos = self.pos();
let name = self.parse_const()?;
let ty = self.parse_ident()?;
Ok(Extern::Const {
name,
ty,
pos: pos.unwrap(),
})
Ok(Extern::Const { name, ty, pos })
} else {
Err(self.error(
pos.unwrap(),
pos,
"Invalid extern: must be (extern constructor ...) or (extern extractor ...)"
.to_string(),
))
@@ -367,7 +355,7 @@ impl<'a> Parser<'a> {
term,
args,
template,
pos: pos.unwrap(),
pos,
})
}
@@ -383,7 +371,7 @@ impl<'a> Parser<'a> {
Ok(Rule {
pattern,
expr,
pos: pos.unwrap(),
pos,
prio,
})
}
@@ -391,21 +379,17 @@ impl<'a> Parser<'a> {
fn parse_pattern(&mut self) -> ParseResult<Pattern> {
let pos = self.pos();
if self.is_int() {
let pos = pos.unwrap();
Ok(Pattern::ConstInt {
val: self.int()?,
pos,
})
} else if self.is_const() {
let pos = pos.unwrap();
let val = self.parse_const()?;
Ok(Pattern::ConstPrim { val, pos })
} else if self.is_sym_str("_") {
let pos = pos.unwrap();
self.symbol()?;
Ok(Pattern::Wildcard { pos })
} else if self.is_sym() {
let pos = pos.unwrap();
let s = self.symbol()?;
if s.starts_with("=") {
let s = &s[1..];
@@ -426,7 +410,6 @@ impl<'a> Parser<'a> {
}
}
} else if self.is_lparen() {
let pos = pos.unwrap();
self.lparen()?;
if self.is_sym_str("and") {
self.symbol()?;
@@ -446,7 +429,7 @@ impl<'a> Parser<'a> {
Ok(Pattern::Term { sym, args, pos })
}
} else {
Err(self.error(pos.unwrap(), "Unexpected pattern".into()))
Err(self.error(pos, "Unexpected pattern".into()))
}
}
@@ -462,7 +445,6 @@ impl<'a> Parser<'a> {
fn parse_expr(&mut self) -> ParseResult<Expr> {
let pos = self.pos();
if self.is_lparen() {
let pos = pos.unwrap();
self.lparen()?;
if self.is_sym_str("let") {
self.symbol()?;
@@ -486,34 +468,28 @@ impl<'a> Parser<'a> {
Ok(Expr::Term { sym, args, pos })
}
} else if self.is_sym_str("#t") {
let pos = pos.unwrap();
self.symbol()?;
Ok(Expr::ConstInt { val: 1, pos })
} else if self.is_sym_str("#f") {
let pos = pos.unwrap();
self.symbol()?;
Ok(Expr::ConstInt { val: 0, pos })
} else if self.is_const() {
let pos = pos.unwrap();
let val = self.parse_const()?;
Ok(Expr::ConstPrim { val, pos })
} else if self.is_sym() {
let pos = pos.unwrap();
let name = self.parse_ident()?;
Ok(Expr::Var { name, pos })
} else if self.is_int() {
let pos = pos.unwrap();
let val = self.int()?;
Ok(Expr::ConstInt { val, pos })
} else {
Err(self.error(pos.unwrap(), "Invalid expression".into()))
Err(self.error(pos, "Invalid expression".into()))
}
}
fn parse_letdef(&mut self) -> ParseResult<LetDef> {
let pos = self.pos();
self.lparen()?;
let pos = pos.unwrap();
let var = self.parse_ident()?;
let ty = self.parse_ident()?;
let val = Box::new(self.parse_expr()?);