Convert LoadBoolean to LoadEncoded; Fix register handling
This commit is contained in:
parent
6f0955c29a
commit
bd273035aa
@ -629,11 +629,12 @@ impl<'src> Compiler<'src> {
|
||||
if let Token::Boolean(text) = self.current_token {
|
||||
self.advance()?;
|
||||
|
||||
let boolean = text.parse::<bool>().unwrap();
|
||||
let boolean = text.parse::<bool>().unwrap() as u16;
|
||||
let destination = self.next_boolean_register();
|
||||
let load_boolean = Instruction::load_boolean(destination, boolean, false);
|
||||
let load_encoded =
|
||||
Instruction::load_encoded(destination, boolean, TypeCode::BOOLEAN, false);
|
||||
|
||||
self.emit_instruction(load_boolean, Type::Boolean, position);
|
||||
self.emit_instruction(load_encoded, Type::Boolean, position);
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
@ -652,10 +653,12 @@ impl<'src> Compiler<'src> {
|
||||
self.advance()?;
|
||||
|
||||
let byte = u8::from_str_radix(&text[2..], 16)
|
||||
.map_err(|error| CompileError::ParseIntError { error, position })?;
|
||||
let value = ConcreteValue::Byte(byte);
|
||||
.map_err(|error| CompileError::ParseIntError { error, position })?
|
||||
as u16;
|
||||
let destination = self.next_byte_register();
|
||||
let load_encoded = Instruction::load_encoded(destination, byte, TypeCode::BYTE, false);
|
||||
|
||||
self.emit_constant(value, position)?;
|
||||
self.emit_instruction(load_encoded, Type::Byte, position);
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
@ -836,7 +839,7 @@ impl<'src> Compiler<'src> {
|
||||
let (argument, push_back) = match instruction.operation() {
|
||||
Operation::LOAD_CONSTANT => (Operand::Constant(instruction.b_field()), false),
|
||||
Operation::POINT => (instruction.b_as_operand(), false),
|
||||
Operation::LOAD_BOOLEAN
|
||||
Operation::LOAD_ENCODED
|
||||
| Operation::LOAD_LIST
|
||||
| Operation::LOAD_SELF
|
||||
| Operation::ADD
|
||||
@ -1114,8 +1117,10 @@ impl<'src> Compiler<'src> {
|
||||
}
|
||||
};
|
||||
let jump = Instruction::jump(1, true);
|
||||
let load_true = Instruction::load_boolean(destination, true, true);
|
||||
let load_false = Instruction::load_boolean(destination, false, false);
|
||||
let load_true =
|
||||
Instruction::load_encoded(destination, true as u16, TypeCode::BOOLEAN, true);
|
||||
let load_false =
|
||||
Instruction::load_encoded(destination, false as u16, TypeCode::BOOLEAN, false);
|
||||
|
||||
self.emit_instruction(comparison, Type::Boolean, operator_position);
|
||||
self.emit_instruction(jump, Type::None, operator_position);
|
||||
@ -1385,8 +1390,8 @@ impl<'src> Compiler<'src> {
|
||||
Some([
|
||||
Operation::EQUAL | Operation::LESS | Operation::LESS_EQUAL,
|
||||
Operation::JUMP,
|
||||
Operation::LOAD_BOOLEAN,
|
||||
Operation::LOAD_BOOLEAN
|
||||
Operation::LOAD_ENCODED,
|
||||
Operation::LOAD_ENCODED
|
||||
]),
|
||||
) {
|
||||
self.instructions.pop();
|
||||
@ -1456,7 +1461,7 @@ impl<'src> Compiler<'src> {
|
||||
match else_block_distance {
|
||||
0 => {}
|
||||
1 => {
|
||||
if let Some([Operation::LOAD_BOOLEAN | Operation::LOAD_CONSTANT, _]) =
|
||||
if let Some([Operation::LOAD_ENCODED | Operation::LOAD_CONSTANT, _]) =
|
||||
self.get_last_operations()
|
||||
{
|
||||
let loader_index = self.instructions.len() - 2;
|
||||
@ -1491,7 +1496,7 @@ impl<'src> Compiler<'src> {
|
||||
self.instructions
|
||||
.insert(if_block_start, (jump, Type::None, if_block_start_position));
|
||||
|
||||
let if_block_last_instruction_index = self.instructions.len() - else_block_distance - 1;
|
||||
let if_block_last_instruction_index = self.instructions.len() - else_block_distance;
|
||||
let else_block_last_instruction_index = self.instructions.len() - 1;
|
||||
|
||||
let if_block_last_instruction = self.instructions[if_block_last_instruction_index].0;
|
||||
@ -1500,8 +1505,6 @@ impl<'src> Compiler<'src> {
|
||||
|
||||
else_block_last_instruction.set_a_field(if_block_last_instruction.a_field());
|
||||
|
||||
println!("{if_block_last_instruction_index} {else_block_last_instruction_index}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -1517,8 +1520,8 @@ impl<'src> Compiler<'src> {
|
||||
Some([
|
||||
Operation::EQUAL | Operation::LESS | Operation::LESS_EQUAL,
|
||||
Operation::JUMP,
|
||||
Operation::LOAD_BOOLEAN,
|
||||
Operation::LOAD_BOOLEAN
|
||||
Operation::LOAD_ENCODED,
|
||||
Operation::LOAD_ENCODED
|
||||
]),
|
||||
) {
|
||||
self.instructions.pop();
|
||||
|
@ -1,57 +0,0 @@
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
use crate::{Instruction, Operation};
|
||||
|
||||
use super::InstructionFields;
|
||||
|
||||
pub struct LoadBoolean {
|
||||
pub destination: u16,
|
||||
pub value: bool,
|
||||
pub jump_next: bool,
|
||||
}
|
||||
|
||||
impl From<Instruction> for LoadBoolean {
|
||||
fn from(instruction: Instruction) -> Self {
|
||||
LoadBoolean {
|
||||
destination: instruction.a_field(),
|
||||
value: instruction.b_field() != 0,
|
||||
jump_next: instruction.c_field() != 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LoadBoolean> for Instruction {
|
||||
fn from(load_boolean: LoadBoolean) -> Self {
|
||||
let operation = Operation::LOAD_BOOLEAN;
|
||||
let a_field = load_boolean.destination;
|
||||
let b_field = load_boolean.value as u16;
|
||||
let c_field = load_boolean.jump_next as u16;
|
||||
|
||||
InstructionFields {
|
||||
operation,
|
||||
a_field,
|
||||
b_field,
|
||||
c_field,
|
||||
..Default::default()
|
||||
}
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for LoadBoolean {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
let LoadBoolean {
|
||||
destination,
|
||||
value,
|
||||
jump_next,
|
||||
} = self;
|
||||
|
||||
write!(f, "R{destination} = {value}")?;
|
||||
|
||||
if *jump_next {
|
||||
write!(f, " JUMP +1")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
74
dust-lang/src/instruction/load_encoded.rs
Normal file
74
dust-lang/src/instruction/load_encoded.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
use crate::{Instruction, Operation};
|
||||
|
||||
use super::{InstructionFields, TypeCode};
|
||||
|
||||
pub struct LoadEncoded {
|
||||
pub destination: u16,
|
||||
pub value: u16,
|
||||
pub value_type: TypeCode,
|
||||
pub jump_next: bool,
|
||||
}
|
||||
|
||||
impl From<Instruction> for LoadEncoded {
|
||||
fn from(instruction: Instruction) -> Self {
|
||||
LoadEncoded {
|
||||
destination: instruction.a_field(),
|
||||
value: instruction.b_field(),
|
||||
value_type: instruction.b_type(),
|
||||
jump_next: instruction.c_field() != 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LoadEncoded> for Instruction {
|
||||
fn from(load_boolean: LoadEncoded) -> Self {
|
||||
let operation = Operation::LOAD_ENCODED;
|
||||
let a_field = load_boolean.destination;
|
||||
let b_field = load_boolean.value;
|
||||
let b_type = load_boolean.value_type;
|
||||
let c_field = load_boolean.jump_next as u16;
|
||||
|
||||
InstructionFields {
|
||||
operation,
|
||||
a_field,
|
||||
b_field,
|
||||
b_type,
|
||||
c_field,
|
||||
..Default::default()
|
||||
}
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for LoadEncoded {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
let LoadEncoded {
|
||||
destination,
|
||||
value,
|
||||
value_type,
|
||||
jump_next,
|
||||
} = self;
|
||||
|
||||
match *value_type {
|
||||
TypeCode::BOOLEAN => {
|
||||
let boolean = *value != 0;
|
||||
|
||||
write!(f, "R_BOOL_{destination} = {boolean}")?
|
||||
}
|
||||
TypeCode::BYTE => {
|
||||
let byte = *value as u8;
|
||||
|
||||
write!(f, "R_BYTE_{destination} = 0x{byte:0X}")?
|
||||
}
|
||||
_ => panic!("Invalid type code {value_type} for LoadEncoded instruction"),
|
||||
}
|
||||
|
||||
if *jump_next {
|
||||
write!(f, " JUMP +1")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -102,8 +102,8 @@ mod equal;
|
||||
mod jump;
|
||||
mod less;
|
||||
mod less_equal;
|
||||
mod load_boolean;
|
||||
mod load_constant;
|
||||
mod load_encoded;
|
||||
mod load_function;
|
||||
mod load_list;
|
||||
mod load_self;
|
||||
@ -128,8 +128,8 @@ pub use equal::Equal;
|
||||
pub use jump::Jump;
|
||||
pub use less::Less;
|
||||
pub use less_equal::LessEqual;
|
||||
pub use load_boolean::LoadBoolean;
|
||||
pub use load_constant::LoadConstant;
|
||||
pub use load_encoded::LoadEncoded;
|
||||
pub use load_function::LoadFunction;
|
||||
pub use load_list::LoadList;
|
||||
pub use load_self::LoadSelf;
|
||||
@ -286,10 +286,16 @@ impl Instruction {
|
||||
Instruction::from(Close { from, to })
|
||||
}
|
||||
|
||||
pub fn load_boolean(destination: u16, value: bool, jump_next: bool) -> Instruction {
|
||||
Instruction::from(LoadBoolean {
|
||||
pub fn load_encoded(
|
||||
destination: u16,
|
||||
value: u16,
|
||||
value_type: TypeCode,
|
||||
jump_next: bool,
|
||||
) -> Instruction {
|
||||
Instruction::from(LoadEncoded {
|
||||
destination,
|
||||
value,
|
||||
value_type,
|
||||
jump_next,
|
||||
})
|
||||
}
|
||||
@ -546,7 +552,7 @@ impl Instruction {
|
||||
match self.operation() {
|
||||
Operation::LOAD_CONSTANT => Some(Operand::Constant(self.b_field())),
|
||||
Operation::POINT
|
||||
| Operation::LOAD_BOOLEAN
|
||||
| Operation::LOAD_ENCODED
|
||||
| Operation::LOAD_LIST
|
||||
| Operation::LOAD_SELF
|
||||
| Operation::ADD
|
||||
@ -599,7 +605,7 @@ impl Instruction {
|
||||
pub fn yields_value(&self) -> bool {
|
||||
match self.operation() {
|
||||
Operation::POINT
|
||||
| Operation::LOAD_BOOLEAN
|
||||
| Operation::LOAD_ENCODED
|
||||
| Operation::LOAD_CONSTANT
|
||||
| Operation::LOAD_FUNCTION
|
||||
| Operation::LOAD_LIST
|
||||
@ -633,7 +639,7 @@ impl Instruction {
|
||||
|
||||
match operation {
|
||||
Operation::POINT => Point::from(*self).to_string(),
|
||||
Operation::LOAD_BOOLEAN => LoadBoolean::from(*self).to_string(),
|
||||
Operation::LOAD_ENCODED => LoadEncoded::from(*self).to_string(),
|
||||
Operation::LOAD_CONSTANT => LoadConstant::from(*self).to_string(),
|
||||
Operation::LOAD_FUNCTION => LoadFunction::from(*self).to_string(),
|
||||
Operation::LOAD_LIST => LoadList::from(*self).to_string(),
|
||||
|
@ -14,7 +14,7 @@ impl Operation {
|
||||
pub const CLOSE: Operation = Operation(1);
|
||||
|
||||
// Loaders
|
||||
pub const LOAD_BOOLEAN: Operation = Operation(2);
|
||||
pub const LOAD_ENCODED: Operation = Operation(2);
|
||||
pub const LOAD_CONSTANT: Operation = Operation(3);
|
||||
pub const LOAD_FUNCTION: Operation = Operation(4);
|
||||
pub const LOAD_LIST: Operation = Operation(5);
|
||||
@ -53,7 +53,7 @@ impl Operation {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match *self {
|
||||
Self::POINT => "POINT",
|
||||
Self::LOAD_BOOLEAN => "LOAD_BOOLEAN",
|
||||
Self::LOAD_ENCODED => "LOAD_ENCODED",
|
||||
Self::LOAD_CONSTANT => "LOAD_CONSTANT",
|
||||
Self::LOAD_FUNCTION => "LOAD_FUNCTION",
|
||||
Self::LOAD_LIST => "LOAD_LIST",
|
||||
|
@ -276,7 +276,7 @@ mod tests {
|
||||
const ALL_OPERATIONS: [(Operation, RunnerLogic); 23] = [
|
||||
(Operation::POINT, point),
|
||||
(Operation::CLOSE, close),
|
||||
(Operation::LOAD_BOOLEAN, load_boolean),
|
||||
(Operation::LOAD_ENCODED, load_boolean),
|
||||
(Operation::LOAD_CONSTANT, load_constant),
|
||||
(Operation::LOAD_FUNCTION, load_function),
|
||||
(Operation::LOAD_LIST, load_list),
|
||||
|
@ -15,10 +15,10 @@ fn true_and_true() {
|
||||
return_type: Type::Boolean,
|
||||
},
|
||||
smallvec![
|
||||
Instruction::load_boolean(0, true, false),
|
||||
Instruction::load_encoded(0, true, false),
|
||||
Instruction::test(0, true),
|
||||
Instruction::jump(1, true),
|
||||
Instruction::load_boolean(1, true, false),
|
||||
Instruction::load_encoded(1, true, false),
|
||||
Instruction::r#return(true),
|
||||
],
|
||||
smallvec![
|
||||
@ -51,10 +51,10 @@ fn false_and_false() {
|
||||
return_type: Type::Boolean,
|
||||
},
|
||||
smallvec![
|
||||
Instruction::load_boolean(0, false, false),
|
||||
Instruction::load_encoded(0, false, false),
|
||||
Instruction::test(0, true),
|
||||
Instruction::jump(1, true),
|
||||
Instruction::load_boolean(1, false, false),
|
||||
Instruction::load_encoded(1, false, false),
|
||||
Instruction::r#return(true),
|
||||
],
|
||||
smallvec![
|
||||
@ -87,10 +87,10 @@ fn false_and_true() {
|
||||
return_type: Type::Boolean,
|
||||
},
|
||||
smallvec![
|
||||
Instruction::load_boolean(0, false, false),
|
||||
Instruction::load_encoded(0, false, false),
|
||||
Instruction::test(0, true),
|
||||
Instruction::jump(1, true),
|
||||
Instruction::load_boolean(1, true, false),
|
||||
Instruction::load_encoded(1, true, false),
|
||||
Instruction::r#return(true),
|
||||
],
|
||||
smallvec![
|
||||
@ -123,10 +123,10 @@ fn true_and_false() {
|
||||
return_type: Type::Boolean,
|
||||
},
|
||||
smallvec![
|
||||
Instruction::load_boolean(0, true, false),
|
||||
Instruction::load_encoded(0, true, false),
|
||||
Instruction::test(0, true),
|
||||
Instruction::jump(1, true),
|
||||
Instruction::load_boolean(1, false, false),
|
||||
Instruction::load_encoded(1, false, false),
|
||||
Instruction::r#return(true),
|
||||
],
|
||||
smallvec![
|
||||
|
@ -15,13 +15,13 @@ fn true_and_true_and_true() {
|
||||
return_type: Type::Boolean,
|
||||
},
|
||||
smallvec![
|
||||
Instruction::load_boolean(0, true, false),
|
||||
Instruction::load_encoded(0, true, false),
|
||||
Instruction::test(0, true),
|
||||
Instruction::jump(1, true),
|
||||
Instruction::load_boolean(1, true, false),
|
||||
Instruction::load_encoded(1, true, false),
|
||||
Instruction::test(1, true),
|
||||
Instruction::jump(1, true),
|
||||
Instruction::load_boolean(2, true, false),
|
||||
Instruction::load_encoded(2, true, false),
|
||||
Instruction::r#return(true),
|
||||
],
|
||||
smallvec![
|
||||
|
@ -15,10 +15,10 @@ fn true_or_false() {
|
||||
return_type: Type::Boolean,
|
||||
},
|
||||
smallvec![
|
||||
Instruction::load_boolean(0, true, false),
|
||||
Instruction::load_encoded(0, true, false),
|
||||
Instruction::test(0, false),
|
||||
Instruction::jump(1, true),
|
||||
Instruction::load_boolean(1, false, false),
|
||||
Instruction::load_encoded(1, false, false),
|
||||
Instruction::r#return(true),
|
||||
],
|
||||
smallvec![
|
||||
|
@ -39,7 +39,7 @@ fn not() {
|
||||
return_type: Type::Boolean,
|
||||
},
|
||||
vec![
|
||||
(Instruction::load_boolean(0, true, false), Span(1, 5)),
|
||||
(Instruction::load_encoded(0, true, false), Span(1, 5)),
|
||||
(Instruction::not(1, Operand::Register(0)), Span(0, 1)),
|
||||
(Instruction::r#return(true), Span(5, 5)),
|
||||
],
|
||||
|
Loading…
x
Reference in New Issue
Block a user