1use crate::{Dynamic, DynamicErr};
2use smol_str::SmolStr;
3
4use anyhow::{Result, anyhow};
5use std::rc::Rc;
6
7#[derive(Debug, Clone, Copy, Eq, PartialEq)]
8pub enum ConstIntOp {
9 Add,
10 Sub,
11 Mul,
12 Div,
13 Mod,
14}
15
16#[derive(Debug, Default, Clone, Eq)]
17pub enum Type {
18 #[default]
19 Any, Void, Bool,
22 U8,
23 I8,
24 U16,
25 I16,
26 U32,
27 I32,
28 U64,
29 I64,
30 F16,
31 F32,
32 F64,
33 Str,
34 Map,
35 List,
36 Iter,
37 Ident {
38 name: SmolStr,
39 params: Vec<Type>,
40 },
41 ConstInt(i64),
42 ConstBinary {
43 op: ConstIntOp,
44 left: Rc<Type>,
45 right: Rc<Type>,
46 },
47 Tuple(Vec<Type>),
48 Struct {
49 params: Vec<Type>,
50 fields: Vec<(SmolStr, Type)>,
51 },
52 Vec(Rc<Type>, u32), Array(Rc<Type>, u32), ArrayParam(Rc<Type>, Rc<Type>),
55 Fn {
56 tys: Vec<Type>,
57 ret: Rc<Type>,
58 }, Symbol {
60 id: u32,
61 params: Vec<Type>,
62 }, }
64
65unsafe impl Send for Type {}
66unsafe impl Sync for Type {}
67
68impl std::ops::Add for Type {
69 type Output = Self;
70 fn add(self, rhs: Self) -> Self::Output {
71 if self == rhs {
72 self
73 } else if self.is_str() || rhs.is_str() {
74 Type::Str
75 } else if self.is_any() || rhs.is_any() {
76 Type::Any
77 } else if self.is_float() || rhs.is_float() {
78 if self.is_f64() || rhs.is_f64() { Type::F64 } else { Type::F32 }
79 } else if self.is_int() || rhs.is_int() {
80 let width = self.width().max(rhs.width());
81 match width {
82 1 => Type::I8,
83 2 => Type::I16,
84 4 => Type::I32,
85 8 => Type::I64,
86 _ => panic!("{:?} 非法类型", self),
87 }
88 } else if self.is_uint() || rhs.is_uint() {
89 let width = self.width().max(rhs.width());
90 match width {
91 1 => Type::U8,
92 2 => Type::U16,
93 4 => Type::U32,
94 8 => Type::U64,
95 _ => panic!("{:?} 非法类型", self),
96 }
97 } else {
98 Type::Any
99 }
100 }
101}
102
103impl PartialEq for Type {
104 fn eq(&self, other: &Self) -> bool {
105 match (self, other) {
106 (Type::Any, Type::Any) => true,
107 (Type::Void, Type::Void)
108 | (Type::Bool, Type::Bool)
109 | (Type::U8, Type::U8)
110 | (Type::I8, Type::I8)
111 | (Type::U16, Type::U16)
112 | (Type::I16, Type::I16)
113 | (Type::U32, Type::U32)
114 | (Type::I32, Type::I32)
115 | (Type::U64, Type::U64)
116 | (Type::I64, Type::I64)
117 | (Type::F16, Type::F16)
118 | (Type::F32, Type::F32)
119 | (Type::F64, Type::F64)
120 | (Type::Str, Type::Str)
121 | (Type::Map, Type::Map)
122 | (Type::List, Type::List) => true,
123 (Type::Ident { name: name1, params: params1 }, Type::Ident { name: name2, params: params2 }) => name1 == name2 && params1 == params2,
124 (Type::ConstInt(left), Type::ConstInt(right)) => left == right,
125 (Type::ConstBinary { op: op1, left: left1, right: right1 }, Type::ConstBinary { op: op2, left: left2, right: right2 }) => op1 == op2 && left1 == left2 && right1 == right2,
126 (Type::Symbol { id: id1, params: p1 }, Type::Symbol { id: id2, params: p2 }) => id1 == id2 && p1 == p2,
127 (Type::Struct { params: p1, fields: f1 }, Type::Struct { params: p2, fields: f2 }) => {
128 p1.len() == p2.len() && f1.len() == f2.len() && p1.iter().zip(p2.iter()).position(|(t1, t2)| t1 != t2).is_none() && f1.iter().zip(f2.iter()).position(|(item1, item2)| item1 != item2).is_none()
129 }
130 (Type::Vec(elem_type1, len1), Type::Vec(elem_type2, len2)) => elem_type1 == elem_type2 && len1 == len2,
131 (Type::Array(elem_type1, len1), Type::Array(elem_type2, len2)) => elem_type1 == elem_type2 && len1 == len2,
132 (Type::ArrayParam(elem_type1, len1), Type::ArrayParam(elem_type2, len2)) => elem_type1 == elem_type2 && len1 == len2,
133 (Type::Fn { tys: t1, ret: r1 }, Type::Fn { tys: t2, ret: r2 }) => {
134 if t1 == t2 {
135 if r1 != r2 {
136 panic!("函数返回类型不一致")
137 }
138 true
139 } else {
140 false
141 }
142 }
143 _ => false,
144 }
145 }
146}
147
148impl Type {
149 fn align_up(value: u32, align: u32) -> u32 {
150 if align <= 1 { value } else { (value + align - 1) & !(align - 1) }
151 }
152
153 pub fn align(&self) -> u32 {
154 self.storage_width().min(8).max(1)
155 }
156
157 pub fn storage_width(&self) -> u32 {
158 match self {
159 Self::Void => 0,
160 Self::Bool => 1,
161 Self::U8 | Self::I8 => 1,
162 Self::U16 | Self::I16 | Self::F16 => 2,
163 Self::U32 | Self::I32 | Self::F32 => 4,
164 Self::U64 | Self::I64 | Self::F64 => 8,
165 Self::Struct { params: _, fields } => Self::struct_layout(fields).0,
166 Self::Vec(ty, num) => num * ty.storage_width(),
167 Self::Array(ty, num) => num * ty.storage_width(),
168 Self::ArrayParam(ty, len) => {
169 if let Self::ConstInt(num) = len.as_ref() {
170 if *num >= 0 { *num as u32 * ty.storage_width() } else { 8 }
171 } else {
172 8
173 }
174 }
175 Self::ConstBinary { .. } => 8,
176 _ => 8,
177 }
178 }
179
180 pub fn struct_layout(fields: &[(SmolStr, Type)]) -> (u32, Vec<u32>) {
181 let mut offset = 0;
182 let mut offsets = Vec::with_capacity(fields.len());
183 let mut struct_align = 8;
184 for (_, ty) in fields {
185 let align = ty.align().min(8);
186 struct_align = struct_align.max(align);
187 offset = Self::align_up(offset, align);
188 offsets.push(offset);
189 offset += ty.storage_width();
190 }
191 (Self::align_up(offset, struct_align), offsets)
192 }
193
194 pub fn field_offset(&self, idx: usize) -> Option<u32> {
195 if let Self::Struct { params: _, fields } = self { Self::struct_layout(fields).1.get(idx).cloned() } else { None }
196 }
197
198 pub fn len(&self) -> usize {
199 match self {
200 Self::Struct { params: _, fields } => fields.len(),
201 Self::Tuple(items) => items.len(),
202 Self::Vec(_, num) | Self::Array(_, num) => *num as usize,
203 Self::ArrayParam(_, len) => {
204 if let Self::ConstInt(num) = len.as_ref() {
205 if *num >= 0 { *num as usize } else { 0 }
206 } else {
207 0
208 }
209 }
210 Self::ConstBinary { .. } => 0,
211 _ => 0,
212 }
213 }
214
215 pub fn compare_args(left: &[Type], right: &[Type]) -> Option<Vec<Type>> {
216 let mut tys = Vec::new();
217 for (left, right) in left.iter().zip(right.iter()) {
218 if left == right || right.is_any() {
219 tys.push(left.clone());
220 } else if left.is_any() {
221 tys.push(right.clone());
222 } else {
223 return None;
224 }
225 }
226 Some(tys)
227 }
228
229 pub fn force(&self, src: Dynamic) -> Result<Dynamic, DynamicErr> {
230 match self {
231 Self::Bool => src.try_into().map(Dynamic::Bool),
232 Self::I8 => src.try_into().map(Dynamic::I8),
233 Self::I16 => src.try_into().map(Dynamic::I16),
234 Self::I32 => src.try_into().map(Dynamic::I32),
235 Self::I64 => src.try_into().map(Dynamic::I64),
236 Self::U8 => src.try_into().map(Dynamic::U8),
237 Self::U16 => src.try_into().map(Dynamic::U16),
238 Self::U32 => src.try_into().map(Dynamic::U32),
239 Self::U64 => src.try_into().map(Dynamic::U64),
240 Self::F32 => src.try_into().map(Dynamic::F32),
241 Self::F64 => src.try_into().map(Dynamic::F64),
242 _ => Ok(src),
243 }
244 }
245
246 pub fn width(&self) -> u32 {
247 self.storage_width()
249 }
250
251 pub fn is_void(&self) -> bool {
252 if let Self::Void = self { true } else { false }
253 }
254
255 pub fn is_bool(&self) -> bool {
256 if let Self::Bool = self { true } else { false }
257 }
258
259 pub fn is_str(&self) -> bool {
260 if let Self::Str = self { true } else { false }
261 }
262
263 pub fn is_native(&self) -> bool {
264 match self {
265 Self::F16 | Self::F32 | Self::F64 | Self::U8 | Self::I8 | Self::U16 | Self::I16 | Self::U32 | Self::I32 | Self::U64 | Self::I64 => true,
266 _ => false,
267 }
268 }
269
270 pub fn is_any(&self) -> bool {
271 match self {
272 Self::Any => true,
273 Self::Fn { tys: _, ret } => ret.is_any(),
274 _ => false,
275 }
276 }
277
278 pub fn is_ident(&self) -> bool {
279 if let Self::Ident { name: _, params: _ } = self { true } else { false }
280 }
281
282 pub fn is_struct(&self) -> bool {
283 if let Self::Struct { .. } = self { true } else { false }
284 }
285
286 pub fn get_field(&self, name: &str) -> Result<(usize, &Type)> {
287 if let Self::Struct { params: _, fields } = self {
288 fields.iter().enumerate().find(|(_, (field_name, _))| field_name == name).map(|(index, (_, ty))| (index, ty)).ok_or(anyhow!("{:?} 未发现属性 {}", self, name))
289 } else {
290 Err(anyhow!("不是结构体"))
291 }
292 }
293
294 pub fn add_field(&mut self, name: SmolStr, ty: Type) -> Result<u32> {
295 if let Self::Struct { params: _, fields } = self {
296 fields.push((name, ty));
297 Ok(fields.len() as u32 - 1)
298 } else {
299 Err(anyhow!("不是结构体"))
300 }
301 }
302
303 pub fn is_vec(&self) -> bool {
304 if let Self::Vec(_, _) = self { true } else { false }
305 }
306
307 pub fn is_array(&self) -> bool {
308 if let Self::Array(_, _) = self { true } else { false }
309 }
310
311 pub fn is_int(&self) -> bool {
312 match self {
313 Self::I8 | Self::I16 | Self::I32 | Self::I64 => true,
314 _ => false,
315 }
316 }
317
318 pub fn is_uint(&self) -> bool {
319 match self {
320 Self::U8 | Self::U16 | Self::U32 | Self::U64 => true,
321 _ => false,
322 }
323 }
324
325 pub fn sign(self) -> Self {
326 match self {
327 Self::U8 => Self::I8,
328 Self::U16 => Self::I16,
329 Self::U32 => Self::I32,
330 Self::U64 => Self::I64,
331 _ => self,
332 }
333 }
334
335 pub fn is_float(&self) -> bool {
336 match self {
337 Self::F16 | Self::F32 | Self::F64 => true,
338 _ => false,
339 }
340 }
341
342 pub fn is_f64(&self) -> bool {
343 match self {
344 Self::F64 => true,
345 _ => false,
346 }
347 }
348
349 pub fn is_f32(&self) -> bool {
350 match self {
351 Self::F32 => true,
352 _ => false,
353 }
354 }
355
356 pub fn is_fn(&self) -> bool {
357 if let Self::Fn { .. } = self { true } else { false }
358 }
359
360 pub fn from_args(args: Vec<(SmolStr, Type)>) -> (Self, Vec<SmolStr>) {
361 let (args, tys) = args.into_iter().fold((Vec::new(), Vec::new()), |mut v, a| {
362 v.0.push(a.0);
363 v.1.push(a.1);
364 v
365 });
366 (Self::Fn { tys, ret: Rc::new(Type::Any) }, args)
367 }
368}
369
370impl Dynamic {
371 pub fn get_type(&self) -> Type {
372 let len = self.len() as u32;
373 match self {
374 Self::Bool(_) => Type::Bool,
375 Self::I8(_) => Type::I8,
376 Self::I16(_) => Type::I16,
377 Self::I32(_) => Type::I32,
378 Self::I64(_) => Type::I64,
379 Self::U8(_) => Type::U8,
380 Self::U16(_) => Type::U16,
381 Self::U32(_) => Type::U32,
382 Self::U64(_) => Type::U64,
383 Self::F32(_) => Type::F32,
384 Self::F64(_) => Type::F64,
385 Self::Bytes(_) => Type::Vec(Rc::new(Type::U8), len),
386 Self::VecI8(_) => Type::Vec(Rc::new(Type::I8), len),
387 Self::VecI16(_) => Type::Vec(Rc::new(Type::I16), len),
388 Self::VecI32(_) => Type::Vec(Rc::new(Type::I32), len),
389 Self::VecI64(_) => Type::Vec(Rc::new(Type::I64), len),
390 Self::VecU16(_) => Type::Vec(Rc::new(Type::U16), len),
391 Self::VecU32(_) => Type::Vec(Rc::new(Type::U32), len),
392 Self::VecU64(_) => Type::Vec(Rc::new(Type::U64), len),
393 Self::VecF32(_) => Type::Vec(Rc::new(Type::F32), len),
394 Self::VecF64(_) => Type::Vec(Rc::new(Type::F64), len),
395 Self::String(_) => Type::Str,
396 Self::Map(_) => Type::Map,
397 Self::Struct { ty, .. } => ty.clone(),
398 Self::Null => Type::Void,
399 Self::List(items) => {
400 let tys: Vec<Type> = items.read().unwrap().iter().map(|v| v.get_type()).collect();
401 if let Some(first) = tys.first() {
402 if tys.iter().all(|x| x == first) {
403 return Type::Array(Rc::new(first.clone()), len);
404 }
405 }
406 Type::List
407 }
408 Self::Iter { idx: _, keys: _, value: _ } => Type::Iter,
409 }
410 }
411}
412
413pub fn call_fn(ptr: i64, ret_ty: Type, param: Box<Dynamic>) -> Result<Box<Dynamic>> {
414 match ret_ty {
415 Type::Any => {
416 let fn_ptr: extern "C" fn(*const Dynamic) -> *mut Dynamic = unsafe { std::mem::transmute(ptr) };
417 let r = fn_ptr(Box::into_raw(param));
418 Ok(unsafe { Box::from_raw(r) })
419 }
420 Type::Bool => {
421 let fn_ptr: extern "C" fn(*const Dynamic) -> i8 = unsafe { std::mem::transmute(ptr) };
422 let r = fn_ptr(Box::into_raw(param));
423 Ok(Box::new(Dynamic::Bool(r != 0)))
424 }
425 Type::Void => {
426 let fn_ptr: extern "C" fn(*const Dynamic) = unsafe { std::mem::transmute(ptr) };
427 fn_ptr(Box::into_raw(param));
428 Ok(Box::new(Dynamic::Null))
429 }
430 Type::F32 => {
431 let fn_ptr: extern "C" fn(*const Dynamic) -> f32 = unsafe { std::mem::transmute(ptr) };
432 Ok(Box::new(Dynamic::F32(fn_ptr(Box::into_raw(param)))))
433 }
434 Type::F64 => {
435 let fn_ptr: extern "C" fn(*const Dynamic) -> f64 = unsafe { std::mem::transmute(ptr) };
436 Ok(Box::new(Dynamic::F64(fn_ptr(Box::into_raw(param)))))
437 }
438 _ => {
439 let fn_ptr: extern "C" fn(*const Dynamic) -> i64 = unsafe { std::mem::transmute(ptr) };
440 let r = fn_ptr(Box::into_raw(param));
441 Ok(Box::new(Dynamic::I64(r)))
442 }
443 }
444}