tl_compiler/
jit_runtime.rs1use crate::value::VmValue;
6use std::sync::Arc;
7
8#[unsafe(no_mangle)]
10pub extern "C" fn tl_rt_add(a: *const VmValue, b: *const VmValue, out: *mut VmValue) {
11 let a = unsafe { &*a };
12 let b = unsafe { &*b };
13 let result = match (a, b) {
14 (VmValue::Int(x), VmValue::Int(y)) => VmValue::Int(x + y),
15 (VmValue::Float(x), VmValue::Float(y)) => VmValue::Float(x + y),
16 (VmValue::Int(x), VmValue::Float(y)) => VmValue::Float(*x as f64 + y),
17 (VmValue::Float(x), VmValue::Int(y)) => VmValue::Float(x + *y as f64),
18 (VmValue::String(x), VmValue::String(y)) => {
19 VmValue::String(Arc::from(format!("{x}{y}").as_str()))
20 }
21 _ => VmValue::None,
22 };
23 unsafe {
24 out.write(result);
25 }
26}
27
28#[unsafe(no_mangle)]
30pub extern "C" fn tl_rt_sub(a: *const VmValue, b: *const VmValue, out: *mut VmValue) {
31 let a = unsafe { &*a };
32 let b = unsafe { &*b };
33 let result = match (a, b) {
34 (VmValue::Int(x), VmValue::Int(y)) => VmValue::Int(x - y),
35 (VmValue::Float(x), VmValue::Float(y)) => VmValue::Float(x - y),
36 (VmValue::Int(x), VmValue::Float(y)) => VmValue::Float(*x as f64 - y),
37 (VmValue::Float(x), VmValue::Int(y)) => VmValue::Float(x - *y as f64),
38 _ => VmValue::None,
39 };
40 unsafe {
41 out.write(result);
42 }
43}
44
45#[unsafe(no_mangle)]
47pub extern "C" fn tl_rt_mul(a: *const VmValue, b: *const VmValue, out: *mut VmValue) {
48 let a = unsafe { &*a };
49 let b = unsafe { &*b };
50 let result = match (a, b) {
51 (VmValue::Int(x), VmValue::Int(y)) => VmValue::Int(x * y),
52 (VmValue::Float(x), VmValue::Float(y)) => VmValue::Float(x * y),
53 (VmValue::Int(x), VmValue::Float(y)) => VmValue::Float(*x as f64 * y),
54 (VmValue::Float(x), VmValue::Int(y)) => VmValue::Float(x * *y as f64),
55 _ => VmValue::None,
56 };
57 unsafe {
58 out.write(result);
59 }
60}
61
62#[unsafe(no_mangle)]
64pub extern "C" fn tl_rt_cmp(a: *const VmValue, b: *const VmValue) -> i64 {
65 let a = unsafe { &*a };
66 let b = unsafe { &*b };
67 match (a, b) {
68 (VmValue::Int(x), VmValue::Int(y)) => {
69 if x < y {
70 -1
71 } else if x > y {
72 1
73 } else {
74 0
75 }
76 }
77 (VmValue::Float(x), VmValue::Float(y)) => {
78 if x < y {
79 -1.0 as i64
80 } else if x > y {
81 1
82 } else {
83 0
84 }
85 }
86 _ => 0,
87 }
88}
89
90#[unsafe(no_mangle)]
92pub extern "C" fn tl_rt_is_truthy(val: *const VmValue) -> i64 {
93 let val = unsafe { &*val };
94 if val.is_truthy() { 1 } else { 0 }
95}