mirror of https://github.com/rm-dr/daisy
Improved operator ordering
parent
aa90d798c9
commit
c3686172cd
|
@ -9,7 +9,6 @@ This is nowhere near complete. Stay tuned.
|
|||
|
||||
## Before For 1.0 release
|
||||
- `+` as a unary operator
|
||||
- Compare operators => *, / should have the same priority!
|
||||
- Commands
|
||||
- Documentation (usage)
|
||||
- Documentation (comments)
|
||||
|
|
|
@ -92,31 +92,31 @@ fn treeify_binary(
|
|||
|
||||
|
||||
// Precedence of this operator
|
||||
let this_val = {
|
||||
let this_op = {
|
||||
let PreToken::PreOperator(l, s) = this else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
o.unwrap().as_int()
|
||||
o.unwrap()
|
||||
};
|
||||
|
||||
// Precedence of the operators contesting our arguments
|
||||
let left_val = if i > 1 {
|
||||
let left_op = if i > 1 {
|
||||
let PreToken::PreOperator(l, s) = &g_inner[i-2] else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
Some(o.unwrap().as_int())
|
||||
Some(o.unwrap())
|
||||
} else { None };
|
||||
|
||||
let right_val = if i < g_inner.len()-2 {
|
||||
let right_op = if i < g_inner.len()-2 {
|
||||
let PreToken::PreOperator(l, s) = &g_inner[i+2] else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
Some(o.unwrap().as_int())
|
||||
Some(o.unwrap())
|
||||
} else { None };
|
||||
|
||||
if {
|
||||
(left_val.is_none() || this_val >= left_val.unwrap()) &&
|
||||
(right_val.is_none() || this_val >= right_val.unwrap())
|
||||
(left_op.is_none() || this_op >= left_op.unwrap()) &&
|
||||
(right_op.is_none() || this_op >= right_op.unwrap())
|
||||
} {
|
||||
// This operator has higher precedence, it takes both arguments
|
||||
let left_pre = g_inner.remove(i-1).unwrap();
|
||||
|
@ -208,31 +208,31 @@ fn treeify_unary(
|
|||
} else {
|
||||
|
||||
// Precedence of this operator
|
||||
let this_val = {
|
||||
let this_op = {
|
||||
let PreToken::PreOperator(l, s) = this else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
o.unwrap().as_int()
|
||||
o.unwrap()
|
||||
};
|
||||
|
||||
// Precedence of the operator contesting its argument
|
||||
let next_val = if left_associative {
|
||||
let next_op = if left_associative {
|
||||
if i > 1 {
|
||||
let PreToken::PreOperator(l, s) = &g_inner[i-2] else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
Some(o.unwrap().as_int())
|
||||
Some(o.unwrap())
|
||||
} else { None }
|
||||
} else {
|
||||
if i < g_inner.len()-2 {
|
||||
let PreToken::PreOperator(l, s) = &g_inner[i+2] else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
Some(o.unwrap().as_int())
|
||||
Some(o.unwrap())
|
||||
} else { None }
|
||||
};
|
||||
|
||||
if next_val.is_none() || this_val > next_val.unwrap() {
|
||||
if next_op.is_none() || this_op > next_op.unwrap() {
|
||||
let this_pre = g_inner.remove(i).unwrap();
|
||||
let next_pre: PreToken; let next: Token;
|
||||
if left_associative {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use crate::quantity::Quantity;
|
||||
|
||||
|
@ -90,6 +91,27 @@ pub enum Operator {
|
|||
// Not accessible from prompt
|
||||
Flip,
|
||||
}
|
||||
|
||||
impl PartialEq for Operator {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_int() == other.as_int()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Operator {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (self, other) {
|
||||
(Operator::Add, Operator::Subtract)
|
||||
| (Operator::Subtract, Operator::Add)
|
||||
| (Operator::Multiply, Operator::Divide)
|
||||
| (Operator::Divide, Operator::Multiply)
|
||||
=> {Some(Ordering::Equal)}
|
||||
|
||||
_ => { self.as_int().partial_cmp(&other.as_int()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Function {
|
||||
|
@ -243,7 +265,7 @@ impl Operator {
|
|||
fn add_parens_to_arg(&self, arg: &Token) -> String {
|
||||
let mut astr: String = arg.print();
|
||||
if let Token::Operator(o,_) = arg {
|
||||
if o.as_int() < self.as_int() {
|
||||
if o < self {
|
||||
astr = format!("({})", astr);
|
||||
}
|
||||
}
|
||||
|
@ -339,14 +361,14 @@ impl Operator {
|
|||
|
||||
let mut astr: String = a.print();
|
||||
if let Token::Operator(o,_) = a {
|
||||
if o.as_int() < self.as_int() {
|
||||
if o < self {
|
||||
astr = format!("({})", astr);
|
||||
}
|
||||
}
|
||||
|
||||
let mut bstr: String = b.print();
|
||||
if let Token::Operator(o,_) = b {
|
||||
if o.as_int() < self.as_int() {
|
||||
if o < self {
|
||||
bstr = format!("({})", astr);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue