Implement unary negation

This commit is contained in:
Daniel M 2022-01-28 14:21:57 +01:00
parent 74dbf724a5
commit 3c6fb5466e
2 changed files with 27 additions and 5 deletions

View File

@ -1,4 +1,4 @@
use crate::parser::{Ast, BinOpType};
use crate::parser::{Ast, BinOpType, UnOpType};
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Value {
@ -24,6 +24,7 @@ impl Interpreter {
match expr {
Ast::I64(val) => Value::I64(val),
Ast::BinOp(bo, lhs, rhs) => self.resolve_binop(bo, *lhs, *rhs),
Ast::UnOp(uo, val) => self.resolve_unop(uo, *val),
}
}
@ -47,6 +48,16 @@ impl Interpreter {
// _ => panic!("Value types are not compatible"),
}
}
fn resolve_unop(&mut self, uo: UnOpType, val: Ast) -> Value {
let val = self.resolve_expr(val);
match val {
Value::I64(val) => match uo {
UnOpType::Neg => Value::I64(-val),
}
}
}
}
#[cfg(test)]

View File

@ -36,18 +36,27 @@ pub enum BinOpType {
Shr,
}
/// Types for unary operators
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum UnOpType {
/// Negation
Neg,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Ast {
/// Integer literal (64-bit)
I64(i64),
/// Binary operation. Consists of type, left hand side and right hand side
BinOp(BinOpType, Box<Ast>, Box<Ast>),
/// Unary operation. Consists of type and the value that is operated on
UnOp(UnOpType, Box<Ast>),
}
/*
## Grammar
### Expressions
expr_primary = LITERAL | "(" expr ")"
expr_primary = LITERAL | "(" expr ")" | "-" expr_primary
expr_mul = expr_primary (("*" | "/" | "%") expr_primary)*
expr_add = expr_mul (("+" | "-") expr_mul)*
expr_shift = expr_add ((">>" | "<<") expr_add)*
@ -123,6 +132,8 @@ impl<T: Iterator<Item = Token>> Parser<T> {
inner
}
Token::Sub => Ast::UnOp(UnOpType::Neg, self.parse_primary().into()),
tok => panic!("Error parsing primary expr: Unexpected Token '{:?}'", tok),
}
}