lua_assembler/builder/
mod.rs1use crate::{
2 instructions::LuacInstruction,
3 program::{LuaObject, LuaProgram, LuacCodeObject, LuacHeader},
4};
5
6#[derive(Debug)]
8pub struct LuacBuilder {
9 instructions: Vec<LuacInstruction>,
10 constants: Vec<LuaObject>,
11 names: Vec<String>,
12}
13
14impl LuacBuilder {
15 pub fn new() -> Self {
16 Self { instructions: Vec::new(), constants: Vec::new(), names: Vec::new() }
17 }
18
19 pub fn print_str(mut self, s: &str) -> Self {
21 let const_value = LuaObject::Str(s.to_string());
22 let const_index = self.constants.len() as u8;
23 self.constants.push(const_value);
24
25 let print_name = "print".to_string();
26 let print_index = if let Some(idx) = self.names.iter().position(|n| n == &print_name) {
27 idx as u8
28 }
29 else {
30 self.names.push(print_name);
31 (self.names.len() - 1) as u8
32 };
33
34 self.instructions.push(LuacInstruction::LoadName(print_index));
35 self.instructions.push(LuacInstruction::LoadConst(const_index));
36 self.instructions.push(LuacInstruction::CallFunction(1));
37 self.instructions.push(LuacInstruction::ReturnValue);
38 self
39 }
40
41 pub fn build(self, header: LuacHeader) -> LuaProgram {
42 let co_code_instructions: Vec<u32> = self.instructions.iter().flat_map(|instr| instr.to_bytecode()).collect();
43
44 LuaProgram {
45 header,
46 code_object: LuacCodeObject {
47 source_name: "<string>".to_string(),
48 first_line: 1,
49 last_line: 1,
50 num_params: 0,
51 is_vararg: 0,
52 max_stack_size: 0,
53 nested_functions: vec![],
54 upvalues: vec![],
55 local_vars: vec![],
56 line_info: vec![],
57 co_argcount: 0,
58 co_nlocal: 0,
59 co_stacks: 0,
60 num_upval: 0,
61 co_code: co_code_instructions,
62 co_consts: self.constants,
63 upvalue_n: 0,
64 },
65 }
66 }
67}