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
61 .first()
62 .ok_or(anyhow::anyhow!("missing operand"))?
63 .parse()?,
64 inst.operands
65 .get(1)
66 .ok_or(anyhow::anyhow!("missing operand"))?
67 .parse()?,
68 ))
69}
70
71pub fn to_call(inst: &Inst2) -> Result<CallInst> {
72 Ok(CallInst::new(
73 inst.operands
74 .first()
75 .ok_or(anyhow::anyhow!("missing operand"))?
76 .parse()?,
77 ))
78}
79
80pub fn to_syscall(inst: &Inst2, syscalls: &BTreeMap<String, u32>) -> Result<SyscallInst> {
81 let syscall_name = inst
82 .operands
83 .first()
84 .ok_or(anyhow::anyhow!("missing operand"))?;
85 let id = syscalls
86 .get(syscall_name)
87 .ok_or(anyhow::anyhow!("invalid syscall"))?
88 .to_owned();
89 Ok(SyscallInst::new(id as u16))
90}
91
92pub fn to_ret(_inst: &Inst2) -> Result<RetInst> {
93 Ok(RetInst::new())
94}
95
96pub fn to_ret_v(_inst: &Inst2) -> Result<RetVInst> {
97 Ok(RetVInst::new())
98}
99
100pub fn to_jmp(inst: &Inst2) -> Result<JmpInst> {
101 Ok(JmpInst::new(
102 inst.operands
103 .first()
104 .ok_or(anyhow::anyhow!("missing operand"))?
105 .parse()?,
106 ))
107}
108
109pub fn to_jz(inst: &Inst2) -> Result<JzInst> {
110 Ok(JzInst::new(
111 inst.operands
112 .first()
113 .ok_or(anyhow::anyhow!("missing operand"))?
114 .parse()?,
115 ))
116}
117
118pub fn to_push_nil(_inst: &Inst2) -> Result<PushNilInst> {
119 Ok(PushNilInst::new())
120}
121
122pub fn to_push_true(_inst: &Inst2) -> Result<PushTrueInst> {
123 Ok(PushTrueInst::new())
124}
125
126pub fn to_push_i32(inst: &Inst2) -> Result<PushI32Inst> {
127 Ok(PushI32Inst::new(
128 inst.operands
129 .first()
130 .ok_or(anyhow::anyhow!("missing operand"))?
131 .parse()?,
132 ))
133}
134
135pub fn to_push_i16(inst: &Inst2) -> Result<PushI16Inst> {
136 Ok(PushI16Inst::new(
137 inst.operands
138 .first()
139 .ok_or(anyhow::anyhow!("missing operand"))?
140 .parse()?,
141 ))
142}
143
144pub fn to_push_i8(inst: &Inst2) -> Result<PushI8Inst> {
145 Ok(PushI8Inst::new(
146 inst.operands
147 .first()
148 .ok_or(anyhow::anyhow!("missing operand"))?
149 .parse()?,
150 ))
151}
152
153pub fn to_push_f32(inst: &Inst2) -> Result<PushF32Inst> {
154 Ok(PushF32Inst::new(
155 inst.operands
156 .first()
157 .ok_or(anyhow::anyhow!("missing operand"))?
158 .parse()?,
159 ))
160}
161
162pub fn to_push_string(inst: &Inst2, nls: Nls) -> Result<PushStringInst> {
163 Ok(PushStringInst::new(
164 inst.operands
165 .first()
166 .ok_or(anyhow::anyhow!("missing operand"))?
167 .to_owned(),
168 nls,
169 ))
170}
171
172pub fn to_push_global(inst: &Inst2) -> Result<PushGlobalInst> {
173 Ok(PushGlobalInst::new(
174 inst.operands
175 .first()
176 .ok_or(anyhow::anyhow!("missing operand"))?
177 .parse()?,
178 ))
179}
180
181pub fn to_push_stack(inst: &Inst2) -> Result<PushStackInst> {
182 Ok(PushStackInst::new(
183 inst.operands
184 .first()
185 .ok_or(anyhow::anyhow!("missing operand"))?
186 .parse()?,
187 ))
188}
189
190pub fn to_push_global_table(inst: &Inst2) -> Result<PushGlobalTableInst> {
191 Ok(PushGlobalTableInst::new(
192 inst.operands
193 .first()
194 .ok_or(anyhow::anyhow!("missing operand"))?
195 .parse()?,
196 ))
197}
198
199pub fn to_push_local_table(inst: &Inst2) -> Result<PushLocalTableInst> {
200 Ok(PushLocalTableInst::new(
201 inst.operands
202 .first()
203 .ok_or(anyhow::anyhow!("missing operand"))?
204 .parse()?,
205 ))
206}
207
208pub fn to_push_top(_inst: &Inst2) -> Result<PushTopInst> {
209 Ok(PushTopInst::new())
210}
211
212pub fn to_push_return(_inst: &Inst2) -> Result<PushReturnInst> {
213 Ok(PushReturnInst::new())
214}
215
216pub fn to_pop_global(inst: &Inst2) -> Result<PopGlobalInst> {
217 Ok(PopGlobalInst::new(
218 inst.operands
219 .first()
220 .ok_or(anyhow::anyhow!("missing operand"))?
221 .parse()?,
222 ))
223}
224
225pub fn to_pop_stack(inst: &Inst2) -> Result<PopStackInst> {
226 Ok(PopStackInst::new(
227 inst.operands
228 .first()
229 .ok_or(anyhow::anyhow!("missing operand"))?
230 .parse()?,
231 ))
232}
233
234pub fn to_pop_global_table(inst: &Inst2) -> Result<PopGlobalTableInst> {
235 Ok(PopGlobalTableInst::new(
236 inst.operands
237 .first()
238 .ok_or(anyhow::anyhow!("missing operand"))?
239 .parse()?,
240 ))
241}
242
243pub fn to_pop_local_table(inst: &Inst2) -> Result<PopLocalTableInst> {
244 Ok(PopLocalTableInst::new(
245 inst.operands
246 .first()
247 .ok_or(anyhow::anyhow!("missing operand"))?
248 .parse()?,
249 ))
250}
251
252pub fn to_neg(_inst: &Inst2) -> Result<NegInst> {
253 Ok(NegInst::new())
254}
255
256pub fn to_add(_inst: &Inst2) -> Result<AddInst> {
257 Ok(AddInst::new())
258}
259
260pub fn to_sub(_inst: &Inst2) -> Result<SubInst> {
261 Ok(SubInst::new())
262}
263
264pub fn to_mul(_inst: &Inst2) -> Result<MulInst> {
265 Ok(MulInst::new())
266}
267
268pub fn to_div(_inst: &Inst2) -> Result<DivInst> {
269 Ok(DivInst::new())
270}
271
272pub fn to_mod(_inst: &Inst2) -> Result<ModInst> {
273 Ok(ModInst::new())
274}
275
276pub fn to_bit_test(_inst: &Inst2) -> Result<BitTestInst> {
277 Ok(BitTestInst::new())
278}
279
280pub fn to_and(_inst: &Inst2) -> Result<AndInst> {
281 Ok(AndInst::new())
282}
283
284pub fn to_or(_inst: &Inst2) -> Result<OrInst> {
285 Ok(OrInst::new())
286}
287
288pub fn to_set_e(_inst: &Inst2) -> Result<SetEInst> {
289 Ok(SetEInst::new())
290}
291
292pub fn to_set_ne(_inst: &Inst2) -> Result<SetNEInst> {
293 Ok(SetNEInst::new())
294}
295
296pub fn to_set_g(_inst: &Inst2) -> Result<SetGInst> {
297 Ok(SetGInst::new())
298}
299
300pub fn to_set_le(_inst: &Inst2) -> Result<SetLEInst> {
301 Ok(SetLEInst::new())
302}
303
304pub fn to_set_l(_inst: &Inst2) -> Result<SetLInst> {
305 Ok(SetLInst::new())
306}
307
308pub fn to_set_ge(_inst: &Inst2) -> Result<SetGEInst> {
309 Ok(SetGEInst::new())
310}