Type alias
This commit is contained in:
parent
43cad55735
commit
16559d2e55
@ -15,18 +15,20 @@ use nom::sequence::{pair, delimited};
|
|||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::builtin::Builtin;
|
use crate::builtin::Builtin;
|
||||||
|
|
||||||
|
type ParseResult<'a, T> = IResult<&'a str, T>;
|
||||||
|
|
||||||
fn single_alphabetic_character(text: &str) -> IResult<&str, char> {
|
|
||||||
|
fn single_alphabetic_character(text: &str) -> ParseResult<char> {
|
||||||
let p = verify(take(1usize), |s: &str| s.chars().nth(0).map(|c| c.is_alphabetic()).unwrap_or(false));
|
let p = verify(take(1usize), |s: &str| s.chars().nth(0).map(|c| c.is_alphabetic()).unwrap_or(false));
|
||||||
map(p, |s: &str| s.chars().nth(0).unwrap())(text)
|
map(p, |s: &str| s.chars().nth(0).unwrap())(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn single_alphanumeric_character(text: &str) -> IResult<&str, char> {
|
fn single_alphanumeric_character(text: &str) -> ParseResult<char> {
|
||||||
let p = verify(take(1usize), |s: &str| s.chars().nth(0).map(|c| c.is_alphanumeric() || c == '_').unwrap_or(false));
|
let p = verify(take(1usize), |s: &str| s.chars().nth(0).map(|c| c.is_alphanumeric() || c == '_').unwrap_or(false));
|
||||||
map(p, |s: &str| s.chars().nth(0).unwrap())(text)
|
map(p, |s: &str| s.chars().nth(0).unwrap())(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identifier(text: &str) -> IResult<&str, Rc<String>> {
|
fn identifier(text: &str) -> ParseResult<Rc<String>> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
map(alt((
|
map(alt((
|
||||||
pair(char('_'), many1(single_alphanumeric_character)),
|
pair(char('_'), many1(single_alphanumeric_character)),
|
||||||
@ -37,37 +39,37 @@ fn identifier(text: &str) -> IResult<&str, Rc<String>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const OPERATOR_CHARS: &'static str = "~`!@#$%^&*-+=<>?/|";
|
const OPERATOR_CHARS: &'static str = "~`!@#$%^&*-+=<>?/|";
|
||||||
fn parse_binop(input: &str) -> IResult<&str, BinOp> {
|
fn parse_binop(text: &str) -> ParseResult<BinOp> {
|
||||||
let (rest, op): (_, Vec<char>) = many1(one_of(OPERATOR_CHARS))(input)?;
|
let (text, op): (_, Vec<char>) = many1(one_of(OPERATOR_CHARS))(text)?;
|
||||||
let sigil: String = op.into_iter().collect();
|
let sigil: String = op.into_iter().collect();
|
||||||
Ok((rest, BinOp::from_sigil(&sigil)))
|
Ok((text, BinOp::from_sigil(&sigil)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_bool_literal(input: &str) -> IResult<&str, ExpressionKind> {
|
fn parse_bool_literal(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
let p = alt((
|
let p = alt((
|
||||||
value(true, tag("true")),
|
value(true, tag("true")),
|
||||||
value(false, tag("false"))
|
value(false, tag("false"))
|
||||||
));
|
));
|
||||||
map(p, ExpressionKind::BoolLiteral)(input)
|
map(p, ExpressionKind::BoolLiteral)(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_number_literal(input: &str) -> IResult<&str, ExpressionKind> {
|
fn parse_number_literal(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
let num_lit = many1(alt((
|
let num_lit = many1(alt((
|
||||||
map(one_of("1234567890"), |s: char| Some(s)),
|
map(one_of("1234567890"), |s: char| Some(s)),
|
||||||
map(nom::character::complete::char('_'), |_| None)
|
map(nom::character::complete::char('_'), |_| None)
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let (rest, n) = map_res(num_lit,
|
let (text, n) = map_res(num_lit,
|
||||||
|digits: Vec<Option<char>>| {
|
|digits: Vec<Option<char>>| {
|
||||||
let num_str: String = digits.into_iter().filter_map(|x| x).collect();
|
let num_str: String = digits.into_iter().filter_map(|x| x).collect();
|
||||||
u64::from_str_radix(&num_str, 10)
|
u64::from_str_radix(&num_str, 10)
|
||||||
})(input)?;
|
})(text)?;
|
||||||
|
|
||||||
Ok((rest, ExpressionKind::NatLiteral(n)))
|
Ok((text, ExpressionKind::NatLiteral(n)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn parse_binary_literal(input: &str) -> IResult<&str, ExpressionKind> {
|
fn parse_binary_literal(input: &str) -> ParseResult<ExpressionKind> {
|
||||||
let (rest, _) = tag("0b")(input)?;
|
let (rest, _) = tag("0b")(input)?;
|
||||||
let (rest, n): (&str, u64) = map_res(
|
let (rest, n): (&str, u64) = map_res(
|
||||||
take_while(|c: char| c == '0' || c == '1'),
|
take_while(|c: char| c == '0' || c == '1'),
|
||||||
@ -77,7 +79,7 @@ fn parse_binary_literal(input: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
Ok((rest, expr))
|
Ok((rest, expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_hex_literal(input: &str) -> IResult<&str, ExpressionKind> {
|
fn parse_hex_literal(input: &str) -> ParseResult<ExpressionKind> {
|
||||||
let (rest, _) = tag("0x")(input)?;
|
let (rest, _) = tag("0x")(input)?;
|
||||||
let (rest, n): (&str, u64) = map_res(
|
let (rest, n): (&str, u64) = map_res(
|
||||||
take_while(|c: char| c.is_digit(16)),
|
take_while(|c: char| c.is_digit(16)),
|
||||||
@ -87,7 +89,7 @@ fn parse_hex_literal(input: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
Ok((rest, expr))
|
Ok((rest, expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_string_literal(text: &str) -> IResult<&str, ExpressionKind> {
|
fn parse_string_literal(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
let (text, string_output) = delimited(
|
let (text, string_output) = delimited(
|
||||||
char('"'), take_until("\""), char('"')
|
char('"'), take_until("\""), char('"')
|
||||||
@ -96,7 +98,7 @@ fn parse_string_literal(text: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
Ok((text, expr))
|
Ok((text, expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn literal(input: &str) -> IResult<&str, ExpressionKind> {
|
fn literal(input: &str) -> ParseResult<ExpressionKind> {
|
||||||
alt((
|
alt((
|
||||||
parse_string_literal,
|
parse_string_literal,
|
||||||
parse_hex_literal,
|
parse_hex_literal,
|
||||||
@ -106,18 +108,18 @@ fn literal(input: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paren_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
fn paren_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
delimited(char('('), expression_kind, char(')'))(text)
|
delimited(char('('), expression_kind, char(')'))(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix_op(input: &str) -> IResult<&str, PrefixOp> {
|
fn prefix_op(input: &str) -> ParseResult<PrefixOp> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
let p = alt((char('+'), char('-'), char('!')));
|
let p = alt((char('+'), char('-'), char('!')));
|
||||||
map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(input)
|
map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identifier_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
fn identifier_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
let (text, qualified_identifier) = map(
|
let (text, qualified_identifier) = map(
|
||||||
qualified_identifier_list,
|
qualified_identifier_list,
|
||||||
|components| QualifiedName { id: ItemId::new(0), components }
|
|components| QualifiedName { id: ItemId::new(0), components }
|
||||||
@ -127,11 +129,11 @@ fn identifier_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
Ok((text, exp.kind))
|
Ok((text, exp.kind))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn qualified_identifier_list(text: &str) -> IResult<&str, Vec<Rc<String>>> {
|
fn qualified_identifier_list(text: &str) -> ParseResult<Vec<Rc<String>>> {
|
||||||
separated_nonempty_list(tag("::"), identifier)(text)
|
separated_nonempty_list(tag("::"), identifier)(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
fn primary_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
// primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_expr | lambda_expr | anonymous_struct | list_expr
|
// primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_expr | lambda_expr | anonymous_struct | list_expr
|
||||||
|
|
||||||
alt((
|
alt((
|
||||||
@ -141,7 +143,7 @@ fn primary_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
))(text)
|
))(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invocation_argument(text: &str) -> IResult<&str, InvocationArgument> {
|
fn invocation_argument(text: &str) -> ParseResult<InvocationArgument> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
alt((
|
alt((
|
||||||
value(InvocationArgument::Ignored, pair(char('_'), alphanumeric0)),
|
value(InvocationArgument::Ignored, pair(char('_'), alphanumeric0)),
|
||||||
@ -151,7 +153,7 @@ fn invocation_argument(text: &str) -> IResult<&str, InvocationArgument> {
|
|||||||
))(text)
|
))(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
fn call_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
let (text, expr) = primary_expr(text)?;
|
let (text, expr) = primary_expr(text)?;
|
||||||
let (text, call_part) = opt(
|
let (text, call_part) = opt(
|
||||||
@ -166,7 +168,7 @@ fn call_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
Ok((text, output))
|
Ok((text, output))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
fn prefix_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
let (text, pfx) = delimited(space0, opt(prefix_op), space0)(text)?;
|
let (text, pfx) = delimited(space0, opt(prefix_op), space0)(text)?;
|
||||||
let (text, result) = call_expr(text)?;
|
let (text, result) = call_expr(text)?;
|
||||||
match pfx {
|
match pfx {
|
||||||
@ -179,7 +181,7 @@ fn prefix_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this implements Pratt parsing, see http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
// this implements Pratt parsing, see http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
||||||
fn precedence_expr(input: &str, precedence: i32) -> IResult<&str, ExpressionKind> {
|
fn precedence_expr(input: &str, precedence: i32) -> ParseResult<ExpressionKind> {
|
||||||
let (mut outer_rest, mut lhs) = prefix_expr(input)?;
|
let (mut outer_rest, mut lhs) = prefix_expr(input)?;
|
||||||
loop {
|
loop {
|
||||||
let (rest, _) = space0(outer_rest)?;
|
let (rest, _) = space0(outer_rest)?;
|
||||||
@ -203,7 +205,7 @@ fn precedence_expr(input: &str, precedence: i32) -> IResult<&str, ExpressionKind
|
|||||||
Ok((outer_rest, lhs))
|
Ok((outer_rest, lhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expression_kind(input: &str) -> IResult<&str, ExpressionKind> {
|
fn expression_kind(input: &str) -> ParseResult<ExpressionKind> {
|
||||||
precedence_expr(input, BinOp::min_precedence())
|
precedence_expr(input, BinOp::min_precedence())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user