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