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