mirror of
https://github.com/MorizzG/rlox.git
synced 2025-12-06 04:12:42 +00:00
improved REPL a bit
now uses rustyline for input
This commit is contained in:
parent
ca6e092b38
commit
fb88595b6c
13 changed files with 560 additions and 100 deletions
|
|
@ -9,10 +9,10 @@ path = "../frontend"
|
|||
|
||||
|
||||
[dependencies]
|
||||
itertools = "0.10.5"
|
||||
lazy_static = "1.4.0"
|
||||
num-derive = "0.3.3"
|
||||
num-traits = "0.2.15"
|
||||
regex = "1.7.1"
|
||||
thiserror = "1.0.38"
|
||||
static_assertions = "1.1.0"
|
||||
itertools = "0.13"
|
||||
lazy_static = "1"
|
||||
num-derive = "0.4"
|
||||
num-traits = "0.2"
|
||||
regex = "1"
|
||||
thiserror = "1"
|
||||
static_assertions = "1"
|
||||
|
|
|
|||
|
|
@ -236,7 +236,10 @@ impl Compiler {
|
|||
self.emit_opcode(Opcode::Negate);
|
||||
}
|
||||
TokenType::Bang => todo!(),
|
||||
_ => unreachable!("Called unary, but next token had token_type {:?}", token.token_type),
|
||||
_ => unreachable!(
|
||||
"Called unary, but next token had token_type {:?}",
|
||||
token.token_type
|
||||
),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -247,8 +250,10 @@ impl Compiler {
|
|||
|
||||
self.expression()?;
|
||||
|
||||
self.consume_token(TokenType::RightParen, |token| CompilerError::MissingRightParen {
|
||||
code_pos: token.code_pos,
|
||||
self.consume_token(TokenType::RightParen, |token| {
|
||||
CompilerError::MissingRightParen {
|
||||
code_pos: token.code_pos,
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -308,7 +313,10 @@ impl Compiler {
|
|||
Ok(())
|
||||
}
|
||||
// call err_fn with dummy token so we don't have to eat the EOF token
|
||||
TokenType::EOF => Err(err_fn(Token::new(TokenType::EOF, self.peek_token().code_pos))),
|
||||
TokenType::EOF => Err(err_fn(Token::new(
|
||||
TokenType::EOF,
|
||||
self.peek_token().code_pos,
|
||||
))),
|
||||
_ => Err(err_fn(self.next_token())),
|
||||
}
|
||||
}
|
||||
|
|
@ -346,9 +354,15 @@ impl Compiler {
|
|||
if const_idx <= u8::MAX as usize {
|
||||
self.emit_opcode_byte(Opcode::LoadConst, const_idx.try_into().unwrap());
|
||||
} else if const_idx <= u16::MAX as usize {
|
||||
self.emit_opcode_bytes(Opcode::LoadConstLong, &u16_to_bytes(const_idx.try_into().unwrap()))
|
||||
self.emit_opcode_bytes(
|
||||
Opcode::LoadConstLong,
|
||||
&u16_to_bytes(const_idx.try_into().unwrap()),
|
||||
)
|
||||
} else {
|
||||
panic!("Tried to add more than {} constants to current chunk", u16::MAX);
|
||||
panic!(
|
||||
"Tried to add more than {} constants to current chunk",
|
||||
u16::MAX
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ pub struct ChunkDebugInfo {
|
|||
|
||||
impl ChunkDebugInfo {
|
||||
pub fn new() -> Self {
|
||||
ChunkDebugInfo { line_infos: Vec::new() }
|
||||
ChunkDebugInfo {
|
||||
line_infos: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_line(&mut self, line: u32, offset: usize) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@ pub enum RuntimeError {
|
|||
#[error("Opcopde {opcode} had invalid operand {operand}")]
|
||||
UnaryInvalidOperand { opcode: Opcode, operand: Value },
|
||||
#[error("Opcopde {opcode} had invalid operands {left} and {right}")]
|
||||
BinaryInvalidOperand { opcode: Opcode, left: Value, right: Value },
|
||||
BinaryInvalidOperand {
|
||||
opcode: Opcode,
|
||||
left: Value,
|
||||
right: Value,
|
||||
},
|
||||
#[error("Division by zero")]
|
||||
DivisionByZero,
|
||||
}
|
||||
|
|
@ -52,7 +56,7 @@ impl From<RuntimeError> for LoxError {
|
|||
}
|
||||
}
|
||||
|
||||
fn format_multiple_errors(errs: &Vec<impl std::error::Error>) -> String {
|
||||
fn format_multiple_errors(errs: &[impl std::error::Error]) -> String {
|
||||
let msg = if errs.len() == 1 {
|
||||
errs[0].to_string()
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -51,9 +51,12 @@ pub fn run_repl(vm: &mut VM) {
|
|||
std::process::exit(66);
|
||||
});
|
||||
|
||||
let num_open_braces = (input_buf.matches('{').count() as i64) - (input_buf.matches('}').count() as i64);
|
||||
let num_open_parens = (input_buf.matches('(').count() as i64) - (input_buf.matches(')').count() as i64);
|
||||
let num_open_brackets = (input_buf.matches('[').count() as i64) - (input_buf.matches(']').count() as i64);
|
||||
let num_open_braces =
|
||||
(input_buf.matches('{').count() as i64) - (input_buf.matches('}').count() as i64);
|
||||
let num_open_parens =
|
||||
(input_buf.matches('(').count() as i64) - (input_buf.matches(')').count() as i64);
|
||||
let num_open_brackets =
|
||||
(input_buf.matches('[').count() as i64) - (input_buf.matches(']').count() as i64);
|
||||
|
||||
// all braces/parens/brackets closed => break
|
||||
if num_open_braces == 0 && num_open_parens == 0 && num_open_brackets == 0 {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub enum Value {
|
||||
#[default]
|
||||
Nil,
|
||||
Number(f64),
|
||||
}
|
||||
|
||||
impl Default for Value {
|
||||
fn default() -> Self {
|
||||
Value::Nil
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Value {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
|
|
|
|||
37
vm/src/vm.rs
37
vm/src/vm.rs
|
|
@ -134,7 +134,13 @@ impl VM {
|
|||
self.push_value(Value::Number(left + right));
|
||||
}
|
||||
// (Value::String(left), Value::String(right)) => todo!(),
|
||||
(left, right) => return Err(RuntimeError::BinaryInvalidOperand { opcode, left, right }),
|
||||
(left, right) => {
|
||||
return Err(RuntimeError::BinaryInvalidOperand {
|
||||
opcode,
|
||||
left,
|
||||
right,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Opcode::Subtract => {
|
||||
|
|
@ -144,7 +150,13 @@ impl VM {
|
|||
(Value::Number(left), Value::Number(right)) => {
|
||||
self.push_value(Value::Number(left - right));
|
||||
}
|
||||
(left, right) => return Err(RuntimeError::BinaryInvalidOperand { opcode, left, right }),
|
||||
(left, right) => {
|
||||
return Err(RuntimeError::BinaryInvalidOperand {
|
||||
opcode,
|
||||
left,
|
||||
right,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Opcode::Multiply => {
|
||||
|
|
@ -154,7 +166,13 @@ impl VM {
|
|||
(Value::Number(left), Value::Number(right)) => {
|
||||
self.push_value(Value::Number(left * right));
|
||||
}
|
||||
(left, right) => return Err(RuntimeError::BinaryInvalidOperand { opcode, left, right }),
|
||||
(left, right) => {
|
||||
return Err(RuntimeError::BinaryInvalidOperand {
|
||||
opcode,
|
||||
left,
|
||||
right,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Opcode::Divide => {
|
||||
|
|
@ -167,7 +185,13 @@ impl VM {
|
|||
}
|
||||
self.push_value(Value::Number(left / right));
|
||||
}
|
||||
(left, right) => return Err(RuntimeError::BinaryInvalidOperand { opcode, left, right }),
|
||||
(left, right) => {
|
||||
return Err(RuntimeError::BinaryInvalidOperand {
|
||||
opcode,
|
||||
left,
|
||||
right,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Opcode::Negate => {
|
||||
|
|
@ -176,7 +200,10 @@ impl VM {
|
|||
if let Value::Number(num) = value {
|
||||
self.push_value(Value::Number(-num));
|
||||
} else {
|
||||
return Err(RuntimeError::UnaryInvalidOperand { opcode, operand: value });
|
||||
return Err(RuntimeError::UnaryInvalidOperand {
|
||||
opcode,
|
||||
operand: value,
|
||||
});
|
||||
}
|
||||
}
|
||||
Opcode::Return => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue