1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
use std::fmt::{Debug, Display};
use crate::prelude::*;
#[derive(Clone, Default)]
pub struct Chunk {
pub constants: Vec<Value>,
pub code: Vec<Instruction>,
pub pos: Vec<Position>,
}
impl Chunk {
pub fn new() -> Self {
Self {
constants: Vec::new(),
code: Vec::new(),
pos: Vec::new(),
}
}
}
#[derive(Clone, Debug)]
#[repr(align(4))]
pub enum Instruction {
NoOp,
CreateLocal,
LoadLocal(u16),
StoreLocal(u16),
DiscardLocals(u16),
LoadGlobal(u16),
StoreGlobal(u16),
Const(u16),
Int(i16),
True,
False,
Nil,
Dup, Discard(u16),
UnaryOp(UnaryOp),
BinaryOp(BinaryOp),
NewList(u16),
NewTable(u16),
NewMatrix(u16, u8),
Field(u16),
StoreField(u16),
Index(u8),
StoreIndex(u8),
Jump(u16),
JumpTrue(u16),
JumpFalse(u16),
JumpNil(u16),
IterCreate,
IterNext,
Try(u16),
TryEnd,
Call(u8),
Return,
}
impl Debug for Chunk {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[Chunk {}]", self.code.len())
}
}
impl Display for Chunk {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "constants: ")?;
for (i, c) in self.constants.iter().enumerate() {
writeln!(f, " {i:04}: {c}")?;
}
writeln!(f, "code:")?;
for (i, ins) in self.code.iter().enumerate() {
writeln!(f, " {i:04}: {ins}")?;
}
Ok(())
}
}
impl Display for Instruction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use Instruction::*;
match self {
NoOp => write!(f, "noop"),
CreateLocal => write!(f, "create local"),
LoadLocal(idx) => write!(f, "load local \x1b[33m{idx}\x1b[0m"),
StoreLocal(idx) => write!(f, "store local \x1b[33m{idx}\x1b[0m"),
DiscardLocals(count) => write!(f, "discard locals \x1b[35m{count}\x1b[0m"),
LoadGlobal(name) => write!(f, "load global \x1b[36m{name}\x1b[0m"),
StoreGlobal(name) => write!(f, "store global \x1b[36m{name}\x1b[0m"),
Const(idx) => write!(f, "const \x1b[33m{idx}\x1b[0m"),
Int(idx) => write!(f, "push \x1b[34m{idx}\x1b[0m"),
True => write!(f, "push \x1b[34mtrue\x1b[0m"),
False => write!(f, "push \x1b[34mfalse\x1b[0m"),
Nil => write!(f, "push \x1b[34mnil\x1b[0m"),
Dup => write!(f, "duplicate"),
Discard(count) => write!(f, "discard \x1b[35m{count}\x1b[0m"),
UnaryOp(op) => write!(f, "unary \x1b[32m{op:?}\x1b[0m"),
BinaryOp(op) => write!(f, "binary \x1b[32m{op:?}\x1b[0m"),
NewList(len) => write!(f, "list \x1b[35m{len}\x1b[0m"),
NewTable(len) => write!(f, "table \x1b[35m{len}\x1b[0m"),
NewMatrix(len, codomain) => write!(f, "matrix \x1b[35m{}\x1b[0mx\x1b[35m{}\x1b[0m", *len / (*codomain as u16), codomain),
Index(idx) => write!(f, "index \x1b[33m{idx}\x1b[0m"),
StoreIndex(idx) => write!(f, "store_index \x1b[33m{idx}\x1b[0m"),
Jump(idx) => write!(f, "jump \x1b[33m{idx}\x1b[0m"),
JumpTrue(idx) => write!(f, "jumpt \x1b[33m{idx}\x1b[0m"),
JumpFalse(idx) => write!(f, "jumpf \x1b[33m{idx}\x1b[0m"),
JumpNil(idx) => write!(f, "jumpn \x1b[33m{idx}\x1b[0m"),
Call(arity) => write!(f, "call \x1b[35m{arity}\x1b[0m"),
Return => write!(f, "return"),
IterCreate => write!(f, "iter create"),
IterNext => write!(f, "iter next"),
Field(name_idx) => write!(f, "field \x1b[33m{name_idx}\x1b[0m"),
StoreField(name_idx) => write!(f, "store field \x1b[33m{name_idx}\x1b[0m"),
Try(idx) => write!(f, "try \x1b[33m{idx}\x1b[0m"),
TryEnd => write!(f, "try end"),
}
}
}
|