Implement unary negation
This commit is contained in:
parent
74dbf724a5
commit
3c6fb5466e
@ -1,4 +1,4 @@
|
|||||||
use crate::parser::{Ast, BinOpType};
|
use crate::parser::{Ast, BinOpType, UnOpType};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
@ -24,6 +24,7 @@ impl Interpreter {
|
|||||||
match expr {
|
match expr {
|
||||||
Ast::I64(val) => Value::I64(val),
|
Ast::I64(val) => Value::I64(val),
|
||||||
Ast::BinOp(bo, lhs, rhs) => self.resolve_binop(bo, *lhs, *rhs),
|
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"),
|
// _ => 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)]
|
#[cfg(test)]
|
||||||
|
|||||||
@ -36,18 +36,27 @@ pub enum BinOpType {
|
|||||||
Shr,
|
Shr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Types for unary operators
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
pub enum UnOpType {
|
||||||
|
/// Negation
|
||||||
|
Neg,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum Ast {
|
pub enum Ast {
|
||||||
/// Integer literal (64-bit)
|
/// Integer literal (64-bit)
|
||||||
I64(i64),
|
I64(i64),
|
||||||
/// Binary operation. Consists of type, left hand side and right hand side
|
/// Binary operation. Consists of type, left hand side and right hand side
|
||||||
BinOp(BinOpType, Box<Ast>, Box<Ast>),
|
BinOp(BinOpType, Box<Ast>, Box<Ast>),
|
||||||
|
/// Unary operation. Consists of type and the value that is operated on
|
||||||
|
UnOp(UnOpType, Box<Ast>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
## Grammar
|
## Grammar
|
||||||
### Expressions
|
### Expressions
|
||||||
expr_primary = LITERAL | "(" expr ")"
|
expr_primary = LITERAL | "(" expr ")" | "-" expr_primary
|
||||||
expr_mul = expr_primary (("*" | "/" | "%") expr_primary)*
|
expr_mul = expr_primary (("*" | "/" | "%") expr_primary)*
|
||||||
expr_add = expr_mul (("+" | "-") expr_mul)*
|
expr_add = expr_mul (("+" | "-") expr_mul)*
|
||||||
expr_shift = expr_add ((">>" | "<<") expr_add)*
|
expr_shift = expr_add ((">>" | "<<") expr_add)*
|
||||||
@ -123,6 +132,8 @@ impl<T: Iterator<Item = Token>> Parser<T> {
|
|||||||
inner
|
inner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token::Sub => Ast::UnOp(UnOpType::Neg, self.parse_primary().into()),
|
||||||
|
|
||||||
tok => panic!("Error parsing primary expr: Unexpected Token '{:?}'", tok),
|
tok => panic!("Error parsing primary expr: Unexpected Token '{:?}'", tok),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user