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