Add LE/GE
This commit is contained in:
parent
130cb2763b
commit
22d7a323af
24
src/ast.rs
24
src/ast.rs
@ -321,7 +321,9 @@ pub struct PrimaryExpression(Node<Expression>);
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum BinaryOperator {
|
pub enum BinaryOperator {
|
||||||
LessThan,
|
LessThan,
|
||||||
Gt,
|
LessThanOrEqual,
|
||||||
|
GreaterThan,
|
||||||
|
GreaterThanOrEqual,
|
||||||
Add,
|
Add,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +331,9 @@ impl BinaryOperator {
|
|||||||
pub fn precedence(&self) -> u32 {
|
pub fn precedence(&self) -> u32 {
|
||||||
match self {
|
match self {
|
||||||
BinaryOperator::LessThan => 10,
|
BinaryOperator::LessThan => 10,
|
||||||
BinaryOperator::Gt => 10,
|
BinaryOperator::LessThanOrEqual => 10,
|
||||||
|
BinaryOperator::GreaterThan => 10,
|
||||||
|
BinaryOperator::GreaterThanOrEqual => 10,
|
||||||
BinaryOperator::Add => 20,
|
BinaryOperator::Add => 20,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,10 +416,18 @@ fn parse_binop_rhs(
|
|||||||
impl Parse for BinaryOperator {
|
impl Parse for BinaryOperator {
|
||||||
fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> {
|
fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> {
|
||||||
if let Some(token) = stream.next() {
|
if let Some(token) = stream.next() {
|
||||||
match token {
|
match (token, stream.peek()) {
|
||||||
Token::Symbol('<') => Ok(BinaryOperator::LessThan),
|
(Token::Symbol('<'), Some(Token::Symbol('='))) => {
|
||||||
Token::Symbol('>') => Ok(BinaryOperator::Gt),
|
stream.next();
|
||||||
Token::Symbol('+') => Ok(BinaryOperator::Add),
|
Ok(BinaryOperator::LessThanOrEqual)
|
||||||
|
}
|
||||||
|
(Token::Symbol('>'), Some(Token::Symbol('='))) => {
|
||||||
|
stream.next();
|
||||||
|
Ok(BinaryOperator::GreaterThanOrEqual)
|
||||||
|
}
|
||||||
|
(Token::Symbol('<'), _) => Ok(BinaryOperator::LessThan),
|
||||||
|
(Token::Symbol('>'), _) => Ok(BinaryOperator::GreaterThan),
|
||||||
|
(Token::Symbol('+'), _) => Ok(BinaryOperator::Add),
|
||||||
_ => Err(stream.expected_err("binop")),
|
_ => Err(stream.expected_err("binop")),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -315,13 +315,27 @@ impl Expression {
|
|||||||
*rhs.get(0).unwrap(),
|
*rhs.get(0).unwrap(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
BinaryOperator::Gt => {
|
BinaryOperator::LessThanOrEqual => {
|
||||||
|
instructions.push(Instruction::LessThanOrEqual(
|
||||||
|
reg,
|
||||||
|
*lhs.get(0).unwrap(),
|
||||||
|
*rhs.get(0).unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
BinaryOperator::GreaterThan => {
|
||||||
instructions.push(Instruction::LessThan(
|
instructions.push(Instruction::LessThan(
|
||||||
reg,
|
reg,
|
||||||
*rhs.get(0).unwrap(),
|
*rhs.get(0).unwrap(),
|
||||||
*lhs.get(0).unwrap(),
|
*lhs.get(0).unwrap(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
BinaryOperator::GreaterThanOrEqual => {
|
||||||
|
instructions.push(Instruction::LessThanOrEqual(
|
||||||
|
reg,
|
||||||
|
*rhs.get(0).unwrap(),
|
||||||
|
*lhs.get(0).unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
BinaryOperator::Add => {
|
BinaryOperator::Add => {
|
||||||
instructions.push(Instruction::Add(
|
instructions.push(Instruction::Add(
|
||||||
reg,
|
reg,
|
||||||
|
|||||||
30
src/vm.rs
30
src/vm.rs
@ -42,6 +42,8 @@ pub enum Instruction {
|
|||||||
Add(u16, u16, u16),
|
Add(u16, u16, u16),
|
||||||
/// R(A) := R(B) < R(C)
|
/// R(A) := R(B) < R(C)
|
||||||
LessThan(u16, u16, u16),
|
LessThan(u16, u16, u16),
|
||||||
|
/// R(A) := R(B) < R(C)
|
||||||
|
LessThanOrEqual(u16, u16, u16),
|
||||||
/// PC += sAx
|
/// PC += sAx
|
||||||
Jmp(i32),
|
Jmp(i32),
|
||||||
/// if (R(B) <=> C) then R(A) := R(B) else PC++
|
/// if (R(B) <=> C) then R(A) := R(B) else PC++
|
||||||
@ -72,7 +74,10 @@ impl Debug for Instruction {
|
|||||||
Instruction::Close(arg0) => write!(f, "CLOSE {}", arg0),
|
Instruction::Close(arg0) => write!(f, "CLOSE {}", arg0),
|
||||||
Instruction::Closure(arg0, arg1) => write!(f, "CLOSURE {} {}", arg0, arg1),
|
Instruction::Closure(arg0, arg1) => write!(f, "CLOSURE {} {}", arg0, arg1),
|
||||||
Instruction::Return(arg0, arg1) => write!(f, "RETURN {} {}", arg0, arg1),
|
Instruction::Return(arg0, arg1) => write!(f, "RETURN {} {}", arg0, arg1),
|
||||||
Instruction::LessThan(arg0, arg1, arg2) => write!(f, "LE {} {} {}", arg0, arg1, arg2),
|
Instruction::LessThan(arg0, arg1, arg2) => write!(f, "LT {} {} {}", arg0, arg1, arg2),
|
||||||
|
Instruction::LessThanOrEqual(arg0, arg1, arg2) => {
|
||||||
|
write!(f, "LE {} {} {}", arg0, arg1, arg2)
|
||||||
|
}
|
||||||
Instruction::Add(arg0, arg1, arg2) => write!(f, "ADD {} {} {}", arg0, arg1, arg2),
|
Instruction::Add(arg0, arg1, arg2) => write!(f, "ADD {} {} {}", arg0, arg1, arg2),
|
||||||
Instruction::LoadNil(arg0, arg1) => write!(f, "LOADNIL {} {}", arg0, arg1),
|
Instruction::LoadNil(arg0, arg1) => write!(f, "LOADNIL {} {}", arg0, arg1),
|
||||||
}
|
}
|
||||||
@ -112,6 +117,16 @@ impl Value {
|
|||||||
_ => Value::Nil,
|
_ => Value::Nil,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lte(&self, other: &Value) -> Value {
|
||||||
|
match (self, other) {
|
||||||
|
(Value::Number(lhs), Value::Number(rhs)) => {
|
||||||
|
let res = LuaNumber::from_bits(*lhs) <= LuaNumber::from_bits(*rhs);
|
||||||
|
Value::Number((res as u64 as f64).to_bits())
|
||||||
|
}
|
||||||
|
_ => Value::Nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Value {
|
impl Debug for Value {
|
||||||
@ -454,6 +469,19 @@ impl ClosureRunner {
|
|||||||
.unwrap_or(Value::Nil);
|
.unwrap_or(Value::Nil);
|
||||||
self.set_stack(*res, lhs.lt(&rhs));
|
self.set_stack(*res, lhs.lt(&rhs));
|
||||||
}
|
}
|
||||||
|
Instruction::LessThanOrEqual(res, lhs, rhs) => {
|
||||||
|
let lhs = self
|
||||||
|
.stack
|
||||||
|
.get(lhs)
|
||||||
|
.map(|v| v.borrow().clone())
|
||||||
|
.unwrap_or(Value::Nil);
|
||||||
|
let rhs = self
|
||||||
|
.stack
|
||||||
|
.get(rhs)
|
||||||
|
.map(|v| v.borrow().clone())
|
||||||
|
.unwrap_or(Value::Nil);
|
||||||
|
self.set_stack(*res, lhs.lte(&rhs));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.program_counter += 1;
|
self.program_counter += 1;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user