Skip to main content

ling_codegen/
bytecode.rs

1//! Ling bytecode emitter — compact stack-VM instruction stream.
2
3use crate::{CodegenBackend, MirProgram};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6#[repr(u8)]
7pub enum Op {
8    Nop  = 0,
9    Push = 1,
10    Pop  = 2,
11    Add  = 3, Sub  = 4, Mul  = 5, Div  = 6, Rem = 7,
12    Eq   = 8, Ne   = 9, Lt   = 10, Le   = 11, Gt = 12, Ge = 13,
13    And  = 14, Or  = 15, Not = 16,
14    Load = 17, Store = 18,
15    Call = 19, Ret  = 20,
16    Jump = 21, JumpIf = 22,
17    Halt = 0xFF,
18}
19
20#[derive(Debug, Default)]
21pub struct Chunk {
22    pub code:      Vec<u8>,
23    pub constants: Vec<f64>,
24}
25
26impl Chunk {
27    pub fn emit(&mut self, op: Op) { self.code.push(op as u8); }
28    pub fn emit_u16(&mut self, v: u16) { self.code.extend_from_slice(&v.to_le_bytes()); }
29    pub fn push_const(&mut self, v: f64) -> u16 {
30        let idx = self.constants.len() as u16;
31        self.constants.push(v);
32        idx
33    }
34}
35
36pub struct BytecodeBackend;
37
38impl CodegenBackend for BytecodeBackend {
39    fn emit(&mut self, mir: &MirProgram, out: &std::path::Path) -> anyhow::Result<()> {
40        let chunk = Chunk::default();
41        let bytes = chunk.code;
42        std::fs::write(out.with_extension("lingbc"), bytes)?;
43        Ok(())
44    }
45}