sth
This commit is contained in:
parent
2c2322bb6c
commit
1846fe41ae
|
@ -8,6 +8,7 @@ use utils::default;
|
|||
mod syntax;
|
||||
mod utils;
|
||||
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut buf = default();
|
||||
stdin().read_to_string(&mut buf)?;
|
||||
|
|
|
@ -36,6 +36,7 @@ pub enum Expr<'a> {
|
|||
Match(ExprRef<'a>, &'a [(Spanned<Pattern>, SpanExpr<'a>)]),
|
||||
Set(ExprRef<'a>, ExprRef<'a>),
|
||||
Func(Ident, &'a [Spanned<Pattern>], ExprRef<'a>),
|
||||
Block(ExprList<'a>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
|
@ -57,7 +58,7 @@ pub enum BinaryOperator {
|
|||
Star,
|
||||
Slash,
|
||||
And,
|
||||
Or,
|
||||
VLine,
|
||||
Lt,
|
||||
Gt,
|
||||
Equ,
|
||||
|
@ -68,7 +69,7 @@ pub enum BinaryOperator {
|
|||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum UnaryOperator {
|
||||
Not,
|
||||
Neg,
|
||||
Deref,
|
||||
Tilde,
|
||||
Minus,
|
||||
Star,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::ast::{Literal, SpanExpr};
|
||||
use super::ast::{BinaryOperator, Literal, SpanExpr, UnaryOperator};
|
||||
|
||||
use {
|
||||
super::{
|
||||
|
@ -15,39 +15,70 @@ use {
|
|||
logos::Lexer,
|
||||
};
|
||||
|
||||
/// Equivalently-named unit variant mapping
|
||||
macro_rules! equivmap {
|
||||
($src:ident, $target:ident, [$variant0:ident $(, $variant:ident)* $(,)?] $(,)?) => {
|
||||
just($src::$variant0).to($target::$variant0)
|
||||
$(.or(just($src::$variant).to($target::$variant)))*
|
||||
};
|
||||
}
|
||||
|
||||
fn expr<'a, I>() -> impl Parser<'a, I, SpanExpr<'a>, Extra<'a>> + Clone
|
||||
where
|
||||
I: Input<'a, Token = Token, Span = SimpleSpan> + ValueInput<'a>,
|
||||
{
|
||||
recursive(|expr| {
|
||||
let ident = select!(Token::Ident(id) => Expr::Ident(id));
|
||||
let atom = {
|
||||
// Literal
|
||||
select! {
|
||||
Token::Int(a) => Literal::Integer(a),
|
||||
Token::String(a) => Literal::String(a)
|
||||
}
|
||||
.map(Expr::Literal)
|
||||
|
||||
let literal = select! {
|
||||
Token::Int(a) => Literal::Integer(a),
|
||||
Token::String(a) => Literal::String(a)
|
||||
}
|
||||
.or(ident)
|
||||
.map_with_span(Spanned::new)
|
||||
.or(expr
|
||||
.map(Expr::Literal);
|
||||
|
||||
let atom = literal.or(ident).map_with_span(Spanned::new).or(expr
|
||||
.clone()
|
||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen)));
|
||||
|
||||
let call = atom
|
||||
.clone()
|
||||
.pipe(arena_box)
|
||||
.then(
|
||||
.foldl_with_state(
|
||||
expr.clone()
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.pipe(arena_collect)
|
||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen))
|
||||
.map_with_span(Spanned::new)
|
||||
.repeated(),
|
||||
|expr, paramlist, state: &mut State| {
|
||||
Spanned::new(
|
||||
Expr::Call(state.arena.alloc(expr), paramlist.item),
|
||||
merge_spans(expr.span, paramlist.span),
|
||||
)
|
||||
},
|
||||
)
|
||||
.map(|(expr, params)| Expr::Call(expr, params));
|
||||
.boxed();
|
||||
|
||||
call.map_with_span(Spanned::new).or(atom)
|
||||
let unary = call;
|
||||
|
||||
let binary = unary.clone().foldl_with_state(
|
||||
equivmap!(
|
||||
Token,
|
||||
BinaryOperator,
|
||||
[Plus, Minus, Star, Slash, And, VLine, Lt, Gt, Equ, Nequ, LtEqu, GtEqu],
|
||||
)
|
||||
.map_with_span(Spanned::new)
|
||||
.then(unary)
|
||||
.repeated(),
|
||||
|l, (op, r), state: &mut State| {
|
||||
Spanned::new(
|
||||
Expr::Binary(op, state.arena.alloc(l), state.arena.alloc(r)),
|
||||
merge_spans(l.span, r.span),
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
binary.or(atom)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -105,3 +136,8 @@ where
|
|||
{
|
||||
parser.map_with_state(|item, _, state| &*state.arena.alloc(item))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn merge_spans(start: SimpleSpan, end: SimpleSpan) -> SimpleSpan {
|
||||
SimpleSpan::new(start.start, end.end)
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ pub enum Token {
|
|||
#[token("*")] Star,
|
||||
#[token("/")] Slash,
|
||||
#[token("&")] And,
|
||||
#[token("|")] Or,
|
||||
#[token("|")] VLine,
|
||||
#[token("~")] Tilde,
|
||||
|
||||
#[token("<")] Lt,
|
||||
|
|
Loading…
Reference in a new issue