luna_lib/lang/
code.rs

1use super::{
2    ast::{BinaryOperator, UnaryOperator},
3    value::Value,
4};
5use crate::luna_impl::position::Located;
6use std::{cell::RefCell, fmt::Display, rc::Rc};
7
8pub type Register = u16;
9pub type Address = u32;
10pub type VectorSize = u16;
11pub type ObjectSize = u16;
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
13pub enum ByteCode {
14    #[default]
15    None, // 0
16
17    Jump {
18        // 1
19        addr: Address,
20    },
21    JumpIf {
22        // 2 - 15 : u32 u32
23        negative: bool,
24        cond: Source,
25        addr: Address,
26    },
27    JumpNull {
28        // 16 - 22 : u32 u32
29        negative: bool,
30        cond: Source,
31        addr: Address,
32    },
33
34    CallZero {
35        // 44 - 71 : u32 u32 u32 u32
36        dst: Option<Location>,
37        func: Source,
38    },
39    CallSingle {
40        // 44 - 71 : u32 u32 u32 u32
41        dst: Option<Location>,
42        func: Source,
43        arg: Source,
44    },
45    Call {
46        // 44 - 71 : u32 u32 u32 u32
47        dst: Option<Location>,
48        func: Source,
49        offset: Register,
50        amount: u8,
51    },
52    Return {
53        // 72 - 79 : u32
54        src: Option<Source>,
55    },
56
57    Move {
58        // 80 - 100 : u32 u32
59        dst: Location,
60        src: Source,
61    },
62    Field {
63        // 101 - 247 : u32 u32 u32
64        dst: Location,
65        head: Source,
66        field: Source,
67    },
68    SetField {
69        // 248 - 590 : u32 u32 u32
70        head: Source,
71        field: Source,
72        src: Source,
73    },
74
75    Vector {
76        // 591 - 593 : u32 u32 u32
77        dst: Location,
78        start: Register,
79        amount: VectorSize,
80    },
81    Object {
82        // 594 - 596 : u32 u32 u32
83        dst: Location,
84        start: Register,
85        amount: ObjectSize,
86    },
87    Function {
88        // 597 - 599 : u32 u32
89        dst: Location,
90        addr: Address,
91    },
92
93    Binary {
94        // 600 - 746 : u8 u32 u32 u32
95        op: BinaryOperation,
96        dst: Location,
97        left: Source,
98        right: Source,
99    },
100    Unary {
101        // 747 - 767 : u8 u32 u32
102        op: UnaryOperation,
103        dst: Location,
104        src: Source,
105    },
106}
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
108pub enum Source {
109    Register(Register),
110    Upvalue(Address),
111    Global(Address),
112    Constant(Address),
113    #[default]
114    Null,
115    Bool(bool),
116    Char(char),
117}
118#[derive(Debug, Clone, Copy, PartialEq, Eq)]
119pub enum Location {
120    Register(Register),
121    Upvalue(Address),
122    Global(Address),
123}
124#[derive(Debug, Clone, Copy, PartialEq, Eq)]
125pub enum BinaryOperation {
126    Add,
127    Sub,
128    Mul,
129    Div,
130    Pow,
131    Mod,
132    EQ,
133    NE,
134    LT,
135    GT,
136    LE,
137    GE,
138    And,
139    Or,
140}
141#[derive(Debug, Clone, Copy, PartialEq, Eq)]
142pub enum UnaryOperation {
143    Neg,
144    Not,
145}
146
147#[derive(Debug, Clone, Default)]
148pub struct Closure {
149    pub code: Vec<Located<ByteCode>>,
150    pub registers: Register,
151    pub closures: Vec<Rc<RefCell<Self>>>,
152    pub upvalues: Vec<Upvalue>,
153    pub consts: Vec<Value>,
154    pub path: Option<String>,
155}
156#[derive(Debug, Clone, PartialEq, Default)]
157pub struct Upvalue {
158    pub register: Register,
159    pub depth: u8,
160}
161
162impl Display for Source {
163    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164        match self {
165            Self::Register(reg) => write!(f, "@{reg}"),
166            Self::Upvalue(addr) => write!(f, "@u{addr}"),
167            Self::Global(addr) => write!(f, "@g{addr}"),
168            Self::Constant(addr) => write!(f, "#{addr}"),
169            Self::Null => write!(f, "null"),
170            Self::Bool(v) => write!(f, "{v:?}"),
171            Self::Char(v) => write!(f, "{v:?}"),
172        }
173    }
174}
175impl Display for Location {
176    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
177        match self {
178            Self::Register(reg) => write!(f, "!{reg}"),
179            Self::Upvalue(addr) => write!(f, "!u{addr}"),
180            Self::Global(addr) => write!(f, "!g{addr}"),
181        }
182    }
183}
184impl Display for ByteCode {
185    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
186        match self {
187            Self::None => write!(f, "none"),
188            Self::Jump { addr } => write!(f, "jump *{addr:?}"),
189            Self::JumpIf {
190                negative,
191                cond,
192                addr,
193            } => {
194                if *negative {
195                    write!(f, "jumpifnot {cond} *{addr:?}")
196                } else {
197                    write!(f, "jumpif {cond} *{addr:?}")
198                }
199            }
200            Self::JumpNull { negative, cond, addr } => {
201                if *negative {
202                    write!(f, "jumpnotnull {cond} *{addr:?}")
203                } else {
204                    write!(f, "jumpnull {cond} *{addr:?}")
205                }
206            }
207            Self::CallZero {
208                dst,
209                func,
210            } => {
211                if let Some(dst) = dst {
212                    write!(f, "call {func} -> {dst}")
213                } else {
214                    write!(f, "call {func}")
215                }
216            }
217            Self::CallSingle {
218                dst,
219                func,
220                arg,
221            } => {
222                if let Some(dst) = dst {
223                    write!(f, "call {func} {arg} -> {dst}")
224                } else {
225                    write!(f, "call {func} {arg}")
226                }
227            }
228            Self::Call {
229                dst,
230                func,
231                offset,
232                amount,
233            } => {
234                if let Some(dst) = dst {
235                    write!(f, "call {func} @{offset}..+{amount} -> {dst}")
236                } else {
237                    write!(f, "call {func} @{offset}..+{amount}")
238                }
239            }
240            Self::Return { src } => {
241                if let Some(src) = src {
242                    write!(f, "return {src}")
243                } else {
244                    write!(f, "return")
245                }
246            }
247            Self::Move { dst, src } => write!(f, "move {dst} = {src}"),
248            Self::Field { dst, head, field } => write!(f, "field {dst} = {head} . {field}"),
249            Self::SetField { head, field, src } => write!(f, "setfield {head} . {field} = {src}"),
250            Self::Vector { dst, start, amount } => write!(f, "vector {dst} = @{start}..+{amount}"),
251            Self::Object { dst, start, amount } => write!(f, "object {dst} = @{start}..+{amount}"),
252            Self::Function { dst, addr } => write!(f, "func {dst} = #f{addr:?}"),
253            Self::Binary {
254                op,
255                dst,
256                left,
257                right,
258            } => write!(
259                f,
260                "binary {dst} = {left} {} {right}",
261                format!("{op:?}").to_lowercase()
262            ),
263            Self::Unary { op, dst, src } => write!(
264                f,
265                "unary {dst} = {} {src}",
266                format!("{op:?}").to_lowercase()
267            ),
268        }
269    }
270}
271impl Display for Closure {
272    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
273        writeln!(f, "closure {:08x?}", self as *const Closure)?;
274        writeln!(f, "registers: {}", self.registers)?;
275        writeln!(f, "code, #{} instructions:", self.code.len())?;
276        for (addr, bytecode) in self.code.iter().enumerate() {
277            writeln!(f, "\t[{addr:04}] {bytecode}")?;
278        }
279        writeln!(f, "upvalues:")?;
280        for (addr, upvalue) in self.upvalues.iter().enumerate() {
281            writeln!(
282                f,
283                "\t[{addr}] register: {}, depth: {}",
284                upvalue.register, upvalue.depth
285            )?;
286        }
287        writeln!(f, "constants:")?;
288        for (addr, value) in self.consts.iter().enumerate() {
289            writeln!(f, "\t[{addr}] {}: {:?}", value.typ(), value)?;
290        }
291        writeln!(f, "closures:")?;
292        for (addr, closure) in self.closures.iter().enumerate() {
293            writeln!(f, "\t[{addr}] {:08x?}", closure.as_ptr())?;
294        }
295        writeln!(f)?;
296        for closure in self.closures.iter() {
297            write!(f, "{}", closure.borrow())?;
298        }
299        Ok(())
300    }
301}
302
303impl From<Location> for Source {
304    fn from(value: Location) -> Self {
305        match value {
306            Location::Register(register) => Self::Register(register),
307            Location::Upvalue(addr) => Self::Upvalue(addr),
308            Location::Global(addr) => Self::Global(addr),
309        }
310    }
311}
312
313impl From<BinaryOperator> for BinaryOperation {
314    fn from(value: BinaryOperator) -> Self {
315        match value {
316            BinaryOperator::Plus => Self::Add,
317            BinaryOperator::Minus => Self::Sub,
318            BinaryOperator::Star => Self::Mul,
319            BinaryOperator::Slash => Self::Div,
320            BinaryOperator::Exponent => Self::Pow,
321            BinaryOperator::Percent => Self::Mod,
322            BinaryOperator::EqualEqual => Self::EQ,
323            BinaryOperator::ExclamationEqual => Self::NE,
324            BinaryOperator::Less => Self::LT,
325            BinaryOperator::Greater => Self::GT,
326            BinaryOperator::LessEqual => Self::LE,
327            BinaryOperator::GreaterEqual => Self::GE,
328            BinaryOperator::Ampersand => Self::And,
329            BinaryOperator::Pipe => Self::Or,
330        }
331    }
332}
333impl From<UnaryOperator> for UnaryOperation {
334    fn from(value: UnaryOperator) -> Self {
335        match value {
336            UnaryOperator::Minus => Self::Neg,
337            UnaryOperator::Exclamation => Self::Not,
338        }
339    }
340}
341impl Display for BinaryOperation {
342    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
343        match self {
344            Self::Add => write!(f, "add"),
345            Self::Sub => write!(f, "sub"),
346            Self::Mul => write!(f, "mul"),
347            Self::Div => write!(f, "div"),
348            Self::Pow => write!(f, "pow"),
349            Self::Mod => write!(f, "mod"),
350            Self::EQ => write!(f, "eq"),
351            Self::NE => write!(f, "ne"),
352            Self::LT => write!(f, "lt"),
353            Self::GT => write!(f, "gt"),
354            Self::LE => write!(f, "le"),
355            Self::GE => write!(f, "ge"),
356            Self::And => write!(f, "and"),
357            Self::Or => write!(f, "or"),
358        }
359    }
360}
361impl Display for UnaryOperation {
362    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
363        match self {
364            UnaryOperation::Neg => write!(f, "neg"),
365            UnaryOperation::Not => write!(f, "not"),
366        }
367    }
368}