use crate::compiler::value::parameters::Variable;
use crate::compiler::value::values::{FunctionDefinitionObject, TypeDefinition, Value};
use std::collections::HashMap;
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub struct Bytecode {
pub bytes: Vec<u8>,
pub lines: Vec<usize>,
pub(crate) labels: HashMap<String, usize>,
}
impl Bytecode {
pub fn new() -> Self {
Bytecode::default()
}
pub fn new_from_bytes(bytes: Vec<u8>) -> Self {
Bytecode {
bytes,
lines: vec![],
labels: HashMap::new(),
}
}
pub fn len(&self) -> usize {
self.bytes.len()
}
pub fn is_empty(&self) -> bool {
self.bytes.is_empty()
}
pub fn get(&self, index: usize) -> u8 {
*self.bytes.get(index).unwrap()
}
pub fn bytes(&mut self, mut bytes: Vec<u8>) -> usize {
self.bytes.append(&mut bytes);
self.bytes.len().saturating_sub(1)
}
pub fn byte(&mut self, byte: u8) -> usize {
let last_used_line = match self.lines.last() {
None => 0,
Some(line) => *line,
};
self.byte_and_line(byte, last_used_line)
}
pub fn byte_and_line(&mut self, byte: u8, line: usize) -> usize {
self.lines.push(line);
self.bytes.push(byte);
self.bytes.len().saturating_sub(1)
}
pub fn clear(&mut self) {
self.bytes.clear();
self.lines.clear();
self.labels.clear();
}
}
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub struct Executable {
pub script_bytecode: Bytecode,
pub script_constants: Vec<Value>,
pub script_variables: Vec<Variable>,
pub function_definitions: HashMap<String, Vec<FunctionDefinitionObject>>,
pub type_definitions: Vec<TypeDefinition>,
}
impl Executable {
pub fn as_fdo(&self) -> FunctionDefinitionObject {
FunctionDefinitionObject {
variables: self.script_variables.clone(),
constants: self.script_constants.clone(),
formal_arguments: vec![], bytecode: self.script_bytecode.clone(),
name: "top level script".to_string(),
}
}
}