在 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 定义
评论