hornvale/scripting_language/chunk/
mod.rs

1use std::error::Error as StdError;
2use std::fmt::Write as FmtWrite;
3use std::io::Write as IoWrite;
4
5use crate::scripting_language::constants::Constants;
6use crate::scripting_language::garbage_collection::reference::Reference;
7use crate::scripting_language::instructions::Instructions;
8use crate::scripting_language::value::Value;
9
10/// A chunk or portion thereof consisting of bytecode.
11#[derive(Clone, Debug, Default, Display)]
12#[display(fmt = "instructions: {}, constants: {}", instructions, constants)]
13pub struct Chunk {
14  /// The serialized instructions comprising the chunk.
15  pub instructions: Instructions,
16  /// The constant pool.
17  pub constants: Constants,
18}
19
20impl Chunk {
21  /// Dump the disassembled chunk to a std::fmt::Write object.
22  #[named]
23  #[inline]
24  pub fn dump_fmt<W: FmtWrite>(&self, out: &mut W) -> Result<(), Box<dyn StdError>> {
25    trace_enter!();
26    self.instructions.dump(out)?;
27    trace_exit!();
28    Ok(())
29  }
30
31  /// Dump the disassembled chunk to a std::io::Write object.
32  #[named]
33  #[inline]
34  pub fn dump_io<W: IoWrite>(&self, out: &mut W) -> Result<(), Box<dyn StdError>> {
35    trace_enter!();
36    let mut string = String::new();
37    self.dump_fmt(&mut string)?;
38    write!(out, "{}", string)?;
39    trace_exit!();
40    Ok(())
41  }
42
43  /// Read a string.
44  #[named]
45  pub fn read_string(&self, index: u16) -> Reference<String> {
46    trace_enter!();
47    trace_var!(index);
48    let result = if let Value::String(string) = self.constants.constants[index as usize] {
49      string
50    } else {
51      panic!("Constant is not String!")
52    };
53    trace_var!(result);
54    trace_exit!();
55    result
56  }
57}
58
59#[cfg(test)]
60pub mod test {
61
62  use super::*;
63  use crate::scripting_language::instruction::Instruction;
64  use crate::scripting_language::value::Value;
65  use crate::test::*;
66
67  #[named]
68  #[test]
69  pub fn test() {
70    init();
71    trace_enter!();
72    let mut string = String::new();
73    let mut chunk = Chunk::default();
74    let const_inst = chunk.constants.push(Value::Number(1.2)).unwrap();
75    chunk.instructions.append(const_inst, 1);
76    chunk.instructions.append(Instruction::Return, 2);
77    let result = chunk.dump_fmt(&mut string).unwrap();
78    assert_eq!(result, ());
79    let lines: Vec<&str> = string.split("\n").collect();
80    assert_eq!(lines[0], "");
81    assert_eq!(lines[1], "Index   Offset    Line       Instruction  Args");
82    assert_eq!(lines[2], "----------------------------------------------");
83    assert_eq!(lines[3], "    0   0x0000       1       Constant(0)     1");
84    assert_eq!(lines[4], "    1   0x0002       2            Return     0");
85    trace_exit!();
86  }
87}