A lot of stuff around identifiers
This commit is contained in:
parent
e2fc454c82
commit
a6d065864c
@ -4,28 +4,45 @@ use std::rc::Rc;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
use nom::character::complete::{one_of, space0};
|
use nom::character::complete::{one_of, space0, alphanumeric0};
|
||||||
use nom::bytes::complete::{tag, take_while, take_until};
|
use nom::bytes::complete::{tag, take, take_while, take_until};
|
||||||
use nom::combinator::{map, map_res, value, opt};
|
use nom::combinator::{map, map_res, value, opt, verify};
|
||||||
use nom::multi::many1;
|
use nom::multi::{separated_list, many1, many0};
|
||||||
use nom::error::{ParseError, ErrorKind};
|
//use nom::error::{ParseError, ErrorKind};
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::sequence::delimited;
|
use nom::sequence::{pair, delimited};
|
||||||
|
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::builtin::Builtin;
|
use crate::builtin::Builtin;
|
||||||
|
|
||||||
|
|
||||||
const OPERATOR_CHARS: &'static str = "~`!@#$%^&*-+=<>?/|";
|
fn single_alphabetic_character(text: &str) -> IResult<&str, char> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn single_alphanumeric_character(text: &str) -> IResult<&str, char> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn identifier(text: &str) -> IResult<&str, Rc<String>> {
|
||||||
|
use nom::character::complete::char;
|
||||||
|
map(alt((
|
||||||
|
pair(char('_'), many1(single_alphanumeric_character)),
|
||||||
|
pair(single_alphabetic_character, many0(single_alphanumeric_character))
|
||||||
|
)),
|
||||||
|
|(first, rest): (char, Vec<char>)| Rc::new(format!("{}{}", first, rest.into_iter().collect::<String>()))
|
||||||
|
)(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
const OPERATOR_CHARS: &'static str = "~`!@#$%^&*-+=<>?/|";
|
||||||
fn parse_binop(input: &str) -> IResult<&str, BinOp> {
|
fn parse_binop(input: &str) -> IResult<&str, BinOp> {
|
||||||
use nom::character::complete::one_of;
|
|
||||||
let (rest, op): (_, Vec<char>) = many1(one_of(OPERATOR_CHARS))(input)?;
|
let (rest, op): (_, Vec<char>) = many1(one_of(OPERATOR_CHARS))(input)?;
|
||||||
let sigil: String = op.into_iter().collect();
|
let sigil: String = op.into_iter().collect();
|
||||||
Ok((rest, BinOp::from_sigil(&sigil)))
|
Ok((rest, BinOp::from_sigil(&sigil)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn parse_bool_literal(input: &str) -> IResult<&str, ExpressionKind> {
|
fn parse_bool_literal(input: &str) -> IResult<&str, ExpressionKind> {
|
||||||
let p = alt((
|
let p = alt((
|
||||||
value(true, tag("true")),
|
value(true, tag("true")),
|
||||||
@ -79,7 +96,7 @@ fn parse_string_literal(text: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
Ok((text, expr))
|
Ok((text, expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_literal(input: &str) -> IResult<&str, ExpressionKind> {
|
fn literal(input: &str) -> IResult<&str, ExpressionKind> {
|
||||||
alt((
|
alt((
|
||||||
parse_string_literal,
|
parse_string_literal,
|
||||||
parse_hex_literal,
|
parse_hex_literal,
|
||||||
@ -100,11 +117,45 @@ fn prefix_op(input: &str) -> IResult<&str, PrefixOp> {
|
|||||||
map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(input)
|
map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn primary_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
||||||
|
// primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_expr | lambda_expr | anonymous_struct | list_expr
|
||||||
|
|
||||||
|
alt((
|
||||||
|
literal,
|
||||||
|
paren_expr,
|
||||||
|
))(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn invocation_argument(text: &str) -> IResult<&str, InvocationArgument> {
|
||||||
|
use nom::character::complete::char;
|
||||||
|
alt((
|
||||||
|
value(InvocationArgument::Ignored, pair(char('_'), alphanumeric0)),
|
||||||
|
map(expression_kind, |kind: ExpressionKind| InvocationArgument::Positional(
|
||||||
|
Expression { id: ItemId::new(0), kind, type_anno: None }))
|
||||||
|
//map(identifier, |id: Rc<String>|
|
||||||
|
))(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
||||||
|
use nom::character::complete::char;
|
||||||
|
let (text, expr) = primary_expr(text)?;
|
||||||
|
let (text, call_part) = opt(
|
||||||
|
delimited(char('('), separated_list(char(','), invocation_argument), char(')'))
|
||||||
|
)(text)?;
|
||||||
|
let output = if let Some(arguments) = call_part {
|
||||||
|
let f = bx!(Expression { id: ItemId::new(0), kind: expr, type_anno: None });
|
||||||
|
ExpressionKind::Call { f, arguments }
|
||||||
|
} else {
|
||||||
|
expr
|
||||||
|
};
|
||||||
|
Ok((text, output))
|
||||||
|
}
|
||||||
|
|
||||||
fn prefix_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
fn prefix_expr(text: &str) -> IResult<&str, ExpressionKind> {
|
||||||
let (text, pfx) = delimited(space0, opt(prefix_op), space0)(text)?;
|
let (text, pfx) = delimited(space0, opt(prefix_op), space0)(text)?;
|
||||||
let (text, result) = alt((
|
let (text, result) = alt((
|
||||||
paren_expr,
|
paren_expr,
|
||||||
parse_literal
|
literal,
|
||||||
))(text)?;
|
))(text)?;
|
||||||
match pfx {
|
match pfx {
|
||||||
None => Ok((text, result)),
|
None => Ok((text, result)),
|
||||||
@ -145,6 +196,7 @@ fn expression_kind(input: &str) -> IResult<&str, ExpressionKind> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_parsing(input: &str) -> Result<String, String> {
|
pub fn perform_parsing(input: &str) -> Result<String, String> {
|
||||||
let output = expression_kind(input);
|
//let output = expression_kind(input);
|
||||||
|
let output = identifier(input);
|
||||||
Ok(format!("{:?}", output))
|
Ok(format!("{:?}", output))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user