Make a bunch of things more concise

This commit is contained in:
greg 2020-02-13 03:11:46 -08:00
parent 54649246b0
commit e2fc454c82

View File

@ -5,7 +5,7 @@ use std::str::FromStr;
use nom::IResult; use nom::IResult;
use nom::character::complete::{one_of, space0}; use nom::character::complete::{one_of, space0};
use nom::bytes::complete::{tag, take_while}; use nom::bytes::complete::{tag, take_while, take_until};
use nom::combinator::{map, map_res, value, opt}; use nom::combinator::{map, map_res, value, opt};
use nom::multi::many1; use nom::multi::many1;
use nom::error::{ParseError, ErrorKind}; use nom::error::{ParseError, ErrorKind};
@ -27,11 +27,11 @@ fn parse_binop(input: &str) -> IResult<&str, BinOp> {
fn parse_bool_literal(input: &str) -> IResult<&str, ExpressionKind> { fn parse_bool_literal(input: &str) -> IResult<&str, ExpressionKind> {
let (rest, value) = alt(( let p = alt((
value(true, tag("true")), value(true, tag("true")),
value(false, tag("false")) value(false, tag("false"))
))(input)?; ));
Ok((rest, ExpressionKind::BoolLiteral(value))) map(p, ExpressionKind::BoolLiteral)(input)
} }
fn parse_number_literal(input: &str) -> IResult<&str, ExpressionKind> { fn parse_number_literal(input: &str) -> IResult<&str, ExpressionKind> {
@ -71,9 +71,10 @@ fn parse_hex_literal(input: &str) -> IResult<&str, ExpressionKind> {
} }
fn parse_string_literal(text: &str) -> IResult<&str, ExpressionKind> { fn parse_string_literal(text: &str) -> IResult<&str, ExpressionKind> {
let (text, _) = nom::character::complete::char('"')(text)?; use nom::character::complete::char;
let (text, string_output) = nom::bytes::complete::take_until("\"")(text)?; let (text, string_output) = delimited(
let (text, _) = nom::character::complete::char('"')(text)?; char('"'), take_until("\""), char('"')
)(text)?;
let expr = ExpressionKind::StringLiteral(Rc::new(string_output.to_string())); let expr = ExpressionKind::StringLiteral(Rc::new(string_output.to_string()));
Ok((text, expr)) Ok((text, expr))
} }
@ -88,45 +89,28 @@ fn parse_literal(input: &str) -> IResult<&str, ExpressionKind> {
))(input) ))(input)
} }
fn paren_expr(input: &str) -> IResult<&str, ExpressionKind> { fn paren_expr(text: &str) -> IResult<&str, ExpressionKind> {
let (rest, _) = nom::character::complete::char('(')(input)?; use nom::character::complete::char;
let (rest, inner) = expression_kind(rest)?; delimited(char('('), expression_kind, char(')'))(text)
let (rest, _) = nom::character::complete::char(')')(rest)?;
Ok((rest, inner))
} }
fn prefix_op(input: &str) -> IResult<&str, PrefixOp> { fn prefix_op(input: &str) -> IResult<&str, PrefixOp> {
use nom::character::complete::char; use nom::character::complete::char;
let (rest, sigil) = alt(( let p = alt((char('+'), char('-'), char('!')));
char('+'), map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(input)
char('-'),
char('!')
))(input)?;
let op = PrefixOp::from_str(&sigil.to_string()).unwrap();
Ok((rest, op))
/*
alt((
value(Plus, char('+')),
value(Minus, char('-')),
value(Bang, char('!'))
))(input)
*/
} }
fn prefix_expr(input: &str) -> IResult<&str, ExpressionKind> { fn prefix_expr(text: &str) -> IResult<&str, ExpressionKind> {
let (rest, _) = space0(input)?; let (text, pfx) = delimited(space0, opt(prefix_op), space0)(text)?;
let (rest, pfx) = opt(prefix_op)(rest)?; let (text, result) = alt((
let (rest, _) = space0(rest)?;
let (rest, result) = alt((
paren_expr, paren_expr,
parse_literal parse_literal
))(rest)?; ))(text)?;
match pfx { match pfx {
None => Ok((rest, result)), None => Ok((text, result)),
Some(pfx) => { Some(pfx) => {
let exp = Expression { id: ItemId::new(0), kind: result, type_anno: None }; let exp = Expression { id: ItemId::new(0), kind: result, type_anno: None };
Ok((rest, ExpressionKind::PrefixExp(pfx, Box::new(exp)))) Ok((text, ExpressionKind::PrefixExp(pfx, Box::new(exp))))
} }
} }
} }