Skip to content

Commit

Permalink
upgrade lib pest
Browse files Browse the repository at this point in the history
  • Loading branch information
mitnk committed Sep 28, 2024
1 parent 584a5ac commit a038758
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 63 deletions.
2 changes: 1 addition & 1 deletion .clippy.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
large-error-threshold = 256
large-error-threshold = 365
27 changes: 14 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ glob = "0.3.0"
lazy_static = "1.5.0"
libc = "0.2.0"
linefeed = "0.6.0"
# todo: upgrade pest to 2.7+
pest = "=2.3.1"
pest_derive = "2.0"
pest = "2.7"
pest_derive = "2.7"
regex = "1"
yaml-rust = "0.4.0"
uuid = { version = "1.4", features = ["serde", "v4"] }
Expand Down
4 changes: 0 additions & 4 deletions docs/completion.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,6 @@ Put your completion files under `$XDG_CONFIG_HOME/cicada/completers`
(by default it's `~/.config/cicada/completers/`).
The completion files look like this:

> **NOTE:** cicada 0.9.x also loads completers from `~/.cicada/completers`
> (if `~/.config/cicada/completers` not exist) for
> compatibility. From 1.0, cicada will not read this location anymore.
```
$ ls ~/.config/cicada/completers/
brew.yaml git.yaml pip.yaml vox.yaml
Expand Down
60 changes: 29 additions & 31 deletions src/calculator/mod.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,66 @@
// via: https://github.com/pest-parser/book/blob/b6a42eb7/examples/calculator/src/main.rs
use std::num::Wrapping as W;

use pest::Parser;
use pest::iterators::{Pair, Pairs};
use pest::prec_climber::*;
use pest::pratt_parser::{Assoc, Op, PrattParser};

#[derive(Parser)]
#[grammar = "calculator/grammar.pest"]
struct Calculator;

lazy_static! {
static ref PREC_CLIMBER: PrecClimber<Rule> = {
static ref PRATT_PARSER: PrattParser<Rule> = {
use Rule::*;
use Assoc::*;

PrecClimber::new(vec![
Operator::new(add, Left) | Operator::new(subtract, Left),
Operator::new(multiply, Left) | Operator::new(divide, Left),
Operator::new(power, Right)
])
PrattParser::new()
.op(Op::infix(add, Left) | Op::infix(subtract, Left))
.op(Op::infix(multiply, Left) | Op::infix(divide, Left))
.op(Op::infix(power, Right))
};
}

pub fn eval_int(expression: Pairs<Rule>) -> i64 {
PREC_CLIMBER.climb(
expression,
|pair: Pair<Rule>| match pair.as_rule() {
Rule::num => pair.as_str().parse::<i64>().unwrap_or(0),
Rule::expr => eval_int(pair.into_inner()),
PRATT_PARSER
.map_primary(|primary| match primary.as_rule() {
Rule::num => primary.as_str().parse::<i64>().unwrap(),
Rule::expr => eval_int(primary.into_inner()),
_ => unreachable!(),
},
|lhs: i64, op: Pair<Rule>, rhs: i64| match op.as_rule() {
Rule::add => (W(lhs) + W(rhs)).0,
})
.map_infix(|lhs: i64, op: Pair<Rule>, rhs: i64| match op.as_rule() {
Rule::add => (W(lhs) + W(rhs)).0,
Rule::subtract => (W(lhs) - W(rhs)).0,
Rule::multiply => (W(lhs) * W(rhs)).0,
Rule::divide => {
Rule::divide => {
if rhs == 0 {
(lhs as f64 / 0.0) as i64
} else {
(W(lhs) / W(rhs)).0
}
}
Rule::power => lhs.pow(rhs as u32),
Rule::power => lhs.pow(rhs as u32),
_ => unreachable!(),
},
)
})
.parse(expression)
}

pub fn eval_float(expression: Pairs<Rule>) -> f64 {
PREC_CLIMBER.climb(
expression,
|pair: Pair<Rule>| match pair.as_rule() {
Rule::num => pair.as_str().parse::<f64>().unwrap_or(0.0),
Rule::expr => eval_float(pair.into_inner()),
PRATT_PARSER
.map_primary(|primary| match primary.as_rule() {
Rule::num => primary.as_str().parse::<f64>().unwrap(),
Rule::expr => eval_float(primary.into_inner()),
_ => unreachable!(),
},
|lhs: f64, op: Pair<Rule>, rhs: f64| match op.as_rule() {
Rule::add => lhs + rhs,
})
.map_infix(|lhs, op, rhs| match op.as_rule() {
Rule::add => lhs + rhs,
Rule::subtract => lhs - rhs,
Rule::multiply => lhs * rhs,
Rule::divide => lhs / rhs,
Rule::power => lhs.powf(rhs),
Rule::divide => lhs / rhs,
Rule::power => lhs.powf(rhs),
_ => unreachable!(),
},
)
})
.parse(expression)
}

pub fn calculate(line: &str) -> Result<pest::iterators::Pairs<'_, Rule>, pest::error::Error<Rule>> {
Expand Down
8 changes: 5 additions & 3 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,11 +680,13 @@ fn try_run_calculator(line: &str, capture: bool) -> Option<CommandResult> {
pub fn run_calculator(line: &str) -> Result<String, &str> {
let parse_result = calculator::calculate(line);
match parse_result {
Ok(calc) => {
Ok(mut calc) => {
let expr = calc.next().unwrap().into_inner();

if line.contains('.') {
Ok(format!("{}", calculator::eval_float(calc)))
Ok(format!("{}", calculator::eval_float(expr)))
} else {
Ok(format!("{}", calculator::eval_int(calc)))
Ok(format!("{}", calculator::eval_int(expr)))
}
}
Err(_) => {
Expand Down
9 changes: 1 addition & 8 deletions src/tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,7 @@ pub fn get_config_dir() -> String {

pub fn get_user_completer_dir() -> String {
let dir_config = get_config_dir();
let dir_completers = format!("{}/completers", dir_config);
if Path::new(&dir_completers).exists() {
return dir_completers;
}

// fail back to $HOME/.cicada, will remove after 1.0 release
let home = get_user_home();
format!("{}/.cicada/completers", home)
format!("{}/completers", dir_config)
}

pub fn unquote(s: &str) -> String {
Expand Down

0 comments on commit a038758

Please sign in to comment.