Skip to main content

dynamic/
types.rs

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, //这个是任何类型 none 动态类型 可以是任何类型
20    Void, //整个是空类型  void()
21    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),   //spirv 特有 表示向量 一般在四个元素以下
53    Array(Rc<Type>, u32), //这是通常意义上的 类型数组,没有大小的限制
54    ArrayParam(Rc<Type>, Rc<Type>),
55    Fn {
56        tys: Vec<Type>,
57        ret: Rc<Type>,
58    }, //调用参数 和返回参数的类型 注意
59    Symbol {
60        id: u32,
61        params: Vec<Type>,
62    }, //自定义的类型 仅在有符号表的情况下有意义 可能是结构 有可能是函数 支持泛型参数
63}
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        //所占字节数
248        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}