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, Jump {
18 addr: Address,
20 },
21 JumpIf {
22 negative: bool,
24 cond: Source,
25 addr: Address,
26 },
27 JumpNull {
28 negative: bool,
30 cond: Source,
31 addr: Address,
32 },
33
34 CallZero {
35 dst: Option<Location>,
37 func: Source,
38 },
39 CallSingle {
40 dst: Option<Location>,
42 func: Source,
43 arg: Source,
44 },
45 Call {
46 dst: Option<Location>,
48 func: Source,
49 offset: Register,
50 amount: u8,
51 },
52 Return {
53 src: Option<Source>,
55 },
56
57 Move {
58 dst: Location,
60 src: Source,
61 },
62 Field {
63 dst: Location,
65 head: Source,
66 field: Source,
67 },
68 SetField {
69 head: Source,
71 field: Source,
72 src: Source,
73 },
74
75 Vector {
76 dst: Location,
78 start: Register,
79 amount: VectorSize,
80 },
81 Object {
82 dst: Location,
84 start: Register,
85 amount: ObjectSize,
86 },
87 Function {
88 dst: Location,
90 addr: Address,
91 },
92
93 Binary {
94 op: BinaryOperation,
96 dst: Location,
97 left: Source,
98 right: Source,
99 },
100 Unary {
101 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}