python_assembler/builder/
mod.rs1#![doc = include_str!("readme.md")]
2
3use crate::{
4 instructions::PythonInstruction,
5 program::{PycHeader, PythonCodeObject, PythonObject, PythonProgram},
6};
7
8#[derive(Debug)]
10pub struct PythonBuilder {
11 _instructions: Vec<PythonInstruction>,
12 constants: Vec<PythonObject>,
13 names: Vec<String>,
14}
15
16impl PythonBuilder {
17 pub fn new() -> Self {
19 Self { _instructions: vec![PythonInstruction::RESUME], constants: vec![PythonObject::None], names: Vec::new() }
20 }
21
22 pub fn print_str(mut self, s: &str) -> Self {
24 let const_value = PythonObject::Str(s.to_string());
25 let const_index = self.constants.len() as u32;
26 self.constants.push(const_value);
27
28 let print_name = "print".to_string();
29 let name_index = if let Some(idx) = self.names.iter().position(|n| n == &print_name) {
30 idx as u32
31 }
32 else {
33 self.names.push(print_name);
34 (self.names.len() - 1) as u32
35 };
36
37 self._instructions.push(PythonInstruction::PUSH_NULL);
39 self._instructions.push(PythonInstruction::LOAD_GLOBAL(name_index << 1)); self._instructions.push(PythonInstruction::LOAD_CONST(const_index));
41 self._instructions.push(PythonInstruction::CALL(1));
42 self._instructions.push(PythonInstruction::POP_TOP);
43 self
44 }
45
46 pub fn build(mut self, header: PycHeader) -> PythonProgram {
48 use crate::program::PythonVersion;
49
50 self._instructions.push(PythonInstruction::RETURN_CONST(0)); let version = PythonVersion::from_magic(header.magic);
54 PythonProgram {
55 header,
56 code_object: PythonCodeObject {
57 name: "<module>".to_string(),
58 qualname: "<module>".to_string(),
59 source_name: "<string>".to_string(),
60 first_line: 1,
61 last_line: 1,
62 co_argcount: 0,
63 co_posonlyargcount: 0,
64 co_kwonlyargcount: 0,
65 co_nlocals: 0,
66 co_stacksize: 10,
67 co_flags: 0x40, co_code: self._instructions,
69 co_consts: self.constants,
70 co_names: self.names,
71 co_localsplusnames: vec![],
72 co_localspluskinds: vec![],
73 co_linetable: vec![0, 1], co_exceptiontable: vec![],
75 },
76 version,
77 }
78 }
79}