在 AST 中增加支持 struct 的代码之后,我们的 AST 变成这样
编译到中间代码显然会出错,首先是 Pattern 不支持这种 访问
这里 还没有处理到
Pattern::Member(base, field) => { println!("pat {:?} {:?}", base, field); let obj = self.get_pattern_dest(code, *base)?; None }
复制代码
我们修改成这样
Pattern::Member(base, field) => { let obj = self.get_pattern_dest(code, *base)?; let idx = self.symbols.add_const(None, Dynamic::from(field)); Some(Symbol::Idx(Box::new(obj), Box::new(idx))) }
复制代码
现在编译可以顺利通过 生成的 Zeta 中间代码长这样
但是获取类型的时候出错,因为我们还没有注册 这个结构类型,所以我们需要注册结构
下面是在 spirv 模块里面注册 struct 的函数
fn add_struct(&mut self, def: &StructDef)-> u32 { let type_ids: Vec<u32> = def.fields.iter().map(|(_, ty)| self.get_type(ty.clone()) ).collect(); let struct_ty = self.builder.type_struct(type_ids); self.builder.decorate(struct_ty, spirv::Decoration::Block, vec![]); let mut offset = 0u32; for (id, field) in def.fields.iter().enumerate() { self.builder.member_decorate(struct_ty, id as u32, spirv::Decoration::Offset, vec![rspirv::dr::Operand::LiteralBit32(offset)]); let size = field.1.width(); offset += size; } struct_ty }
复制代码
在 import_module 的时候,注册所有的 struct
for (_, def) in module.defs { let ty_id = self.add_struct(&def); self.types.push((Type::Struct(def), ty_id)); }
复制代码
然后需要修改 Type::Struct 的比较 只要名字相等就相等
impl PartialEq for StructDef { fn eq(&self, other: &Self) -> bool { self.name == other.name }}
复制代码
现在我们 成功的 编译到这里了
Symbol::Idx(obj, idx)=> { let obj = self.get(obj); if let Type::Vec(ty, num) = obj.ty { if let Some(val) = self.get_const(idx) { let ty_id = self.get_type((*ty).clone()); let id = self.builder.composite_extract(ty_id, None, obj.id, vec![val.val.as_u32().unwrap()]).unwrap(); Var{id, ty: (*ty).clone(), cls: StorageClass::Function} } else { panic!("") } } else { panic!("{:?} {:?}", obj, idx) }
复制代码
还没实现。现在 输出的东西是这样的
这个 type 有点小问题,不是我们的标准版本 是简化版本 没有详细的 fields 定义
评论