写点什么

结构支持 编译到中间代码

作者:Miracle
  • 2025-09-24
    四川
  • 本文字数:1253 字

    阅读完需:约 4 分钟

结构支持 编译到中间代码

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


用户头像

Miracle

关注

三十年资深码农 2019-10-25 加入

还未添加个人简介

评论

发布
暂无评论
结构支持 编译到中间代码_Miracle_InfoQ写作社区