1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
use nom::{ branch::alt, bytes::complete::tag, character::complete::char, character::complete::{alpha1, alphanumeric1, multispace0, multispace1}, combinator::{eof, map, opt, recognize}, error::{ContextError, ParseError}, multi::{many0, separated_list0}, sequence::{delimited, pair, preceded}, IResult, }; use crate::types::{Argument, FnDecl, FnRetTy, Function, PrimitiveType, Query, QueryKind, Type}; type Symbol = String; pub fn parse_query<'a, E>(i: &'a str) -> IResult<&'a str, Query, E> where E: ParseError<&'a str> + ContextError<&'a str>, { parse_function_query(i) } fn parse_symbol<'a, E>(i: &'a str) -> IResult<&'a str, Symbol, E> where E: ParseError<&'a str> + ContextError<&'a str>, { map( recognize(pair( alt((tag("_"), alpha1)), many0(alt((tag("_"), alphanumeric1))), )), |symbol: &str| symbol.to_string(), )(i) } fn parse_function_query<'a, E>(i: &'a str) -> IResult<&'a str, Query, E> where E: ParseError<&'a str> + ContextError<&'a str>, { let (i, _) = tag("fn")(i)?; let (i, _) = multispace1(i)?; let (i, name) = opt(parse_symbol)(i)?; let (i, decl) = opt(parse_function)(i)?; let query = Query { name, kind: decl.map(QueryKind::FunctionQuery), }; Ok((i, query)) } fn parse_function<'a, E>(i: &'a str) -> IResult<&'a str, Function, E> where E: ParseError<&'a str> + ContextError<&'a str>, { let (i, decl) = parse_function_decl(i)?; let function = Function { decl }; Ok((i, function)) } fn parse_function_decl<'a, E>(i: &'a str) -> IResult<&'a str, FnDecl, E> where E: ParseError<&'a str> + ContextError<&'a str>, { let (i, inputs) = delimited( char('('), alt((map(tag(".."), |_| None), opt(parse_arguments))), char(')'), )(i)?; let (i, output) = alt((map(char('_'), |_| None), opt(parse_output)))(i)?; let decl = FnDecl { inputs, output }; Ok((i, decl)) } fn parse_arguments<'a, E>(i: &'a str) -> IResult<&'a str, Vec<Argument>, E> where E: ParseError<&'a str> + ContextError<&'a str>, { separated_list0( char(','), preceded( multispace0, alt(( parse_argument, map(char('_'), |_| Argument { ty: None, name: None, }), )), ), )(i) } fn parse_argument<'a, E>(i: &'a str) -> IResult<&'a str, Argument, E> where E: ParseError<&'a str> + ContextError<&'a str>, { let (i, name) = alt((map(char('_'), |_| None), opt(parse_symbol)))(i)?; let (i, _) = char(':')(i)?; let (i, _) = multispace0(i)?; let (i, ty) = alt((map(char('_'), |_| None), opt(parse_type)))(i)?; let arg = Argument { ty, name }; Ok((i, arg)) } fn parse_output<'a, E>(i: &'a str) -> IResult<&'a str, FnRetTy, E> where E: ParseError<&'a str> + ContextError<&'a str>, { preceded( multispace0, alt(( map(preceded(tag("->"), parse_type), FnRetTy::Return), map(eof, |_| FnRetTy::DefaultReturn), )), )(i) } fn parse_type<'a, E>(i: &'a str) -> IResult<&'a str, Type, E> where E: ParseError<&'a str> + ContextError<&'a str>, { preceded(multispace0, map(parse_primitive_type, Type::Primitive))(i) } fn parse_primitive_type<'a, E>(i: &'a str) -> IResult<&'a str, PrimitiveType, E> where E: ParseError<&'a str> + ContextError<&'a str>, { alt(( map(tag("isize"), |_| PrimitiveType::Isize), map(tag("usize"), |_| PrimitiveType::Usize), ))(i) }