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