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.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