From d034a99ac16e89f3a42ff3dd1406fdd47d7e2129 Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 7 Mar 2020 04:24:20 -0800 Subject: [PATCH] Some wording changes; added ws combinator --- schala-lang/language/src/parser.rs | 43 ++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/schala-lang/language/src/parser.rs b/schala-lang/language/src/parser.rs index 1b71802..b6e5eb8 100644 --- a/schala-lang/language/src/parser.rs +++ b/schala-lang/language/src/parser.rs @@ -8,7 +8,7 @@ use nom::character::complete::{one_of, space0, alphanumeric0}; use nom::bytes::complete::{tag, take, take_while, take_while1, take_until}; use nom::combinator::{cut, map, map_res, value, opt, verify}; use nom::multi::{separated_list, separated_nonempty_list, many1, many0}; -use nom::error::{context, VerboseError}; +use nom::error::{context, ParseError, VerboseError}; use nom::branch::alt; use nom::sequence::{pair, delimited, preceded}; @@ -18,6 +18,16 @@ use crate::builtin::Builtin; type ParseResult<'a, T> = IResult<&'a str, T, VerboseError<&'a str>>; +pub fn ws, F>(parser: F) -> impl Fn(I) -> IResult +where + I: nom::InputTakeAtPosition, + ::Item: nom::AsChar + Clone, + F: Fn(I) -> IResult, + { + delimited(space0, parser, space0) + } + + fn single_alphabetic_character(text: &str) -> ParseResult { 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) @@ -69,20 +79,20 @@ fn number_literal(text: &str) -> ParseResult { } -fn binary_literal(input: &str) -> ParseResult { +fn binary_literal(text: &str) -> ParseResult { let p = preceded(tag("0b"), cut(take_while1(|c: char| c == '0' || c == '1'))); let (rest, n): (&str, u64) = map_res( p, |hex_str: &str| u64::from_str_radix(hex_str, 2) - )(input)?; + )(text)?; let expr = ExpressionKind::NatLiteral(n); Ok((rest, expr)) } -fn hex_literal(input: &str) -> ParseResult { +fn hex_literal(text: &str) -> ParseResult { let p = preceded(tag("0x"), cut(take_while1(|c: char| c.is_digit(16)))); let (rest, n): (&str, u64) = map_res( p, |hex_str: &str| u64::from_str_radix(hex_str, 16) - )(input)?; + )(text)?; let expr = ExpressionKind::NatLiteral(n); Ok((rest, expr)) } @@ -96,14 +106,14 @@ fn string_literal(text: &str) -> ParseResult { Ok((text, expr)) } -fn literal(input: &str) -> ParseResult { +fn literal(text: &str) -> ParseResult { alt(( string_literal, hex_literal, binary_literal, number_literal, bool_literal, - ))(input) + ))(text) } fn paren_expr(text: &str) -> ParseResult { @@ -111,10 +121,10 @@ fn paren_expr(text: &str) -> ParseResult { context("Paren expression", delimited(char('('), expression_kind, char(')')))(text) } -fn prefix_op(input: &str) -> ParseResult { +fn prefix_op(text: &str) -> ParseResult { use nom::character::complete::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())(text) } fn identifier_expr(text: &str) -> ParseResult { @@ -167,7 +177,7 @@ fn call_expr(text: &str) -> ParseResult { } fn prefix_expr(text: &str) -> ParseResult { - let (text, pfx) = delimited(space0, opt(prefix_op), space0)(text)?; + let (text, pfx) = ws(opt(prefix_op))(text)?; let (text, result) = call_expr(text)?; match pfx { None => Ok((text, result)), @@ -209,9 +219,20 @@ fn precedence_expr(text: &str) -> ParseResult { } fn expression_kind(text: &str) -> ParseResult { - precedence_expr(text) + context("Expression kind", precedence_expr)(text) } +/* +fn type_anno(text: &str) -> ParseResult { + +} + +fn expression(text: &str) -> ParseResult { + let (rest, (kind, type_anno)) = pair(expression_kind, type_anno)(text)?; + Ok((rest, Expression::with_anno(ItemId::new(0), kind, type_anno))) +} +*/ + pub fn perform_parsing(input: &str) -> Result { let output = match expression_kind(input) { Ok((rest, ast)) => format!("{:?} (rest: {})", ast, rest),