Start parsing expressions
This commit is contained in:
parent
991df5e026
commit
04417ea0f9
3 changed files with 55 additions and 52 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use chrono::{NaiveDate, NaiveDateTime};
|
||||
use chrono::NaiveDate;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Time {
|
||||
|
|
@ -76,7 +76,7 @@ pub struct WeekdaySpec {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IntVar {
|
||||
pub enum Var {
|
||||
/// `j`, see <https://en.wikipedia.org/wiki/Julian_day>
|
||||
JulianDay,
|
||||
/// `y`
|
||||
|
|
@ -141,24 +141,6 @@ pub enum IntVar {
|
|||
Saturday,
|
||||
/// `sun`, always 7
|
||||
Sunday,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IntExpr {
|
||||
Lit(i64),
|
||||
Var(IntVar),
|
||||
Paren(Box<IntVar>),
|
||||
Neg(Box<IntExpr>),
|
||||
Add(Box<IntExpr>, Box<IntExpr>),
|
||||
Sub(Box<IntExpr>, Box<IntExpr>),
|
||||
Mul(Box<IntExpr>, Box<IntExpr>),
|
||||
Div(Box<IntExpr>, Box<IntExpr>),
|
||||
Mod(Box<IntExpr>, Box<IntExpr>),
|
||||
Ternary(Box<BoolExpr>, Box<IntExpr>, Box<IntExpr>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BoolVar {
|
||||
/// `isWeekday`, whether the current day is one of mon-fri
|
||||
IsWeekday,
|
||||
/// `isWeekend`, whether the current day is one of sat-sun
|
||||
|
|
@ -168,27 +150,34 @@ pub enum BoolVar {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BoolExpr {
|
||||
Lit(bool),
|
||||
Var(BoolVar),
|
||||
Paren(Box<BoolVar>),
|
||||
Eq(Box<IntExpr>, Box<IntExpr>),
|
||||
Neq(Box<IntExpr>, Box<IntExpr>),
|
||||
Lt(Box<IntExpr>, Box<IntExpr>),
|
||||
Lte(Box<IntExpr>, Box<IntExpr>),
|
||||
Gt(Box<IntExpr>, Box<IntExpr>),
|
||||
Gte(Box<IntExpr>, Box<IntExpr>),
|
||||
Not(Box<BoolExpr>),
|
||||
And(Box<BoolExpr>, Box<BoolExpr>),
|
||||
Or(Box<BoolExpr>, Box<BoolExpr>),
|
||||
Xor(Box<BoolExpr>, Box<BoolExpr>),
|
||||
BEq(Box<BoolExpr>, Box<BoolExpr>),
|
||||
BNeq(Box<BoolExpr>, Box<BoolExpr>),
|
||||
pub enum Expr {
|
||||
Lit(i64),
|
||||
Var(Var),
|
||||
Paren(Box<Expr>),
|
||||
// Integer-y operations
|
||||
Neg(Box<Expr>),
|
||||
Add(Box<Expr>, Box<Expr>),
|
||||
Sub(Box<Expr>, Box<Expr>),
|
||||
Mul(Box<Expr>, Box<Expr>),
|
||||
Div(Box<Expr>, Box<Expr>),
|
||||
Mod(Box<Expr>, Box<Expr>),
|
||||
// Comparisons
|
||||
Eq(Box<Expr>, Box<Expr>),
|
||||
Neq(Box<Expr>, Box<Expr>),
|
||||
Lt(Box<Expr>, Box<Expr>),
|
||||
Lte(Box<Expr>, Box<Expr>),
|
||||
Gt(Box<Expr>, Box<Expr>),
|
||||
Gte(Box<Expr>, Box<Expr>),
|
||||
// Boolean-y operations
|
||||
Not(Box<Expr>),
|
||||
And(Box<Expr>, Box<Expr>),
|
||||
Or(Box<Expr>, Box<Expr>),
|
||||
Xor(Box<Expr>, Box<Expr>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FormulaSpec {
|
||||
pub start: Option<BoolExpr>, // None: *
|
||||
pub start: Option<Expr>, // None: *
|
||||
pub start_delta: Option<Delta>,
|
||||
pub start_time: Option<Time>,
|
||||
pub end: Option<Delta>,
|
||||
|
|
|
|||
31
src/parse.rs
31
src/parse.rs
|
|
@ -4,11 +4,12 @@ use std::result;
|
|||
use chrono::NaiveDate;
|
||||
use pest::error::{Error, ErrorVariant};
|
||||
use pest::iterators::Pair;
|
||||
use pest::prec_climber::PrecClimber;
|
||||
use pest::{Parser, Span};
|
||||
|
||||
use crate::commands::{
|
||||
Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, FormulaSpec, Note, Spec,
|
||||
Task, Time, Weekday, WeekdaySpec,
|
||||
Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, Expr, FormulaSpec, Note,
|
||||
Spec, Task, Time, Weekday, WeekdaySpec,
|
||||
};
|
||||
|
||||
#[derive(pest_derive::Parser)]
|
||||
|
|
@ -30,11 +31,6 @@ fn fail<S: Into<String>, T>(span: Span, message: S) -> Result<T> {
|
|||
Err(error(span, message))
|
||||
}
|
||||
|
||||
fn parse_number(p: Pair<Rule>) -> Result<i32> {
|
||||
assert_eq!(p.as_rule(), Rule::number);
|
||||
Ok(p.as_str().parse().unwrap())
|
||||
}
|
||||
|
||||
fn parse_title(p: Pair<Rule>) -> Result<String> {
|
||||
assert_eq!(p.as_rule(), Rule::title);
|
||||
let p = p.into_inner().next().unwrap();
|
||||
|
|
@ -116,7 +112,7 @@ fn parse_amount(p: Pair<Rule>) -> Result<Amount> {
|
|||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
Rule::number => value = parse_number(p)?,
|
||||
Rule::amount_value => value = p.as_str().parse().unwrap(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
@ -274,6 +270,25 @@ fn parse_date_fixed(p: Pair<Rule>) -> Result<DateSpec> {
|
|||
Ok(spec)
|
||||
}
|
||||
|
||||
fn parse_number(p: Pair<Rule>) -> Result<i32> {
|
||||
assert_eq!(p.as_rule(), Rule::number);
|
||||
Ok(p.as_str().parse().unwrap())
|
||||
}
|
||||
|
||||
fn parse_term(p: Pair<Rule>) -> Expr {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn parse_op(l: Expr, p: Pair<Rule>, r: Expr) -> Expr {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn parse_expr(p: Pair<Rule>) -> Result<Expr> {
|
||||
assert_eq!(p.as_rule(), Rule::expr);
|
||||
let climber = PrecClimber::new(vec![todo!()]);
|
||||
Ok(climber.climb(p.into_inner(), parse_term, parse_op))
|
||||
}
|
||||
|
||||
fn parse_date_expr(p: Pair<Rule>) -> Result<FormulaSpec> {
|
||||
assert_eq!(p.as_rule(), Rule::date_expr);
|
||||
dbg!(p);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ WHITESPACE = _{ !eol ~ WHITE_SPACE }
|
|||
rest_some = { (!eol ~ ANY)+ }
|
||||
rest_any = { (!eol ~ ANY)* }
|
||||
|
||||
number = @{ ASCII_DIGIT{1,9} } // Fits into an i32
|
||||
|
||||
title = { WHITESPACE ~ rest_some ~ eol }
|
||||
|
||||
year = @{ ASCII_DIGIT{4} }
|
||||
|
|
@ -20,7 +18,8 @@ time = ${ hour ~ ":" ~ minute }
|
|||
weekday = { "mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun" }
|
||||
|
||||
amount_sign = { "+" | "-" }
|
||||
amount = { amount_sign? ~ number? }
|
||||
amount_value = @{ ASCII_DIGIT{1,9} } // Fits into an i32
|
||||
amount = { amount_sign? ~ amount_value? }
|
||||
delta_weekdays = { amount ~ weekday }
|
||||
delta_minutes = { amount ~ "min" }
|
||||
delta_years = { amount ~ "y" }
|
||||
|
|
@ -42,20 +41,20 @@ delta = {
|
|||
)+
|
||||
}
|
||||
|
||||
number = @{ ("+" | "-")? ~ ASCII_DIGIT{1,9} } // Fits into an i32
|
||||
paren_expr = { "(" ~ expr ~ ")" }
|
||||
boolean = { "true" | "false" }
|
||||
variable = {
|
||||
"j"
|
||||
| "yl" | "yd" | "Yd" | "yw" | "Yw" | "y"
|
||||
| "ml" | "md" | "Md" | "mw" | "Mw" | "m"
|
||||
| "yl" | "yd" | "yD" | "yw" | "yW" | "y"
|
||||
| "ml" | "md" | "mD" | "mw" | "mW" | "m"
|
||||
| "d" | "D"
|
||||
| "iy" | "iyl"
|
||||
| "wd"
|
||||
| "e"
|
||||
| "mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun"
|
||||
| "isWeekday" | "isWeekend" | "isLeapYear"
|
||||
}
|
||||
term = { paren_expr | number | boolean | variable }
|
||||
term = { paren_expr | number | boolean | weekday | variable }
|
||||
op = {
|
||||
"+" | "-" | "*" | "/" | "%"
|
||||
| "=" | "!="
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue