Compare commits
No commits in common. "fa13697596666aeb153fd80cc3cd2fc7d57ff975" and "f0c84fe0c8c72ab52af3de90e227eb2839d259d8" have entirely different histories.
fa13697596
...
f0c84fe0c8
@ -23,9 +23,6 @@ pub enum BinaryOperation {
|
|||||||
Subtract,
|
Subtract,
|
||||||
LeftShift,
|
LeftShift,
|
||||||
RightShift,
|
RightShift,
|
||||||
BitwiseAnd,
|
|
||||||
BitwiseXor,
|
|
||||||
BitwiseOr,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BinaryExpression {
|
pub struct BinaryExpression {
|
||||||
@ -138,37 +135,13 @@ impl BinaryExpression {
|
|||||||
|
|
||||||
match &self.op {
|
match &self.op {
|
||||||
BinaryOperation::Multiply => {
|
BinaryOperation::Multiply => {
|
||||||
handle_diagnostic!(
|
todo!()
|
||||||
self.check_op(
|
|
||||||
|lhs, rhs| lhs.can_multiply(rhs),
|
|
||||||
|lhs, rhs| lhs.multiply_result(rhs),
|
|
||||||
|lhs, rhs| format!(
|
|
||||||
"Incompatible types: cannot multiply {} by {}",
|
|
||||||
lhs, rhs
|
|
||||||
)
|
|
||||||
),
|
|
||||||
diagnostics
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
BinaryOperation::Divide => {
|
BinaryOperation::Divide => {
|
||||||
handle_diagnostic!(
|
todo!()
|
||||||
self.check_op(
|
|
||||||
|lhs, rhs| lhs.can_divide(rhs),
|
|
||||||
|lhs, rhs| lhs.divide_result(rhs),
|
|
||||||
|lhs, rhs| format!("Incompatible types: cannot divide {} by {}", lhs, rhs)
|
|
||||||
),
|
|
||||||
diagnostics
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
BinaryOperation::Modulo => {
|
BinaryOperation::Modulo => {
|
||||||
handle_diagnostic!(
|
todo!()
|
||||||
self.check_op(
|
|
||||||
|lhs, rhs| lhs.can_modulo(rhs),
|
|
||||||
|lhs, rhs| lhs.modulo_result(rhs),
|
|
||||||
|lhs, rhs| format!("Incompatible types: cannot modulo {} by {}", lhs, rhs)
|
|
||||||
),
|
|
||||||
diagnostics
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
BinaryOperation::Add => {
|
BinaryOperation::Add => {
|
||||||
handle_diagnostic!(
|
handle_diagnostic!(
|
||||||
@ -193,66 +166,8 @@ impl BinaryExpression {
|
|||||||
diagnostics
|
diagnostics
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
BinaryOperation::LeftShift => {
|
BinaryOperation::LeftShift => todo!(),
|
||||||
handle_diagnostic!(
|
BinaryOperation::RightShift => todo!(),
|
||||||
self.check_op(
|
|
||||||
|lhs, rhs| lhs.can_left_shift(rhs),
|
|
||||||
|lhs, rhs| lhs.left_shift_result(rhs),
|
|
||||||
|lhs, rhs| format!(
|
|
||||||
"Incompatible types: cannot left shift {} by {}",
|
|
||||||
lhs, rhs
|
|
||||||
)
|
|
||||||
),
|
|
||||||
diagnostics
|
|
||||||
);
|
|
||||||
}
|
|
||||||
BinaryOperation::RightShift => {
|
|
||||||
handle_diagnostic!(
|
|
||||||
self.check_op(
|
|
||||||
|lhs, rhs| lhs.can_right_shift(rhs),
|
|
||||||
|lhs, rhs| lhs.right_shift_result(rhs),
|
|
||||||
|lhs, rhs| format!(
|
|
||||||
"Incompatible types: cannot right shift {} by {}",
|
|
||||||
lhs, rhs
|
|
||||||
)
|
|
||||||
),
|
|
||||||
diagnostics
|
|
||||||
);
|
|
||||||
}
|
|
||||||
BinaryOperation::BitwiseAnd => {
|
|
||||||
handle_diagnostic!(
|
|
||||||
self.check_op(
|
|
||||||
|lhs, rhs| lhs.can_bitwise_and(rhs),
|
|
||||||
|lhs, rhs| lhs.bitwise_and_result(rhs),
|
|
||||||
|lhs, rhs| format!(
|
|
||||||
"Incompatible types: cannot bitwise and {} by {}",
|
|
||||||
lhs, rhs
|
|
||||||
)
|
|
||||||
),
|
|
||||||
diagnostics
|
|
||||||
);
|
|
||||||
}
|
|
||||||
BinaryOperation::BitwiseXor => handle_diagnostic!(
|
|
||||||
self.check_op(
|
|
||||||
|lhs, rhs| lhs.can_bitwise_xor(rhs),
|
|
||||||
|lhs, rhs| lhs.bitwise_xor_result(rhs),
|
|
||||||
|lhs, rhs| format!("Incompatible types: cannot bitwise xor {} by {}", lhs, rhs)
|
|
||||||
),
|
|
||||||
diagnostics
|
|
||||||
),
|
|
||||||
BinaryOperation::BitwiseOr => {
|
|
||||||
handle_diagnostic!(
|
|
||||||
self.check_op(
|
|
||||||
|lhs, rhs| lhs.can_bitwise_or(rhs),
|
|
||||||
|lhs, rhs| lhs.bitwise_or_result(rhs),
|
|
||||||
|lhs, rhs| format!(
|
|
||||||
"Incompatible types: cannot bitwise or {} by {}",
|
|
||||||
lhs, rhs
|
|
||||||
)
|
|
||||||
),
|
|
||||||
diagnostics
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
diagnostics_result!(diagnostics)
|
diagnostics_result!(diagnostics)
|
||||||
@ -276,26 +191,13 @@ impl BinaryExpression {
|
|||||||
IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Multiply)
|
IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Multiply)
|
||||||
}
|
}
|
||||||
BinaryOperation::Divide => IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Divide),
|
BinaryOperation::Divide => IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Divide),
|
||||||
BinaryOperation::Modulo => IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Modulo),
|
BinaryOperation::Modulo => todo!(),
|
||||||
BinaryOperation::Add => IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Add),
|
BinaryOperation::Add => IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Add),
|
||||||
BinaryOperation::Subtract => {
|
BinaryOperation::Subtract => {
|
||||||
IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Subtract)
|
IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::Subtract)
|
||||||
}
|
}
|
||||||
BinaryOperation::LeftShift => {
|
BinaryOperation::LeftShift => todo!(),
|
||||||
IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::LeftShift)
|
BinaryOperation::RightShift => todo!(),
|
||||||
}
|
|
||||||
BinaryOperation::RightShift => {
|
|
||||||
IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::RightShift)
|
|
||||||
}
|
|
||||||
BinaryOperation::BitwiseAnd => {
|
|
||||||
IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::BitwiseAnd)
|
|
||||||
}
|
|
||||||
BinaryOperation::BitwiseXor => {
|
|
||||||
IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::BitwiseXor)
|
|
||||||
}
|
|
||||||
BinaryOperation::BitwiseOr => {
|
|
||||||
IrBinaryOperation::new(lhs, rhs, IrBinaryOperator::BitwiseOr)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
IrOperation::Binary(ir_binary_operation)
|
IrOperation::Binary(ir_binary_operation)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,14 +10,8 @@ use std::fmt::{Display, Formatter};
|
|||||||
pub enum IrBinaryOperator {
|
pub enum IrBinaryOperator {
|
||||||
Multiply,
|
Multiply,
|
||||||
Divide,
|
Divide,
|
||||||
Modulo,
|
|
||||||
Add,
|
Add,
|
||||||
Subtract,
|
Subtract,
|
||||||
LeftShift,
|
|
||||||
RightShift,
|
|
||||||
BitwiseAnd,
|
|
||||||
BitwiseXor,
|
|
||||||
BitwiseOr,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IrBinaryOperation {
|
pub struct IrBinaryOperation {
|
||||||
@ -47,16 +41,9 @@ impl IrBinaryOperation {
|
|||||||
self.right.multiply_operand(),
|
self.right.multiply_operand(),
|
||||||
destination,
|
destination,
|
||||||
),
|
),
|
||||||
IrBinaryOperator::Divide => Instruction::Divide(
|
IrBinaryOperator::Divide => {
|
||||||
self.left.as_location_or_number(),
|
todo!()
|
||||||
self.right.as_location_or_number(),
|
}
|
||||||
destination,
|
|
||||||
),
|
|
||||||
IrBinaryOperator::Modulo => Instruction::Modulo(
|
|
||||||
self.left.as_location_or_number(),
|
|
||||||
self.right.as_location_or_number(),
|
|
||||||
destination,
|
|
||||||
),
|
|
||||||
IrBinaryOperator::Add => Instruction::Add(
|
IrBinaryOperator::Add => Instruction::Add(
|
||||||
self.left.add_operand(constants_table),
|
self.left.add_operand(constants_table),
|
||||||
self.right.add_operand(constants_table),
|
self.right.add_operand(constants_table),
|
||||||
@ -67,31 +54,6 @@ impl IrBinaryOperation {
|
|||||||
self.right.subtract_operand(),
|
self.right.subtract_operand(),
|
||||||
destination,
|
destination,
|
||||||
),
|
),
|
||||||
IrBinaryOperator::LeftShift => Instruction::LeftShift(
|
|
||||||
self.left.as_location_or_integer(),
|
|
||||||
self.right.as_location_or_integer(),
|
|
||||||
destination,
|
|
||||||
),
|
|
||||||
IrBinaryOperator::RightShift => Instruction::RightShift(
|
|
||||||
self.left.as_location_or_integer(),
|
|
||||||
self.right.as_location_or_integer(),
|
|
||||||
destination,
|
|
||||||
),
|
|
||||||
IrBinaryOperator::BitwiseAnd => Instruction::BitwiseAnd(
|
|
||||||
self.left.as_location_or_integer(),
|
|
||||||
self.right.as_location_or_integer(),
|
|
||||||
destination,
|
|
||||||
),
|
|
||||||
IrBinaryOperator::BitwiseXor => Instruction::BitwiseXor(
|
|
||||||
self.left.as_location_or_integer(),
|
|
||||||
self.right.as_location_or_integer(),
|
|
||||||
destination,
|
|
||||||
),
|
|
||||||
IrBinaryOperator::BitwiseOr => Instruction::BitwiseOr(
|
|
||||||
self.left.as_location_or_integer(),
|
|
||||||
self.right.as_location_or_integer(),
|
|
||||||
destination,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
builder.push(instruction);
|
builder.push(instruction);
|
||||||
}
|
}
|
||||||
@ -106,30 +68,12 @@ impl Display for IrBinaryOperation {
|
|||||||
IrBinaryOperator::Divide => {
|
IrBinaryOperator::Divide => {
|
||||||
write!(f, "{} / {}", self.left, self.right)
|
write!(f, "{} / {}", self.left, self.right)
|
||||||
}
|
}
|
||||||
IrBinaryOperator::Modulo => {
|
|
||||||
write!(f, "{} % {}", self.left, self.right)
|
|
||||||
}
|
|
||||||
IrBinaryOperator::Add => {
|
IrBinaryOperator::Add => {
|
||||||
write!(f, "{} + {}", self.left, self.right)
|
write!(f, "{} + {}", self.left, self.right)
|
||||||
}
|
}
|
||||||
IrBinaryOperator::Subtract => {
|
IrBinaryOperator::Subtract => {
|
||||||
write!(f, "{} - {}", self.left, self.right)
|
write!(f, "{} - {}", self.left, self.right)
|
||||||
}
|
}
|
||||||
IrBinaryOperator::LeftShift => {
|
|
||||||
write!(f, "{} << {}", self.left, self.right)
|
|
||||||
}
|
|
||||||
IrBinaryOperator::RightShift => {
|
|
||||||
write!(f, "{} >> {}", self.left, self.right)
|
|
||||||
}
|
|
||||||
IrBinaryOperator::BitwiseAnd => {
|
|
||||||
write!(f, "{} & {}", self.left, self.right)
|
|
||||||
}
|
|
||||||
IrBinaryOperator::BitwiseXor => {
|
|
||||||
write!(f, "{} ^ {}", self.left, self.right)
|
|
||||||
}
|
|
||||||
IrBinaryOperator::BitwiseOr => {
|
|
||||||
write!(f, "{} | {}", self.left, self.right)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,8 @@ use crate::ir::ir_variable::{IrVariable, IrVariableDescriptor, IrVrVariableDescr
|
|||||||
use crate::ir::register_allocation::VrUser;
|
use crate::ir::register_allocation::VrUser;
|
||||||
use crate::type_info::TypeInfo;
|
use crate::type_info::TypeInfo;
|
||||||
use dvm_lib::instruction::{
|
use dvm_lib::instruction::{
|
||||||
AddOperand, Location, LocationOrInteger, LocationOrNumber, MoveOperand, MultiplyOperand,
|
AddOperand, Location, MoveOperand, MultiplyOperand, PushOperand, ReturnOperand,
|
||||||
PushOperand, ReturnOperand, SetFieldOperand, SubtractOperand,
|
SetFieldOperand, SubtractOperand,
|
||||||
};
|
};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
@ -204,33 +204,6 @@ impl IrExpression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_location_or_number(&self) -> LocationOrNumber {
|
|
||||||
match self {
|
|
||||||
IrExpression::Parameter(ir_parameter) => {
|
|
||||||
LocationOrNumber::Location(ir_parameter.as_location())
|
|
||||||
}
|
|
||||||
IrExpression::Variable(ir_variable) => {
|
|
||||||
LocationOrNumber::Location(ir_variable.borrow().descriptor().as_location())
|
|
||||||
}
|
|
||||||
IrExpression::Int(i) => LocationOrNumber::Int(*i),
|
|
||||||
IrExpression::Double(d) => LocationOrNumber::Double(*d),
|
|
||||||
_ => panic!("Attempt to convert {} to a location or number", self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_location_or_integer(&self) -> LocationOrInteger {
|
|
||||||
match self {
|
|
||||||
IrExpression::Parameter(ir_parameter) => {
|
|
||||||
LocationOrInteger::Location(ir_parameter.as_location())
|
|
||||||
}
|
|
||||||
IrExpression::Variable(ir_variable) => {
|
|
||||||
LocationOrInteger::Location(ir_variable.borrow().descriptor().as_location())
|
|
||||||
}
|
|
||||||
IrExpression::Int(i) => LocationOrInteger::Int(*i),
|
|
||||||
_ => panic!("Attempt to convert {} to a location or integer", self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for IrExpression {
|
impl Display for IrExpression {
|
||||||
@ -260,7 +233,13 @@ impl VrUser for IrExpression {
|
|||||||
match self {
|
match self {
|
||||||
IrExpression::Parameter(_) => HashSet::new(),
|
IrExpression::Parameter(_) => HashSet::new(),
|
||||||
IrExpression::Variable(ir_variable) => {
|
IrExpression::Variable(ir_variable) => {
|
||||||
ir_variable.borrow().descriptor().vr_variable_descriptors()
|
if let IrVariableDescriptor::VirtualRegister(vr_variable) =
|
||||||
|
ir_variable.borrow().descriptor()
|
||||||
|
{
|
||||||
|
HashSet::from([vr_variable.clone()])
|
||||||
|
} else {
|
||||||
|
HashSet::new()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IrExpression::Int(_) => HashSet::new(),
|
IrExpression::Int(_) => HashSet::new(),
|
||||||
IrExpression::Double(_) => HashSet::new(),
|
IrExpression::Double(_) => HashSet::new(),
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
use crate::type_info::TypeInfo;
|
use crate::type_info::TypeInfo;
|
||||||
use dvm_lib::instruction::Location;
|
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -25,10 +24,6 @@ impl IrParameter {
|
|||||||
pub fn stack_offset(&self) -> isize {
|
pub fn stack_offset(&self) -> isize {
|
||||||
self.stack_offset
|
self.stack_offset
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_location(&self) -> Location {
|
|
||||||
Location::StackFrameOffset(self.stack_offset)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for IrParameter {
|
impl Display for IrParameter {
|
||||||
|
|||||||
@ -58,12 +58,6 @@ impl<'a> Lexer<'a> {
|
|||||||
Token::new(self.position, self.position + 2, TokenKind::LeftShift)
|
Token::new(self.position, self.position + 2, TokenKind::LeftShift)
|
||||||
} else if chunk.starts_with(">>") {
|
} else if chunk.starts_with(">>") {
|
||||||
Token::new(self.position, self.position + 2, TokenKind::RightShift)
|
Token::new(self.position, self.position + 2, TokenKind::RightShift)
|
||||||
} else if chunk.starts_with("&") {
|
|
||||||
Token::new(self.position, self.position + 1, TokenKind::Ampersand)
|
|
||||||
} else if chunk.starts_with("^") {
|
|
||||||
Token::new(self.position, self.position + 1, TokenKind::Caret)
|
|
||||||
} else if chunk.starts_with("|") {
|
|
||||||
Token::new(self.position, self.position + 1, TokenKind::Bar)
|
|
||||||
} else if chunk.starts_with("=") {
|
} else if chunk.starts_with("=") {
|
||||||
Token::new(self.position, self.position + 1, TokenKind::Equals)
|
Token::new(self.position, self.position + 1, TokenKind::Equals)
|
||||||
} else if chunk.starts_with(",") {
|
} else if chunk.starts_with(",") {
|
||||||
|
|||||||
@ -662,58 +662,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expression(&mut self) -> Result<Expression, Vec<Diagnostic>> {
|
fn expression(&mut self) -> Result<Expression, Vec<Diagnostic>> {
|
||||||
self.bitwise_or_expression()
|
self.shift_expression()
|
||||||
}
|
|
||||||
|
|
||||||
fn bitwise_or_expression(&mut self) -> Result<Expression, Vec<Diagnostic>> {
|
|
||||||
let mut result = self.bitwise_xor_expression()?;
|
|
||||||
while self.current.is_some() && self.peek_current(TokenKind::Bar) {
|
|
||||||
self.advance(); // |
|
|
||||||
let rhs = self.bitwise_xor_expression()?;
|
|
||||||
let source_range =
|
|
||||||
SourceRange::new(result.source_range().start(), rhs.source_range().end());
|
|
||||||
result = Expression::Binary(BinaryExpression::new(
|
|
||||||
result,
|
|
||||||
rhs,
|
|
||||||
BinaryOperation::BitwiseOr,
|
|
||||||
source_range,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bitwise_xor_expression(&mut self) -> Result<Expression, Vec<Diagnostic>> {
|
|
||||||
let mut result = self.bitwise_and_expression()?;
|
|
||||||
while self.current.is_some() && self.peek_current(TokenKind::Caret) {
|
|
||||||
self.advance(); // ^
|
|
||||||
let rhs = self.bitwise_and_expression()?;
|
|
||||||
let source_range =
|
|
||||||
SourceRange::new(result.source_range().start(), rhs.source_range().end());
|
|
||||||
result = Expression::Binary(BinaryExpression::new(
|
|
||||||
result,
|
|
||||||
rhs,
|
|
||||||
BinaryOperation::BitwiseXor,
|
|
||||||
source_range,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bitwise_and_expression(&mut self) -> Result<Expression, Vec<Diagnostic>> {
|
|
||||||
let mut result = self.shift_expression()?;
|
|
||||||
while self.current.is_some() && self.peek_current(TokenKind::Ampersand) {
|
|
||||||
self.advance(); // &
|
|
||||||
let rhs = self.shift_expression()?;
|
|
||||||
let source_range =
|
|
||||||
SourceRange::new(result.source_range().start(), rhs.source_range().end());
|
|
||||||
result = Expression::Binary(BinaryExpression::new(
|
|
||||||
result,
|
|
||||||
rhs,
|
|
||||||
BinaryOperation::BitwiseAnd,
|
|
||||||
source_range,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shift_expression(&mut self) -> Result<Expression, Vec<Diagnostic>> {
|
fn shift_expression(&mut self) -> Result<Expression, Vec<Diagnostic>> {
|
||||||
@ -1118,32 +1067,6 @@ mod smoke_tests {
|
|||||||
fn simple_right_shift() {
|
fn simple_right_shift() {
|
||||||
smoke_test("fn main() 4 >> 1 end");
|
smoke_test("fn main() 4 >> 1 end");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn simple_bitwise_and() {
|
|
||||||
smoke_test("fn main() 2 & 1 end");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn simple_bitwise_xor() {
|
|
||||||
smoke_test("fn main() 1 ^ 2 end");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn simple_bitwise_or() {
|
|
||||||
smoke_test("fn main() 1 | 2 end");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn ops_left_to_right() {
|
|
||||||
smoke_test(
|
|
||||||
"
|
|
||||||
fn main()
|
|
||||||
1 | 2 ^ 3 & 4 << 5 >> 7 + 8 - 9 * 10 / 11 % 12
|
|
||||||
end
|
|
||||||
",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@ -47,9 +47,6 @@ pub enum TokenKind {
|
|||||||
Modulo,
|
Modulo,
|
||||||
LeftShift,
|
LeftShift,
|
||||||
RightShift,
|
RightShift,
|
||||||
Ampersand,
|
|
||||||
Caret,
|
|
||||||
Bar,
|
|
||||||
Class,
|
Class,
|
||||||
Dot,
|
Dot,
|
||||||
SelfKw,
|
SelfKw,
|
||||||
|
|||||||
@ -40,14 +40,6 @@ impl Display for TypeInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_number(type_info: &TypeInfo) -> bool {
|
|
||||||
matches!(type_info, TypeInfo::Integer | TypeInfo::Double)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn are_numbers(left: &TypeInfo, right: &TypeInfo) -> bool {
|
|
||||||
is_number(left) && is_number(right)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypeInfo {
|
impl TypeInfo {
|
||||||
pub fn from_declared_name(
|
pub fn from_declared_name(
|
||||||
declared_name: &str,
|
declared_name: &str,
|
||||||
@ -101,61 +93,6 @@ impl TypeInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_negate(&self) -> bool {
|
|
||||||
is_number(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn negate_result(&self) -> TypeInfo {
|
|
||||||
match self {
|
|
||||||
TypeInfo::Integer => TypeInfo::Integer,
|
|
||||||
TypeInfo::Double => TypeInfo::Double,
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn can_multiply(&self, rhs: &Self) -> bool {
|
|
||||||
are_numbers(self, rhs)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn multiply_result(&self, rhs: &Self) -> TypeInfo {
|
|
||||||
match self {
|
|
||||||
TypeInfo::Integer => match rhs {
|
|
||||||
TypeInfo::Integer => TypeInfo::Integer,
|
|
||||||
TypeInfo::Double => TypeInfo::Double,
|
|
||||||
_ => panic!(),
|
|
||||||
},
|
|
||||||
TypeInfo::Double => TypeInfo::Double,
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn can_divide(&self, rhs: &Self) -> bool {
|
|
||||||
are_numbers(self, rhs)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn divide_result(&self, _rhs: &Self) -> TypeInfo {
|
|
||||||
TypeInfo::Double // ok for now
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn can_modulo(&self, rhs: &Self) -> bool {
|
|
||||||
are_numbers(self, rhs)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn modulo_result(&self, rhs: &Self) -> TypeInfo {
|
|
||||||
match self {
|
|
||||||
TypeInfo::Integer => match rhs {
|
|
||||||
TypeInfo::Integer => TypeInfo::Integer,
|
|
||||||
TypeInfo::Double => TypeInfo::Double,
|
|
||||||
_ => panic!(),
|
|
||||||
},
|
|
||||||
TypeInfo::Double => match rhs {
|
|
||||||
TypeInfo::Integer | TypeInfo::Double => TypeInfo::Double,
|
|
||||||
_ => panic!(),
|
|
||||||
},
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn can_add(&self, rhs: &Self) -> bool {
|
pub fn can_add(&self, rhs: &Self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
TypeInfo::Integer => {
|
TypeInfo::Integer => {
|
||||||
@ -190,7 +127,15 @@ impl TypeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_subtract(&self, rhs: &Self) -> bool {
|
pub fn can_subtract(&self, rhs: &Self) -> bool {
|
||||||
are_numbers(self, rhs)
|
match self {
|
||||||
|
TypeInfo::Integer => {
|
||||||
|
matches!(rhs, TypeInfo::Integer | TypeInfo::Double)
|
||||||
|
}
|
||||||
|
TypeInfo::Double => {
|
||||||
|
matches!(rhs, TypeInfo::Integer | TypeInfo::Double)
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn subtract_result(&self, rhs: &Self) -> TypeInfo {
|
pub fn subtract_result(&self, rhs: &Self) -> TypeInfo {
|
||||||
@ -208,43 +153,15 @@ impl TypeInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_left_shift(&self, rhs: &Self) -> bool {
|
pub fn can_negate(&self) -> bool {
|
||||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
matches!(self, TypeInfo::Integer | TypeInfo::Double)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn left_shift_result(&self, _rhs: &Self) -> TypeInfo {
|
pub fn negate_result(&self) -> TypeInfo {
|
||||||
TypeInfo::Integer
|
match self {
|
||||||
|
TypeInfo::Integer => TypeInfo::Integer,
|
||||||
|
TypeInfo::Double => TypeInfo::Double,
|
||||||
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_right_shift(&self, rhs: &Self) -> bool {
|
|
||||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn right_shift_result(&self, _rhs: &Self) -> TypeInfo {
|
|
||||||
TypeInfo::Integer
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn can_bitwise_and(&self, rhs: &Self) -> bool {
|
|
||||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bitwise_and_result(&self, _rhs: &Self) -> TypeInfo {
|
|
||||||
TypeInfo::Integer
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn can_bitwise_xor(&self, rhs: &Self) -> bool {
|
|
||||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bitwise_xor_result(&self, _rhs: &Self) -> TypeInfo {
|
|
||||||
TypeInfo::Integer
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn can_bitwise_or(&self, rhs: &Self) -> bool {
|
|
||||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bitwise_or_result(&self, _rhs: &Self) -> TypeInfo {
|
|
||||||
TypeInfo::Integer
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,19 +31,9 @@ pub enum Instruction {
|
|||||||
/// (field_pointer_mut_location, operand)
|
/// (field_pointer_mut_location, operand)
|
||||||
SetField(Location, SetFieldOperand),
|
SetField(Location, SetFieldOperand),
|
||||||
|
|
||||||
Multiply(MultiplyOperand, MultiplyOperand, Location),
|
|
||||||
Divide(LocationOrNumber, LocationOrNumber, Location),
|
|
||||||
Modulo(LocationOrNumber, LocationOrNumber, Location),
|
|
||||||
|
|
||||||
Add(AddOperand, AddOperand, Location),
|
Add(AddOperand, AddOperand, Location),
|
||||||
Subtract(SubtractOperand, SubtractOperand, Location),
|
Subtract(SubtractOperand, SubtractOperand, Location),
|
||||||
|
Multiply(MultiplyOperand, MultiplyOperand, Location),
|
||||||
LeftShift(LocationOrInteger, LocationOrInteger, Location),
|
|
||||||
RightShift(LocationOrInteger, LocationOrInteger, Location),
|
|
||||||
|
|
||||||
BitwiseAnd(LocationOrInteger, LocationOrInteger, Location),
|
|
||||||
BitwiseXor(LocationOrInteger, LocationOrInteger, Location),
|
|
||||||
BitwiseOr(LocationOrInteger, LocationOrInteger, Location),
|
|
||||||
|
|
||||||
Pop(Option<Location>),
|
Pop(Option<Location>),
|
||||||
|
|
||||||
@ -75,41 +65,15 @@ impl Display for Instruction {
|
|||||||
write!(f, "pop")
|
write!(f, "pop")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction::Multiply(left, right, destination) => {
|
|
||||||
write!(f, "mul {}, {}, {}", left, right, destination)
|
|
||||||
}
|
|
||||||
Instruction::Divide(left, right, destination) => {
|
|
||||||
write!(f, "div {}, {}, {}", left, right, destination)
|
|
||||||
}
|
|
||||||
Instruction::Modulo(left, right, destination) => {
|
|
||||||
write!(f, "mod {}, {}, {}", left, right, destination)
|
|
||||||
}
|
|
||||||
|
|
||||||
Instruction::Add(left, right, destination) => {
|
Instruction::Add(left, right, destination) => {
|
||||||
write!(f, "add {}, {}, {}", left, right, destination)
|
write!(f, "add {}, {}, {}", left, right, destination)
|
||||||
}
|
}
|
||||||
Instruction::Subtract(left, right, destination) => {
|
Instruction::Subtract(left, right, destination) => {
|
||||||
write!(f, "sub {}, {}, {}", left, right, destination)
|
write!(f, "sub {}, {}, {}", left, right, destination)
|
||||||
}
|
}
|
||||||
|
Instruction::Multiply(left, right, destination) => {
|
||||||
Instruction::LeftShift(left, right, destination) => {
|
write!(f, "mul {}, {}, {}", left, right, destination)
|
||||||
write!(f, "shl {}, {}, {}", left, right, destination)
|
|
||||||
}
|
}
|
||||||
Instruction::RightShift(left, right, destination) => {
|
|
||||||
write!(f, "shr {}, {}, {}", left, right, destination)
|
|
||||||
}
|
|
||||||
|
|
||||||
Instruction::BitwiseAnd(left, right, destination) => {
|
|
||||||
write!(f, "and {}, {}, {}", left, right, destination)
|
|
||||||
}
|
|
||||||
Instruction::BitwiseXor(left, right, destination) => {
|
|
||||||
write!(f, "xor {}, {}, {}", left, right, destination)
|
|
||||||
}
|
|
||||||
Instruction::BitwiseOr(left, right, destination) => {
|
|
||||||
write!(f, "or {}, {}, {}", left, right, destination)
|
|
||||||
}
|
|
||||||
|
|
||||||
Instruction::SetReturnValue(source) => {
|
Instruction::SetReturnValue(source) => {
|
||||||
write!(f, "srv {}", source)
|
write!(f, "srv {}", source)
|
||||||
}
|
}
|
||||||
@ -138,7 +102,7 @@ impl Display for Instruction {
|
|||||||
write!(f, "readf *{}, {}", field_pointer_location, destination)
|
write!(f, "readf *{}, {}", field_pointer_location, destination)
|
||||||
}
|
}
|
||||||
Instruction::SetField(self_location, destination) => {
|
Instruction::SetField(self_location, destination) => {
|
||||||
write!(f, "setf *{}, {}", self_location, destination)
|
write!(f, "setf {}, {}", self_location, destination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,46 +130,6 @@ impl Display for Location {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum LocationOrNumber {
|
|
||||||
Location(Location),
|
|
||||||
Int(i32),
|
|
||||||
Double(f64),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for LocationOrNumber {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
LocationOrNumber::Location(location) => {
|
|
||||||
write!(f, "{}", location)
|
|
||||||
}
|
|
||||||
LocationOrNumber::Int(i) => {
|
|
||||||
write!(f, "{}", i)
|
|
||||||
}
|
|
||||||
LocationOrNumber::Double(d) => {
|
|
||||||
write!(f, "{}", d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum LocationOrInteger {
|
|
||||||
Location(Location),
|
|
||||||
Int(i32),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for LocationOrInteger {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
LocationOrInteger::Location(location) => {
|
|
||||||
write!(f, "{}", location)
|
|
||||||
}
|
|
||||||
LocationOrInteger::Int(i) => {
|
|
||||||
write!(f, "{}", i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum MoveOperand {
|
pub enum MoveOperand {
|
||||||
Location(Location),
|
Location(Location),
|
||||||
Int(i32),
|
Int(i32),
|
||||||
|
|||||||
@ -6,8 +6,7 @@ use crate::vm::function::Function;
|
|||||||
use crate::vm::object::get_object;
|
use crate::vm::object::get_object;
|
||||||
use crate::vm::operand::Operand;
|
use crate::vm::operand::Operand;
|
||||||
use crate::vm::operand_helpers::{
|
use crate::vm::operand_helpers::{
|
||||||
add_operand_to_value, location_or_integer_to_value, location_or_number_to_value,
|
add_operand_to_value, move_operand_to_value, multiply_operand_to_value, push_operand_to_value,
|
||||||
move_operand_to_value, multiply_operand_to_value, push_operand_to_value,
|
|
||||||
return_operand_to_value, set_field_operand_to_value, subtract_operand_to_value,
|
return_operand_to_value, set_field_operand_to_value, subtract_operand_to_value,
|
||||||
};
|
};
|
||||||
use crate::vm::util::*;
|
use crate::vm::util::*;
|
||||||
@ -420,72 +419,6 @@ pub fn call<'a>(
|
|||||||
call_stack.top_mut().increment_ip();
|
call_stack.top_mut().increment_ip();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Multiplicative instructions */
|
|
||||||
Instruction::Multiply(left_operand, right_operand, destination) => {
|
|
||||||
let left_value =
|
|
||||||
multiply_operand_to_value(left_operand, registers, call_stack.top());
|
|
||||||
let right_value =
|
|
||||||
multiply_operand_to_value(right_operand, registers, call_stack.top());
|
|
||||||
|
|
||||||
let result = match left_value {
|
|
||||||
Value::Int(li) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Int(li * ri),
|
|
||||||
Value::Double(rd) => Value::Double(li as f64 * rd),
|
|
||||||
_ => panic!("Attempt to multiply {:?} and {:?}", left_value, right_value),
|
|
||||||
},
|
|
||||||
Value::Double(ld) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Double(ld * ri as f64),
|
|
||||||
Value::Double(rd) => Value::Double(ld * rd),
|
|
||||||
_ => panic!("Attempt to multiply {:?} and {:?}", left_value, right_value),
|
|
||||||
},
|
|
||||||
_ => panic!("Attempt to multiply {:?} and {:?}", left_value, right_value),
|
|
||||||
};
|
|
||||||
|
|
||||||
put_value(registers, call_stack.top_mut(), destination, result);
|
|
||||||
call_stack.top_mut().increment_ip();
|
|
||||||
}
|
|
||||||
Instruction::Divide(left, right, destination) => {
|
|
||||||
let left_value = location_or_number_to_value(left, registers, call_stack.top());
|
|
||||||
let right_value = location_or_number_to_value(right, registers, call_stack.top());
|
|
||||||
|
|
||||||
let result = match left_value {
|
|
||||||
Value::Int(li) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Double(li as f64 / ri as f64),
|
|
||||||
Value::Double(rd) => Value::Double(li as f64 / rd),
|
|
||||||
_ => panic!("Attempt to divide {:?} and {:?}", left_value, right_value),
|
|
||||||
},
|
|
||||||
Value::Double(ld) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Double(ld / ri as f64),
|
|
||||||
Value::Double(rd) => Value::Double(ld / rd),
|
|
||||||
_ => panic!("Attempt to divide {:?} and {:?}", left_value, right_value),
|
|
||||||
},
|
|
||||||
_ => panic!("Attempt to divide {:?} and {:?}", left_value, right_value),
|
|
||||||
};
|
|
||||||
put_value(registers, call_stack.top_mut(), destination, result);
|
|
||||||
call_stack.top_mut().increment_ip();
|
|
||||||
}
|
|
||||||
Instruction::Modulo(left, right, destination) => {
|
|
||||||
let left_value = location_or_number_to_value(left, registers, call_stack.top());
|
|
||||||
let right_value = location_or_number_to_value(right, registers, call_stack.top());
|
|
||||||
|
|
||||||
let result = match left_value {
|
|
||||||
Value::Int(li) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Int(li % ri),
|
|
||||||
Value::Double(rd) => Value::Double(li as f64 % rd),
|
|
||||||
_ => panic!("Attempt to modulo {:?} and {:?}", left_value, right_value),
|
|
||||||
},
|
|
||||||
Value::Double(ld) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Double(ld % ri as f64),
|
|
||||||
Value::Double(rd) => Value::Double(ld % rd),
|
|
||||||
_ => panic!("Attempt to modulo {:?} and {:?}", left_value, right_value),
|
|
||||||
},
|
|
||||||
_ => panic!("Attempt to modulo {:?} and {:?}", left_value, right_value),
|
|
||||||
};
|
|
||||||
|
|
||||||
put_value(registers, call_stack.top_mut(), destination, result);
|
|
||||||
call_stack.top_mut().increment_ip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add instructions */
|
/* Add instructions */
|
||||||
Instruction::Add(left_operand, right_operand, destination) => {
|
Instruction::Add(left_operand, right_operand, destination) => {
|
||||||
let left_value = add_operand_to_value(
|
let left_value = add_operand_to_value(
|
||||||
@ -559,86 +492,24 @@ pub fn call<'a>(
|
|||||||
put_value(registers, call_stack.top_mut(), destination, result);
|
put_value(registers, call_stack.top_mut(), destination, result);
|
||||||
call_stack.top_mut().increment_ip();
|
call_stack.top_mut().increment_ip();
|
||||||
}
|
}
|
||||||
|
Instruction::Multiply(left_operand, right_operand, destination) => {
|
||||||
/* Shift instructions */
|
let left_value =
|
||||||
Instruction::LeftShift(left, right, destination) => {
|
multiply_operand_to_value(left_operand, registers, call_stack.top());
|
||||||
let left_value = location_or_integer_to_value(left, registers, call_stack.top());
|
let right_value =
|
||||||
let right_value = location_or_integer_to_value(right, registers, call_stack.top());
|
multiply_operand_to_value(right_operand, registers, call_stack.top());
|
||||||
|
|
||||||
let result = match left_value {
|
let result = match left_value {
|
||||||
Value::Int(li) => match right_value {
|
Value::Int(li) => match right_value {
|
||||||
Value::Int(ri) => Value::Int(li << ri),
|
Value::Int(ri) => Value::Int(li * ri),
|
||||||
_ => panic!("Attempt to left shift {} by {}", left, right),
|
Value::Double(rd) => Value::Double(li as f64 * rd),
|
||||||
|
_ => panic!("Attempt to multiply {:?} and {:?}", left_value, right_value),
|
||||||
},
|
},
|
||||||
_ => panic!("Attempt to left shift {} by {}", left_value, right_value),
|
Value::Double(ld) => match right_value {
|
||||||
};
|
Value::Int(ri) => Value::Double(ld * ri as f64),
|
||||||
|
Value::Double(rd) => Value::Double(ld * rd),
|
||||||
put_value(registers, call_stack.top_mut(), destination, result);
|
_ => panic!("Attempt to multiply {:?} and {:?}", left_value, right_value),
|
||||||
call_stack.top_mut().increment_ip();
|
|
||||||
}
|
|
||||||
Instruction::RightShift(left, right, destination) => {
|
|
||||||
let left_value = location_or_integer_to_value(left, registers, call_stack.top());
|
|
||||||
let right_value = location_or_integer_to_value(right, registers, call_stack.top());
|
|
||||||
|
|
||||||
let result = match left_value {
|
|
||||||
Value::Int(li) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Int(li >> ri),
|
|
||||||
_ => panic!("Attempt to right shift {} by {}", left_value, right_value),
|
|
||||||
},
|
},
|
||||||
_ => panic!("Attempt to right shift {} by {}", left_value, right_value),
|
_ => panic!("Attempt to multiply {:?} and {:?}", left_value, right_value),
|
||||||
};
|
|
||||||
|
|
||||||
put_value(registers, call_stack.top_mut(), destination, result);
|
|
||||||
call_stack.top_mut().increment_ip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bitwise instructions */
|
|
||||||
Instruction::BitwiseAnd(left, right, destination) => {
|
|
||||||
let left_value = location_or_integer_to_value(left, registers, call_stack.top());
|
|
||||||
let right_value = location_or_integer_to_value(right, registers, call_stack.top());
|
|
||||||
|
|
||||||
let result = match left_value {
|
|
||||||
Value::Int(li) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Int(li & ri),
|
|
||||||
_ => panic!("Attempt to bitwise and {} by {}", left_value, right_value),
|
|
||||||
},
|
|
||||||
_ => panic!("Attempt to bitwise and {} by {}", left_value, right_value),
|
|
||||||
};
|
|
||||||
|
|
||||||
put_value(registers, call_stack.top_mut(), destination, result);
|
|
||||||
call_stack.top_mut().increment_ip();
|
|
||||||
}
|
|
||||||
Instruction::BitwiseXor(left, right, destination) => {
|
|
||||||
let left_value = location_or_integer_to_value(left, registers, call_stack.top());
|
|
||||||
let right_value = location_or_integer_to_value(right, registers, call_stack.top());
|
|
||||||
|
|
||||||
let result = match left_value {
|
|
||||||
Value::Int(li) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Int(li ^ ri),
|
|
||||||
_ => panic!("Attempt to bitwise xor {} by {}", left_value, right_value),
|
|
||||||
},
|
|
||||||
_ => panic!(
|
|
||||||
"Attempt to left bitwise xor {} by {}",
|
|
||||||
left_value, right_value
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
put_value(registers, call_stack.top_mut(), destination, result);
|
|
||||||
call_stack.top_mut().increment_ip();
|
|
||||||
}
|
|
||||||
Instruction::BitwiseOr(left, right, destination) => {
|
|
||||||
let left_value = location_or_integer_to_value(left, registers, call_stack.top());
|
|
||||||
let right_value = location_or_integer_to_value(right, registers, call_stack.top());
|
|
||||||
|
|
||||||
let result = match left_value {
|
|
||||||
Value::Int(li) => match right_value {
|
|
||||||
Value::Int(ri) => Value::Int(li | ri),
|
|
||||||
_ => panic!("Attempt to bitwise or {} by {}", left_value, right_value),
|
|
||||||
},
|
|
||||||
_ => panic!(
|
|
||||||
"Attempt to left bitwise or {} by {}",
|
|
||||||
left_value, right_value
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
put_value(registers, call_stack.top_mut(), destination, result);
|
put_value(registers, call_stack.top_mut(), destination, result);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::instruction::{
|
use crate::instruction::{
|
||||||
AddOperand, LocationOrInteger, LocationOrNumber, MoveOperand, MultiplyOperand, PushOperand,
|
AddOperand, MoveOperand, MultiplyOperand, PushOperand, ReturnOperand, SetFieldOperand,
|
||||||
ReturnOperand, SetFieldOperand, SubtractOperand,
|
SubtractOperand,
|
||||||
};
|
};
|
||||||
use crate::vm::CallFrame;
|
use crate::vm::CallFrame;
|
||||||
use crate::vm::constant::Constant;
|
use crate::vm::constant::Constant;
|
||||||
@ -138,36 +138,3 @@ pub fn set_field_operand_to_value(
|
|||||||
SetFieldOperand::String(constant_name) => load_constant_value(constants, constant_name),
|
SetFieldOperand::String(constant_name) => load_constant_value(constants, constant_name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn location_or_number_to_value(
|
|
||||||
location_or_number: &LocationOrNumber,
|
|
||||||
registers: &[Operand],
|
|
||||||
current_frame: &CallFrame,
|
|
||||||
) -> Value {
|
|
||||||
match location_or_number {
|
|
||||||
LocationOrNumber::Location(location) => load_value(
|
|
||||||
registers,
|
|
||||||
current_frame.stack(),
|
|
||||||
current_frame.fp(),
|
|
||||||
location,
|
|
||||||
),
|
|
||||||
LocationOrNumber::Int(i) => Value::Int(*i),
|
|
||||||
LocationOrNumber::Double(d) => Value::Double(*d),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn location_or_integer_to_value(
|
|
||||||
location_or_integer: &LocationOrInteger,
|
|
||||||
registers: &[Operand],
|
|
||||||
current_frame: &CallFrame,
|
|
||||||
) -> Value {
|
|
||||||
match location_or_integer {
|
|
||||||
LocationOrInteger::Location(location) => load_value(
|
|
||||||
registers,
|
|
||||||
current_frame.stack(),
|
|
||||||
current_frame.fp(),
|
|
||||||
location,
|
|
||||||
),
|
|
||||||
LocationOrInteger::Int(i) => Value::Int(*i),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user