From ce848906c98f7abcfa6d5e0f2b2ae57ba18fd42c Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 7 Mar 2020 03:26:32 -0800 Subject: [PATCH] More work --- schala-lang/language/src/parser.rs | 45 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/schala-lang/language/src/parser.rs b/schala-lang/language/src/parser.rs index 3064d11..6ec0eb0 100644 --- a/schala-lang/language/src/parser.rs +++ b/schala-lang/language/src/parser.rs @@ -5,12 +5,12 @@ use std::str::FromStr; use nom::IResult; use nom::character::complete::{one_of, space0, alphanumeric0}; -use nom::bytes::complete::{tag, take, take_while, take_until}; +use nom::bytes::complete::{tag, take, take_while, take_while1, take_until}; use nom::combinator::{map, map_res, value, opt, verify}; use nom::multi::{separated_list, separated_nonempty_list, many1, many0}; use nom::error::{context, VerboseError}; use nom::branch::alt; -use nom::sequence::{pair, delimited}; +use nom::sequence::{pair, delimited, preceded}; use crate::ast::*; use crate::builtin::Builtin; @@ -40,12 +40,12 @@ fn identifier(text: &str) -> ParseResult> { const OPERATOR_CHARS: &'static str = "~`!@#$%^&*-+=<>?/|"; fn parse_binop(text: &str) -> ParseResult { - let (text, op): (_, Vec) = context("binop yo", many1(one_of(OPERATOR_CHARS)))(text)?; + let (text, op): (_, Vec) = context("Binop", many1(one_of(OPERATOR_CHARS)))(text)?; let sigil: String = op.into_iter().collect(); Ok((text, BinOp::from_sigil(&sigil))) } -fn parse_bool_literal(text: &str) -> ParseResult { +fn bool_literal(text: &str) -> ParseResult { let p = alt(( value(true, tag("true")), value(false, tag("false")) @@ -53,7 +53,7 @@ fn parse_bool_literal(text: &str) -> ParseResult { map(p, ExpressionKind::BoolLiteral)(text) } -fn parse_number_literal(text: &str) -> ParseResult { +fn number_literal(text: &str) -> ParseResult { let num_lit = many1(alt(( map(one_of("1234567890"), |s: char| Some(s)), map(nom::character::complete::char('_'), |_| None) @@ -69,27 +69,25 @@ fn parse_number_literal(text: &str) -> ParseResult { } -fn parse_binary_literal(input: &str) -> ParseResult { - let (rest, _) = tag("0b")(input)?; +fn binary_literal(input: &str) -> ParseResult { + let p = preceded(tag("0b"), take_while1(|c: char| c == '0' || c == '1')); let (rest, n): (&str, u64) = map_res( - take_while(|c: char| c == '0' || c == '1'), - |hex_str: &str| u64::from_str_radix(hex_str, 2) - )(rest)?; + p, |hex_str: &str| u64::from_str_radix(hex_str, 2) + )(input)?; let expr = ExpressionKind::NatLiteral(n); Ok((rest, expr)) } -fn parse_hex_literal(input: &str) -> ParseResult { - let (rest, _) = tag("0x")(input)?; +fn hex_literal(input: &str) -> ParseResult { + let p = preceded(tag("0x"), take_while1(|c: char| c.is_digit(16))); let (rest, n): (&str, u64) = map_res( - take_while(|c: char| c.is_digit(16)), - |hex_str: &str| u64::from_str_radix(hex_str, 16) - )(rest)?; + p, |hex_str: &str| u64::from_str_radix(hex_str, 16) + )(input)?; let expr = ExpressionKind::NatLiteral(n); Ok((rest, expr)) } -fn parse_string_literal(text: &str) -> ParseResult { +fn string_literal(text: &str) -> ParseResult { use nom::character::complete::char; let (text, string_output) = delimited( char('"'), take_until("\""), char('"') @@ -100,11 +98,11 @@ fn parse_string_literal(text: &str) -> ParseResult { fn literal(input: &str) -> ParseResult { alt(( - parse_string_literal, - parse_hex_literal, - parse_binary_literal, - parse_number_literal, - parse_bool_literal + string_literal, + hex_literal, + binary_literal, + number_literal, + bool_literal ))(input) } @@ -216,10 +214,11 @@ fn expression_kind(text: &str) -> ParseResult { pub fn perform_parsing(input: &str) -> Result { let output = match expression_kind(input) { - Ok((rest, ast)) => format!("{:?}", ast), + Ok((rest, ast)) => format!("{:?} (rest: {})", ast, rest), Err(nom::Err::Incomplete(needed)) => format!("Incomplete: {:?}" ,needed), Err(nom::Err::Error(verbose_error) | nom::Err::Failure(verbose_error)) => { - nom::error::convert_error(input, verbose_error) + format!("Verbose Error: ` {:?} `", verbose_error) + //nom::error::convert_error(input, verbose_error) } };