diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-01-09 19:57:39 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-01-09 19:57:39 +0100 |
| commit | 4e589cac364edffb08caf7e09a12cc05894271ac (patch) | |
| tree | 7325c7717ae1b1ead6ad09e6113933cddfe4e3e4 /src/compiler.rs | |
| parent | 011e7b31e63864a83627c79c1b2d10d7dc0662b0 (diff) | |
| download | sylt-4e589cac364edffb08caf7e09a12cc05894271ac.tar.gz | |
boolean {comparisons,algebra}
Diffstat (limited to 'src/compiler.rs')
| -rw-r--r-- | src/compiler.rs | 76 |
1 files changed, 55 insertions, 21 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index d3d4c2c..4b9e74c 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -8,9 +8,10 @@ struct Compiler { //TODO rustify const PREC_NO: u64 = 0; -const PREC_COMP: u64 = 1; -const PREC_TERM: u64 = 2; -const PREC_FACTOR: u64 = 3; +const PREC_BOOL: u64 = 1; +const PREC_COMP: u64 = 2; +const PREC_TERM: u64 = 3; +const PREC_FACTOR: u64 = 4; impl Compiler { pub fn new(tokens: TokenStream) -> Self { @@ -41,13 +42,19 @@ impl Compiler { fn precedence(&self, token: Token) -> u64 { match token { - Token::Minus => PREC_TERM, - Token::Plus => PREC_TERM, + Token::Star | Token::Slash => PREC_FACTOR, - Token::Star => PREC_FACTOR, - Token::Slash => PREC_FACTOR, + Token::Minus | Token::Plus => PREC_TERM, - Token::EqualEqual => PREC_COMP, + Token::EqualEqual + | Token::Greater + | Token::GreaterEqual + | Token::Less + | Token::LessEqual + | Token::NotEqual + => PREC_COMP, + + Token::And | Token::Or => PREC_BOOL, _ => PREC_NO, } @@ -60,6 +67,9 @@ impl Compiler { Token::Float(_) => self.value(block), Token::Int(_) => self.value(block), + Token::Bool(_) => self.value(block), + + Token::Not => self.unary(block), _ => { return false; }, } @@ -69,13 +79,19 @@ impl Compiler { fn infix(&mut self, token: Token, block: &mut Block) -> bool { match token { - Token::Minus => self.binary(block), - Token::Plus => self.binary(block), - - Token::Slash => self.binary(block), - Token::Star => self.binary(block), - - Token::EqualEqual => self.binary(block), + Token::Minus + | Token::Plus + | Token::Slash + | Token::Star + => self.binary(block), + + Token::EqualEqual + | Token::Greater + | Token::GreaterEqual + | Token::Less + | Token::LessEqual + | Token::NotEqual + => self.comparison(block), _ => { return false; }, } @@ -85,7 +101,8 @@ impl Compiler { fn value(&mut self, block: &mut Block) { let value = match self.eat() { Token::Float(f) => { Value::Float(f) }, - Token::Int(f) => { Value::Int(f) } + Token::Int(i) => { Value::Int(i) } + Token::Bool(b) => { Value::Bool(b) } _ => { self.error("Invalid value.") } }; block.add(Op::Constant(value)); @@ -104,11 +121,13 @@ impl Compiler { } fn unary(&mut self, block: &mut Block) { - if Token::Minus != self.eat() { - self.error("Expected minus at start of negation."); - } + let op = match self.eat() { + Token::Minus => Op::Neg, + Token::Not => Op::Not, + _ => self.error("Invalid unary operator"), + }; self.value(block); - block.add(Op::Neg); + block.add(op); } fn binary(&mut self, block: &mut Block) { @@ -121,12 +140,27 @@ impl Compiler { Token::Minus => Op::Sub, Token::Star => Op::Mul, Token::Slash => Op::Div, - Token::EqualEqual => Op::CompEq, _ => { self.error("Illegal operator"); } }; block.add(op); } + fn comparison(&mut self, block: &mut Block) { + let op = self.eat(); + self.parse_precedence(block, self.precedence(op.clone()) + 1); + + let op: &[Op] = match op { + Token::EqualEqual => &[Op::Equal], + Token::Less => &[Op::Less], + Token::Greater => &[Op::Greater], + Token::NotEqual => &[Op::Equal, Op::Not], + Token::LessEqual => &[Op::Greater, Op::Not], + Token::GreaterEqual => &[Op::Less, Op::Not], + _ => { self.error("Illegal comparison operator"); } + }; + block.add_from(op); + } + fn expression(&mut self, block: &mut Block) { self.parse_precedence(block, PREC_NO); } |
