1use crate::enums::lua_type::lua_Type;
2use crate::functions::call_bin_tm::call_bin_tm;
3use crate::functions::lua_g_aritherror::luaG_aritherror;
4use crate::functions::lua_v_tonumber::lua_v_tonumber;
5use crate::functions::luai_numidiv::luai_numidiv;
6use crate::functions::luai_nummod::luai_nummod;
7use crate::macros::cast_to::cast_to;
8use crate::macros::luai_numadd::luai_numadd;
9use crate::macros::luai_numdiv::luai_numdiv;
10use crate::macros::luai_nummul::luai_nummul;
11use crate::macros::luai_numpow::luai_numpow;
12use crate::macros::luai_numsub::luai_numsub;
13use crate::macros::luai_numunm::luai_numunm;
14use crate::macros::nvalue::nvalue;
15use crate::macros::setnvalue::setnvalue;
16use crate::macros::setvvalue::setvvalue;
17use crate::macros::ttisnumber::ttisnumber;
18use crate::macros::ttisvector::ttisvector;
19use crate::macros::vvalue::vvalue;
20use crate::records::lua_state::lua_State;
21use crate::type_aliases::stk_id::StkId;
22use crate::type_aliases::t_value::TValue;
23use crate::type_aliases::tms::TMS;
24use luaur_common::macros::luau_assert::LUAU_ASSERT;
25
26#[allow(non_snake_case)]
27pub unsafe fn lua_v_doarithimpl(
28 L: *mut lua_State,
29 ra: StkId,
30 rb: *const TValue,
31 rc: *const TValue,
32 op: TMS,
33) {
34 let mut tempb = TValue::default();
35 let mut tempc = TValue::default();
36 let b: *const TValue;
37 let c: *const TValue;
38
39 let vb = if ttisvector!(rb) {
40 vvalue!(rb).as_ptr()
41 } else {
42 core::ptr::null()
43 };
44 let vc = if ttisvector!(rc) {
45 vvalue!(rc).as_ptr()
46 } else {
47 core::ptr::null()
48 };
49
50 if !vb.is_null() && !vc.is_null() {
51 match op {
52 TMS::TM_ADD => {
53 setvvalue!(
54 ra,
55 *vb.add(0) + *vc.add(0),
56 *vb.add(1) + *vc.add(1),
57 *vb.add(2) + *vc.add(2),
58 *vb.add(3) + *vc.add(3)
59 );
60 return;
61 }
62 TMS::TM_SUB => {
63 setvvalue!(
64 ra,
65 *vb.add(0) - *vc.add(0),
66 *vb.add(1) - *vc.add(1),
67 *vb.add(2) - *vc.add(2),
68 *vb.add(3) - *vc.add(3)
69 );
70 return;
71 }
72 TMS::TM_MUL => {
73 setvvalue!(
74 ra,
75 *vb.add(0) * *vc.add(0),
76 *vb.add(1) * *vc.add(1),
77 *vb.add(2) * *vc.add(2),
78 *vb.add(3) * *vc.add(3)
79 );
80 return;
81 }
82 TMS::TM_DIV => {
83 setvvalue!(
84 ra,
85 *vb.add(0) / *vc.add(0),
86 *vb.add(1) / *vc.add(1),
87 *vb.add(2) / *vc.add(2),
88 *vb.add(3) / *vc.add(3)
89 );
90 return;
91 }
92 TMS::TM_IDIV => {
93 setvvalue!(
94 ra,
95 luai_numidiv(*vb.add(0) as f64, *vc.add(0) as f64) as f32,
96 luai_numidiv(*vb.add(1) as f64, *vc.add(1) as f64) as f32,
97 luai_numidiv(*vb.add(2) as f64, *vc.add(2) as f64) as f32,
98 luai_numidiv(*vb.add(3) as f64, *vc.add(3) as f64) as f32
99 );
100 return;
101 }
102 TMS::TM_UNM => {
103 setvvalue!(ra, -*vb.add(0), -*vb.add(1), -*vb.add(2), -*vb.add(3));
104 return;
105 }
106 _ => {}
107 }
108 } else if !vb.is_null() {
109 let c_ptr = if ttisnumber!(rc) {
110 rc
111 } else {
112 lua_v_tonumber(rc, &mut tempc)
113 };
114 if !c_ptr.is_null() {
115 let nc = cast_to!(f32, nvalue!(c_ptr));
116 match op {
117 TMS::TM_MUL => {
118 setvvalue!(
119 ra,
120 *vb.add(0) * nc,
121 *vb.add(1) * nc,
122 *vb.add(2) * nc,
123 *vb.add(3) * nc
124 );
125 return;
126 }
127 TMS::TM_DIV => {
128 setvvalue!(
129 ra,
130 *vb.add(0) / nc,
131 *vb.add(1) / nc,
132 *vb.add(2) / nc,
133 *vb.add(3) / nc
134 );
135 return;
136 }
137 TMS::TM_IDIV => {
138 setvvalue!(
139 ra,
140 luai_numidiv(*vb.add(0) as f64, nc as f64) as f32,
141 luai_numidiv(*vb.add(1) as f64, nc as f64) as f32,
142 luai_numidiv(*vb.add(2) as f64, nc as f64) as f32,
143 luai_numidiv(*vb.add(3) as f64, nc as f64) as f32
144 );
145 return;
146 }
147 _ => {}
148 }
149 }
150 } else if !vc.is_null() {
151 let b_ptr = if ttisnumber!(rb) {
152 rb
153 } else {
154 lua_v_tonumber(rb, &mut tempb)
155 };
156 if !b_ptr.is_null() {
157 let nb = cast_to!(f32, nvalue!(b_ptr));
158 match op {
159 TMS::TM_MUL => {
160 setvvalue!(
161 ra,
162 nb * *vc.add(0),
163 nb * *vc.add(1),
164 nb * *vc.add(2),
165 nb * *vc.add(3)
166 );
167 return;
168 }
169 TMS::TM_DIV => {
170 setvvalue!(
171 ra,
172 nb / *vc.add(0),
173 nb / *vc.add(1),
174 nb / *vc.add(2),
175 nb / *vc.add(3)
176 );
177 return;
178 }
179 TMS::TM_IDIV => {
180 setvvalue!(
181 ra,
182 luai_numidiv(nb as f64, *vc.add(0) as f64) as f32,
183 luai_numidiv(nb as f64, *vc.add(1) as f64) as f32,
184 luai_numidiv(nb as f64, *vc.add(2) as f64) as f32,
185 luai_numidiv(nb as f64, *vc.add(3) as f64) as f32
186 );
187 return;
188 }
189 _ => {}
190 }
191 }
192 }
193
194 let b_res = lua_v_tonumber(rb, &mut tempb);
195 let c_res = lua_v_tonumber(rc, &mut tempc);
196 if !b_res.is_null() && !c_res.is_null() {
197 let nb = nvalue!(b_res);
198 let nc = nvalue!(c_res);
199 match op {
200 TMS::TM_ADD => setnvalue!(ra, luai_numadd(nb, nc)),
201 TMS::TM_SUB => setnvalue!(ra, luai_numsub(nb, nc)),
202 TMS::TM_MUL => setnvalue!(ra, luai_nummul(nb, nc)),
203 TMS::TM_DIV => setnvalue!(ra, luai_numdiv(nb, nc)),
204 TMS::TM_IDIV => setnvalue!(ra, luai_numidiv(nb, nc)),
205 TMS::TM_MOD => setnvalue!(ra, luai_nummod(nb, nc)),
206 TMS::TM_POW => setnvalue!(ra, luai_numpow(nb, nc)),
207 TMS::TM_UNM => setnvalue!(ra, luai_numunm(nb)),
208 _ => LUAU_ASSERT!(false),
209 }
210 } else if call_bin_tm(L, rb, rc, ra, op) == 0 {
211 luaG_aritherror(L, rb, rc, op);
212 }
213}
214
215#[export_name = "luaV_doarithimpl_TM_ADD"]
216pub unsafe extern "C" fn lua_v_doarithimpl_tm_add(
217 L: *mut lua_State,
218 ra: StkId,
219 rb: *const TValue,
220 rc: *const TValue,
221) {
222 lua_v_doarithimpl(L, ra, rb, rc, TMS::TM_ADD);
223}
224
225#[export_name = "luaV_doarithimpl_TM_SUB"]
226pub unsafe extern "C" fn lua_v_doarithimpl_tm_sub(
227 L: *mut lua_State,
228 ra: StkId,
229 rb: *const TValue,
230 rc: *const TValue,
231) {
232 lua_v_doarithimpl(L, ra, rb, rc, TMS::TM_SUB);
233}
234
235#[export_name = "luaV_doarithimpl_TM_MUL"]
236pub unsafe extern "C" fn lua_v_doarithimpl_tm_mul(
237 L: *mut lua_State,
238 ra: StkId,
239 rb: *const TValue,
240 rc: *const TValue,
241) {
242 lua_v_doarithimpl(L, ra, rb, rc, TMS::TM_MUL);
243}
244
245#[export_name = "luaV_doarithimpl_TM_DIV"]
246pub unsafe extern "C" fn lua_v_doarithimpl_tm_div(
247 L: *mut lua_State,
248 ra: StkId,
249 rb: *const TValue,
250 rc: *const TValue,
251) {
252 lua_v_doarithimpl(L, ra, rb, rc, TMS::TM_DIV);
253}
254
255#[export_name = "luaV_doarithimpl_TM_IDIV"]
256pub unsafe extern "C" fn lua_v_doarithimpl_tm_idiv(
257 L: *mut lua_State,
258 ra: StkId,
259 rb: *const TValue,
260 rc: *const TValue,
261) {
262 lua_v_doarithimpl(L, ra, rb, rc, TMS::TM_IDIV);
263}
264
265#[export_name = "luaV_doarithimpl_TM_MOD"]
266pub unsafe extern "C" fn lua_v_doarithimpl_tm_mod(
267 L: *mut lua_State,
268 ra: StkId,
269 rb: *const TValue,
270 rc: *const TValue,
271) {
272 lua_v_doarithimpl(L, ra, rb, rc, TMS::TM_MOD);
273}
274
275#[export_name = "luaV_doarithimpl_TM_POW"]
276pub unsafe extern "C" fn lua_v_doarithimpl_tm_pow(
277 L: *mut lua_State,
278 ra: StkId,
279 rb: *const TValue,
280 rc: *const TValue,
281) {
282 lua_v_doarithimpl(L, ra, rb, rc, TMS::TM_POW);
283}
284
285#[export_name = "luaV_doarithimpl_TM_UNM"]
286pub unsafe extern "C" fn lua_v_doarithimpl_tm_unm(
287 L: *mut lua_State,
288 ra: StkId,
289 rb: *const TValue,
290 rc: *const TValue,
291) {
292 lua_v_doarithimpl(L, ra, rb, rc, TMS::TM_UNM);
293}