MOre work

This commit is contained in:
Greg Shuflin 2021-11-17 16:44:09 -08:00
parent d37be75478
commit c1e6bc8c4c
1 changed files with 69 additions and 1 deletions

View File

@ -32,6 +32,11 @@ fn fresh_id(span: &Span) -> Id<ASTItem> {
table_handle.fresh()
}
fn fresh_id_rc(store_ref: &StoreRef) -> Id<ASTItem> {
let mut table_handle = store_ref.borrow_mut();
table_handle.fresh()
}
fn tok<'a, O>(
input_parser: impl Parser<Span<'a>, O, VerboseError<Span<'a>>>,
) -> impl FnMut(Span<'a>) -> IResult<Span<'a>, O, VerboseError<Span<'a>>> {
@ -127,7 +132,50 @@ fn type_singleton_name(input: Span) -> ParseResult<TypeSingletonName> {
}
pub fn expression_kind(input: Span) -> ParseResult<ExpressionKind> {
context("expression-kind", primary_expr)(input)
context("expression-kind", prefix_expr)(input)
}
fn precedence_expr(input: Span) -> ParseResult<ExpressionKind> {
map(pair(prefix_expr, many0(precedence_continuation)),
|(first, rest): (ExpressionKind, Vec<(BinOp, ExpressionKind)>)| unimplemented!())(input)
}
fn precedence_continuation(input: Span) -> ParseResult<(BinOp, ExpressionKind)> {
pair(operator, prefix_expr)(input)
}
fn operator(input: Span) -> ParseResult<BinOp> {
tok(
map(
tuple((
not(tag("*/")),
recognize(many1(one_of("+-*/%<>=!$&|?^`"))),
)), |(_, sigil_span): ((), Span)| BinOp::from_sigil(sigil_span.fragment())))(input)
}
fn prefix_op(input: Span) -> ParseResult<PrefixOp> {
tok(
map(recognize(one_of("+-!")),
|sigil: Span| PrefixOp::from_sigil(sigil.fragment())))(input)
}
fn prefix_expr(input: Span) -> ParseResult<ExpressionKind> {
let handle = input.extra.clone();
context("prefix-expr",
map(
pair(opt(prefix_op), extended_expr), move |(prefix, expr)| {
if let Some(prefix) = prefix {
let expr = Expression::new(fresh_id_rc(&handle), expr);
ExpressionKind::PrefixExp(prefix, Box::new(expr))
} else {
expr
}
}))(input)
}
fn extended_expr(input: Span) -> ParseResult<ExpressionKind> {
context("extended-expr",
primary_expr)(input)
}
fn primary_expr(input: Span) -> ParseResult<ExpressionKind> {
@ -295,6 +343,26 @@ mod test {
span!(expression_kind, " /*yolo*/ barnaby").unwrap().1,
ExpressionKind::Value(qn!(barnaby))
);
let source = "!4";
let parsed = span!(expression_kind, source).map_err(|err| match err {
Err::Error(err) | Err::Failure(err) => {
let err = VerboseError {
errors: err.errors.into_iter().map(|(sp, kind)| (*sp.fragment(), kind)).collect(),
};
nom::error::convert_error(source, err)
}
_ => panic!(),
});
if let Err(err) = parsed {
println!("{}", err);
panic!("parse error desu!");
}
assert_eq!(parsed.unwrap().1, ExpressionKind::PrefixExp(PrefixOp::from_sigil("!"),
Box::new(Expression::new(Default::default(), ExpressionKind::NatLiteral(4)))));
}
#[test]