aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan Perry <avaglir@gmail.com>2019-03-05 14:56:46 -0500
committerNathan Perry <avaglir@gmail.com>2019-03-05 14:56:46 -0500
commit24a7cb3c8eb0517b69c145170765c891a82ccc76 (patch)
tree011687958e1701887fa38ee71fea28e39237e12b /src
parentd96a9c9899690cf639905af8e1006d539f1d49a6 (diff)
add debug_expr command
Diffstat (limited to 'src')
-rw-r--r--src/commands/mod.rs5
-rw-r--r--src/commands/roll.rs59
2 files changed, 58 insertions, 6 deletions
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index 5dd98d8..4619a5a 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -60,6 +60,11 @@ pub fn register_commands(f: StandardFramework) -> StandardFramework {
.desc("simulate rolling dice")
.guild_only(true)
.exec(roll::roll))
+ .command("debug_expr", |c| c
+ .desc("debug calculator expression")
+ .owners_only(true)
+ .exec(roll::debug_expr)
+ )
.unrecognised_command(|ctx, msg, unrec| {
let url = match msg.content.split_whitespace().skip(1).next() {
Some(x) if x.starts_with("http") => x,
diff --git a/src/commands/roll.rs b/src/commands/roll.rs
index 733fc76..bdb729e 100644
--- a/src/commands/roll.rs
+++ b/src/commands/roll.rs
@@ -1,4 +1,5 @@
use failure::Error;
+use itertools::Itertools;
use nom::{
self,
double,
@@ -26,8 +27,9 @@ enum CalcExpr {
#[derive(Clone, Debug, PartialEq, Fail)]
enum CalcParseError {
- #[fail(display = "couldn't consume entire expression. remaining: '{}'.", remaining)]
+ #[fail(display = "couldn't consume entire expression. parsed: {:?}, remaining: '{}'.", parsed, remaining)]
NotReadToEnd {
+ parsed: Box<CalcExpr>,
remaining: String,
},
#[fail(display = "nom error: {}", _0)]
@@ -41,6 +43,7 @@ impl CalcExpr {
.and_then(|(s, res)| {
if s.len() != 0 {
Err(CalcParseError::NotReadToEnd {
+ parsed: res,
remaining: s.as_ref().to_owned(),
})
} else {
@@ -50,13 +53,43 @@ impl CalcExpr {
.map_err(Error::from)
}
- pub fn compute(self: Box<Self>) -> f64 {
+ pub fn pretty(&self) -> String {
+ format!("```\n{}\n```", self.pretty_helper(0))
+ }
+
+ fn pretty_helper(&self, depth: usize) -> String {
+ match self {
+ CalcExpr::Binary(op, e1, e2) => {
+ let lines = vec! {
+ format!("{}{:?} ({}) {{", "\t".repeat(depth), op, self.compute()),
+ e1.pretty_helper(depth + 1),
+ e2.pretty_helper(depth + 1),
+ "\t".repeat(depth) + "}",
+ };
+
+ lines.into_iter().join("\n")
+ },
+ CalcExpr::Unary(op, e) => {
+ let lines = vec! {
+ format!("{}{:?} ({}) {{", "\t".repeat(depth), op, self.compute()),
+ e.pretty_helper(depth + 1),
+ "\t".repeat(depth) + "}",
+ };
+
+ lines.into_iter().join("\n")
+ },
+ CalcExpr::Term(val) => {
+ format!("{}{}", "\t".repeat(depth), val)
+ }
+ }
+ }
+
+ pub fn compute(&self) -> f64 {
use self::CalcExpr::*;
use self::BinOp::*;
use self::UnaryOp::*;
- let s = *self;
- match s {
+ match self {
Binary(bop, e1, e2) => {
let r1 = e1.compute();
let r2 = e2.compute();
@@ -97,7 +130,7 @@ impl CalcExpr {
Round => r.round(),
}
},
- Term(v) => v,
+ Term(v) => *v,
}
}
}
@@ -293,7 +326,7 @@ pub fn roll(_ctx: &mut Context, msg: &Message, args: Args) -> Result<()> {
Ok(expr) => send(msg.channel_id, &format!("{}", expr.compute()), msg.tts),
Err(e) => {
let parse_err = e.downcast::<CalcParseError>().unwrap();
- if let CalcParseError::NotReadToEnd { remaining } = parse_err {
+ if let CalcParseError::NotReadToEnd { remaining, .. } = parse_err {
error!("parsing '{}': failed to consume '{}'", args.rest(), remaining);
send(msg.channel_id, "I COULDN'T READ THAT YOU FUCK", msg.tts)
} else {
@@ -302,3 +335,17 @@ pub fn roll(_ctx: &mut Context, msg: &Message, args: Args) -> Result<()> {
},
}
}
+
+pub fn debug_expr(_ctx: &mut Context, msg: &Message, args: Args) -> Result<()> {
+ match CalcExpr::parse(args.rest()) {
+ Ok(expr) => send(msg.channel_id, &expr.pretty(), false),
+ Err(e) => {
+ let parse_err = e.downcast::<CalcParseError>().unwrap();
+ if let CalcParseError::NotReadToEnd { remaining, parsed } = parse_err {
+ send(msg.channel_id, &format!("parsed this expr: {}\nwith remaining text: '{}'", parsed.pretty(), remaining), false)
+ } else {
+ Err(parse_err.into())
+ }
+ }
+ }
+}