nyar_assembler/program/
builder.rs1use gaia_types::{GaiaError, QualifiedName};
2use gaia_binary::{BinaryWriter, Leb128};
3use crate::program::{
4 entities::NyarProgram,
5 types::{NyarChunk, NyarConstant, NyarExportInfo, NyarImportInfo, NyarInstruction},
6};
7
8impl NyarProgram {
9 pub fn begin_chunk(&mut self) -> usize {
11 let idx = self.module.chunks.len();
12 self.module.chunks.push(NyarChunk::default());
13 idx
14 }
15}
16
17#[derive(Debug, Default)]
19pub struct NyarBuilder {
20 pub program: NyarProgram,
22 pub current_chunk: Option<usize>,
24}
25
26impl NyarBuilder {
27 pub fn new() -> Self {
29 Self::default()
30 }
31
32 pub fn set_name(&mut self, name: QualifiedName) {
34 self.program.set_name(name);
35 }
36
37 pub fn with_version(mut self, version: u16) -> Self {
39 self.program.module.version = version;
40 self
41 }
42
43 pub fn with_flags(mut self, flags: u32) -> Self {
45 self.program.module.flags = flags;
46 self
47 }
48
49 pub fn add_constant(&mut self, constant: NyarConstant) -> usize {
51 let pool = &mut self.program.module.constants;
52 if let Some(pos) = pool.iter().position(|c| c == &constant) {
53 pos
54 }
55 else {
56 pool.push(constant);
57 pool.len() - 1
58 }
59 }
60
61 pub fn begin_chunk(&mut self) {
63 let chunk = NyarChunk::default();
64 self.program.module.chunks.push(chunk);
65 self.current_chunk = Some(self.program.module.chunks.len() - 1);
66 }
67
68 pub fn emit(&mut self, inst: NyarInstruction) -> Result<(), GaiaError> {
70 if let Some(idx) = self.current_chunk {
71 use crate::program::instructions::NyarCodec;
72 let mut writer = BinaryWriter::<Vec<u8>, Leb128>::new(Vec::new());
73 inst.encode(&mut writer).map_err(|_| GaiaError::invalid_data("Io"))?;
74 let buf = writer.into_inner();
75 self.program.module.chunks[idx].code.extend_from_slice(&buf);
76 }
77 Ok(())
78 }
79
80 pub fn set_chunk_meta(&mut self, locals: u16, upvalues: u16, max_stack: u16) {
82 if let Some(idx) = self.current_chunk {
83 let chunk = &mut self.program.module.chunks[idx];
84 chunk.locals = locals;
85 chunk.upvalues = upvalues;
86 chunk.max_stack = max_stack;
87 }
88 }
89
90 pub fn add_import(&mut self, provider: String, symbol: QualifiedName) {
92 self.program.module.imports.push(NyarImportInfo { provider, symbol });
93 }
94
95 pub fn add_export(&mut self, symbol: QualifiedName, chunk_idx: u16) {
97 self.program.module.exports.push(NyarExportInfo { symbol, chunk_idx });
98 }
99
100 pub fn finish(self) -> NyarProgram {
102 self.program
103 }
104}