pipeline_script/core/
builtin.rs1use std::ffi::{c_char, CStr};
2use std::process::{Command, Stdio};
3use std::sync::Mutex;
4use std::thread::{self, JoinHandle};
5use std::time::{Duration, SystemTime, UNIX_EPOCH};
6
7use lazy_static::lazy_static;
8
9#[repr(C)]
10pub struct Array {
11 len: i64,
12 ptr: *mut Any,
13}
14#[repr(C)]
15pub struct Any {
16 id: i32,
17 ptr: *mut i8,
18}
19#[allow(unused)]
20pub extern "C" fn len(target: Array) -> i64 {
21 target.len
22}
23pub extern "C" fn println(obj: Any) {
24 unsafe {
25 match obj.id {
26 0 => {
27 print!("Unit")
28 }
29 1 => {
30 let b = obj.ptr as *mut bool;
31 print!("{}", *b);
32 }
33 3 => {
34 let value = obj.ptr as i8;
35 print!("{}", value);
36 }
37 5 => {
38 let value = obj.ptr as i16;
39 print!("{}", value);
40 }
41 7 => {
42 let v = obj.ptr as i32;
43 print!("{}", v);
44 }
45 9 => {
46 let v = obj.ptr as i64;
47 print!("{}", v);
48 }
49 11 => {
50 let v = obj.ptr as *mut f32;
51 print!("{}", *v);
52 }
53 13 => {
54 let v = obj.ptr as *mut f64;
55 print!("{}", *v);
56 }
57 15 => {
58 let s = CStr::from_ptr(obj.ptr as *const c_char);
59 print!("{}", s.to_str().unwrap());
60 }
61
62 t => todo!("{t}"),
63 }
64 }
65 println!()
67}
68#[allow(unused)]
69pub extern "C" fn print(obj: Array) {
70 for i in 0..obj.len {
71 let obj = unsafe { (obj.ptr).offset(i as isize) };
72 unsafe {
73 match (*obj).id {
74 0 => {
75 print!("Unit")
76 }
77 3 => {
78 let value = (*obj).ptr as i32;
79 print!("{}", value);
80 }
81 4 => {
82 let v = (*obj).ptr as i64;
83 print!("{}", v);
84 }
85 7 => {
86 let s = CStr::from_ptr((*obj).ptr as *const c_char);
87 print!("{}", s.to_str().unwrap());
88 }
89 t => todo!("{t}"),
90 }
91 }
92 }
93}
94pub extern "C" fn append(obj: Array) -> *mut c_char {
95 let mut s = String::new();
96 for i in 0..obj.len {
97 let obj = unsafe { (obj.ptr).offset(i as isize) };
98 unsafe {
99 match (*obj).id {
100 0 => {
101 s.push_str("Unit");
102 }
103 3 => {
104 let value = (*obj).ptr as i32;
105 s.push_str(&format!("{}", value));
106 }
107 4 => {
108 let v = (*obj).ptr as i64;
109 s.push_str(&format!("{}", v));
110 }
111 7 => {
112 let s0 = CStr::from_ptr((*obj).ptr as *const c_char);
113 s.push_str(s0.to_str().unwrap());
114 }
115 t => todo!("{t}"),
116 }
117 }
118 }
119 s.push('\0');
120 let s = s.leak();
121 s.as_ptr() as *mut c_char
122}
123lazy_static! {
124 static ref WORKSPACE: Mutex<String> = Mutex::new("./".to_string());
127
128 static ref THREAD_HANDLES: Mutex<Vec<JoinHandle<()>>> = Mutex::new(Vec::new());
131}
132pub extern "C" fn cmd(command: *mut c_char) {
141 let cmd = unsafe { CStr::from_ptr(command).to_str().unwrap() };
142 let workspace = WORKSPACE.lock().unwrap();
143 Command::new("powershell")
144 .current_dir(workspace.as_str())
145 .arg("/C")
146 .arg(cmd)
147 .stdout(Stdio::inherit())
148 .stderr(Stdio::inherit())
149 .output()
150 .expect("Failed to execute command");
151}
152pub extern "C" fn workspace(dir: *mut c_char) {
161 let dir_str = unsafe { CStr::from_ptr(dir).to_str().unwrap() };
162
163 if !std::path::Path::new(dir_str).exists() {
165 panic!("Directory does not exist: {}", dir_str);
166 }
167
168 let mut workspace = WORKSPACE.lock().unwrap();
170 *workspace = dir_str.to_string();
171}
172#[allow(unused)]
173pub extern "C" fn exit() {
174 std::process::exit(0);
175}
176#[allow(unused)]
177pub extern "C" fn get_env(key: *mut c_char) -> *mut c_char {
178 let key = unsafe { CStr::from_ptr(key).to_str().unwrap() };
179 let mut value = std::env::var(key).unwrap();
180 value.push('\0');
181 let value = value.leak();
182 value.as_ptr() as *mut c_char
183}
184#[allow(unused)]
185pub extern "C" fn set_env(key: *mut c_char, value: *mut c_char) {
186 let key = unsafe { CStr::from_ptr(key).to_str().unwrap() };
187 let value = unsafe { CStr::from_ptr(value).to_str().unwrap() };
188 std::env::set_var(key, value);
189}
190
191#[allow(unused)]
192pub extern "C" fn panic(ptr: *mut c_char) {
193 let s = unsafe { CStr::from_ptr(ptr).to_str().unwrap() };
194 eprintln!("\x1b[31mpanic: {}\x1b[0m", s);
195 std::process::exit(1);
196}
197
198#[no_mangle]
199pub extern "C" fn now() -> u64 {
200 SystemTime::now()
201 .duration_since(UNIX_EPOCH)
202 .unwrap_or_default() .as_millis() as u64 }
205
206pub type ExternFn = extern "C" fn();
208
209pub extern "C" fn spawn(func: ExternFn) {
218 let handle = thread::spawn(move || {
220 func();
221 });
222
223 let mut handles = THREAD_HANDLES.lock().unwrap();
225 handles.push(handle);
226}
227
228pub extern "C" fn wait() {
234 let mut handles = THREAD_HANDLES.lock().unwrap();
235
236 while let Some(handle) = handles.pop() {
238 if let Err(e) = handle.join() {
239 eprintln!("线程执行失败: {:?}", e);
240 }
241 }
242}
243
244pub extern "C" fn sleep(ms: u64) {
245 thread::sleep(Duration::from_millis(ms));
246}