1use std::collections::BTreeMap;
2
3use crate::inst::*;
4use anyhow::Result;
5use rfvp::script::{opcode::Opcode, parser::Nls};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Serialize, Deserialize)]
9pub struct Function {
10 address: u32,
11 args_count: u8,
12 locals_count: u8,
13 insts: Vec<Inst2>,
14}
15
16impl Function {
17 pub fn address(&self) -> u32 {
18 self.address
19 }
20
21 pub fn get_insts(&self) -> &Vec<Inst2> {
22 &self.insts
23 }
24}
25
26#[derive(Debug, Serialize, Deserialize)]
27pub struct Inst2 {
28 address: u32,
29 mnemonic: String,
30 operands: Vec<String>,
31}
32
33impl Inst2 {
34 pub fn get_address(&self) -> u32 {
35 self.address
36 }
37
38 pub fn mnemonic(&self) -> &str {
39 &self.mnemonic
40 }
41
42 pub fn operands(&self) -> &[String] {
43 &self.operands
44 }
45
46 pub fn get_opcode(&self) -> Result<Opcode> {
47 match Opcode::try_from(self.mnemonic.as_str()) {
48 Ok(opcode) => Ok(opcode),
49 Err(_) => Err(anyhow::anyhow!("invalid opcode")),
50 }
51 }
52}
53
54pub fn to_nop(_inst: &Inst2) -> Result<NopInst> {
55 Ok(NopInst::new())
56}
57
58pub fn to_init_stack(inst: &Inst2) -> Result<InitStackInst> {
59 Ok(InitStackInst::new(
60 inst.operands.first()
61 .ok_or(anyhow::anyhow!("missing operand"))?
62 .parse()?,
63 inst.operands
64 .get(1)
65 .ok_or(anyhow::anyhow!("missing operand"))?
66 .parse()?,
67 ))
68}
69
70pub fn to_call(inst: &Inst2) -> Result<CallInst> {
71 Ok(CallInst::new(
72 inst.operands.first()
73 .ok_or(anyhow::anyhow!("missing operand"))?
74 .parse()?,
75 ))
76}
77
78pub fn to_syscall(inst: &Inst2, syscalls: &BTreeMap<String, u32>) -> Result<SyscallInst> {
79 let syscall_name = inst
80 .operands.first()
81 .ok_or(anyhow::anyhow!("missing operand"))?;
82 let id = syscalls
83 .get(syscall_name)
84 .ok_or(anyhow::anyhow!("invalid syscall"))?
85 .to_owned();
86 Ok(SyscallInst::new(id as u16))
87}
88
89pub fn to_ret(_inst: &Inst2) -> Result<RetInst> {
90 Ok(RetInst::new())
91}
92
93pub fn to_ret_v(_inst: &Inst2) -> Result<RetVInst> {
94 Ok(RetVInst::new())
95}
96
97pub fn to_jmp(inst: &Inst2) -> Result<JmpInst> {
98 Ok(JmpInst::new(
99 inst.operands.first()
100 .ok_or(anyhow::anyhow!("missing operand"))?
101 .parse()?,
102 ))
103}
104
105pub fn to_jz(inst: &Inst2) -> Result<JzInst> {
106 Ok(JzInst::new(
107 inst.operands.first()
108 .ok_or(anyhow::anyhow!("missing operand"))?
109 .parse()?,
110 ))
111}
112
113pub fn to_push_nil(_inst: &Inst2) -> Result<PushNilInst> {
114 Ok(PushNilInst::new())
115}
116
117pub fn to_push_true(_inst: &Inst2) -> Result<PushTrueInst> {
118 Ok(PushTrueInst::new())
119}
120
121pub fn to_push_i32(inst: &Inst2) -> Result<PushI32Inst> {
122 Ok(PushI32Inst::new(
123 inst.operands.first()
124 .ok_or(anyhow::anyhow!("missing operand"))?
125 .parse()?,
126 ))
127}
128
129pub fn to_push_i16(inst: &Inst2) -> Result<PushI16Inst> {
130 Ok(PushI16Inst::new(
131 inst.operands.first()
132 .ok_or(anyhow::anyhow!("missing operand"))?
133 .parse()?,
134 ))
135}
136
137pub fn to_push_i8(inst: &Inst2) -> Result<PushI8Inst> {
138 Ok(PushI8Inst::new(
139 inst.operands.first()
140 .ok_or(anyhow::anyhow!("missing operand"))?
141 .parse()?,
142 ))
143}
144
145pub fn to_push_f32(inst: &Inst2) -> Result<PushF32Inst> {
146 Ok(PushF32Inst::new(
147 inst.operands.first()
148 .ok_or(anyhow::anyhow!("missing operand"))?
149 .parse()?,
150 ))
151}
152
153pub fn to_push_string(inst: &Inst2, nls: Nls) -> Result<PushStringInst> {
154 Ok(PushStringInst::new(
155 inst.operands.first()
156 .ok_or(anyhow::anyhow!("missing operand"))?
157 .to_owned(),
158 nls,
159 ))
160}
161
162pub fn to_push_global(inst: &Inst2) -> Result<PushGlobalInst> {
163 Ok(PushGlobalInst::new(
164 inst.operands.first()
165 .ok_or(anyhow::anyhow!("missing operand"))?
166 .parse()?,
167 ))
168}
169
170pub fn to_push_stack(inst: &Inst2) -> Result<PushStackInst> {
171 Ok(PushStackInst::new(
172 inst.operands.first()
173 .ok_or(anyhow::anyhow!("missing operand"))?
174 .parse()?,
175 ))
176}
177
178pub fn to_push_global_table(inst: &Inst2) -> Result<PushGlobalTableInst> {
179 Ok(PushGlobalTableInst::new(
180 inst.operands.first()
181 .ok_or(anyhow::anyhow!("missing operand"))?
182 .parse()?,
183 ))
184}
185
186pub fn to_push_local_table(inst: &Inst2) -> Result<PushLocalTableInst> {
187 Ok(PushLocalTableInst::new(
188 inst.operands.first()
189 .ok_or(anyhow::anyhow!("missing operand"))?
190 .parse()?,
191 ))
192}
193
194pub fn to_push_top(_inst: &Inst2) -> Result<PushTopInst> {
195 Ok(PushTopInst::new())
196}
197
198pub fn to_push_return(_inst: &Inst2) -> Result<PushReturnInst> {
199 Ok(PushReturnInst::new())
200}
201
202pub fn to_pop_global(inst: &Inst2) -> Result<PopGlobalInst> {
203 Ok(PopGlobalInst::new(
204 inst.operands.first()
205 .ok_or(anyhow::anyhow!("missing operand"))?
206 .parse()?,
207 ))
208}
209
210pub fn to_pop_stack(inst: &Inst2) -> Result<PopStackInst> {
211 Ok(PopStackInst::new(
212 inst.operands.first()
213 .ok_or(anyhow::anyhow!("missing operand"))?
214 .parse()?,
215 ))
216}
217
218pub fn to_pop_global_table(inst: &Inst2) -> Result<PopGlobalTableInst> {
219 Ok(PopGlobalTableInst::new(
220 inst.operands.first()
221 .ok_or(anyhow::anyhow!("missing operand"))?
222 .parse()?,
223 ))
224}
225
226pub fn to_pop_local_table(inst: &Inst2) -> Result<PopLocalTableInst> {
227 Ok(PopLocalTableInst::new(
228 inst.operands.first()
229 .ok_or(anyhow::anyhow!("missing operand"))?
230 .parse()?,
231 ))
232}
233
234pub fn to_neg(_inst: &Inst2) -> Result<NegInst> {
235 Ok(NegInst::new())
236}
237
238pub fn to_add(_inst: &Inst2) -> Result<AddInst> {
239 Ok(AddInst::new())
240}
241
242pub fn to_sub(_inst: &Inst2) -> Result<SubInst> {
243 Ok(SubInst::new())
244}
245
246pub fn to_mul(_inst: &Inst2) -> Result<MulInst> {
247 Ok(MulInst::new())
248}
249
250pub fn to_div(_inst: &Inst2) -> Result<DivInst> {
251 Ok(DivInst::new())
252}
253
254pub fn to_mod(_inst: &Inst2) -> Result<ModInst> {
255 Ok(ModInst::new())
256}
257
258pub fn to_bit_test(_inst: &Inst2) -> Result<BitTestInst> {
259 Ok(BitTestInst::new())
260}
261
262pub fn to_and(_inst: &Inst2) -> Result<AndInst> {
263 Ok(AndInst::new())
264}
265
266pub fn to_or(_inst: &Inst2) -> Result<OrInst> {
267 Ok(OrInst::new())
268}
269
270pub fn to_set_e(_inst: &Inst2) -> Result<SetEInst> {
271 Ok(SetEInst::new())
272}
273
274pub fn to_set_ne(_inst: &Inst2) -> Result<SetNEInst> {
275 Ok(SetNEInst::new())
276}
277
278pub fn to_set_g(_inst: &Inst2) -> Result<SetGInst> {
279 Ok(SetGInst::new())
280}
281
282pub fn to_set_le(_inst: &Inst2) -> Result<SetLEInst> {
283 Ok(SetLEInst::new())
284}
285
286pub fn to_set_l(_inst: &Inst2) -> Result<SetLInst> {
287 Ok(SetLInst::new())
288}
289
290pub fn to_set_ge(_inst: &Inst2) -> Result<SetGEInst> {
291 Ok(SetGEInst::new())
292}
293