Implement unary operators and divide binary parsing
This commit is contained in:
parent
23f733d8b2
commit
c5c2fe95ae
@ -322,35 +322,32 @@ impl<'src> Parser<'src> {
|
|||||||
let (previous_instruction, previous_position) =
|
let (previous_instruction, previous_position) =
|
||||||
self.chunk.pop_instruction(self.current_position)?;
|
self.chunk.pop_instruction(self.current_position)?;
|
||||||
|
|
||||||
let (is_constant, destination, from_register) = match previous_instruction.operation() {
|
let (push_back, is_constant, argument) = {
|
||||||
|
match previous_instruction.operation() {
|
||||||
|
Operation::GetLocal => (false, false, previous_instruction.destination()),
|
||||||
Operation::LoadConstant => {
|
Operation::LoadConstant => {
|
||||||
self.decrement_register()?;
|
self.decrement_register()?;
|
||||||
|
|
||||||
(
|
(false, true, previous_instruction.first_argument())
|
||||||
true,
|
|
||||||
previous_instruction.destination(),
|
|
||||||
previous_instruction.first_argument(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Operation::LoadBoolean => {
|
Operation::LoadBoolean => {
|
||||||
self.decrement_register()?;
|
self.increment_register()?;
|
||||||
|
|
||||||
(
|
(true, false, previous_instruction.destination())
|
||||||
true,
|
|
||||||
previous_instruction.destination(),
|
|
||||||
previous_instruction.first_argument(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => {
|
Operation::Close => {
|
||||||
self.emit_instruction(previous_instruction, previous_position);
|
return Err(ParseError::ExpectedExpression {
|
||||||
|
found: self.previous_token.to_owned(),
|
||||||
(false, self.current_register, self.current_register - 1)
|
position: self.previous_position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_ => (true, false, previous_instruction.destination()),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut instruction = match operator.kind() {
|
let mut instruction = match operator.kind() {
|
||||||
TokenKind::Bang => Instruction::not(destination, from_register),
|
TokenKind::Bang => Instruction::not(self.current_register, argument),
|
||||||
TokenKind::Minus => Instruction::negate(destination, from_register),
|
TokenKind::Minus => Instruction::negate(self.current_register, argument),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ParseError::ExpectedTokenMultiple {
|
return Err(ParseError::ExpectedTokenMultiple {
|
||||||
expected: &[TokenKind::Bang, TokenKind::Minus],
|
expected: &[TokenKind::Bang, TokenKind::Minus],
|
||||||
@ -364,6 +361,10 @@ impl<'src> Parser<'src> {
|
|||||||
instruction.set_first_argument_to_constant();
|
instruction.set_first_argument_to_constant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if push_back {
|
||||||
|
self.emit_instruction(previous_instruction, previous_position);
|
||||||
|
}
|
||||||
|
|
||||||
self.emit_instruction(instruction, operator_position);
|
self.emit_instruction(instruction, operator_position);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -10,8 +10,8 @@ fn not() {
|
|||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_boolean(0, true, true), Span(1, 5)),
|
(Instruction::load_boolean(0, true, false), Span(1, 5)),
|
||||||
(Instruction::not(0, 0), Span(1, 5)),
|
(Instruction::not(1, 0), Span(0, 1)),
|
||||||
],
|
],
|
||||||
vec![],
|
vec![],
|
||||||
vec![]
|
vec![]
|
||||||
|
Loading…
Reference in New Issue
Block a user