Skip to main content

assembler/
utils.rs

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}