仓颉编程语言:宏包定义和导入

仓颉宏的定义需要放在由 macro package 声明的包中,被 macro package 限定的包仅允许宏定义对外可见,其他声明包内可见。

说明

重导出的声明也允许对外可见,关于包管理和重导出的相关概念。

// file define.cj
macro package define         // 编译 define.cjo 携带 macro 属性
import std.ast.*

public func A() {}          // Error, 宏包不允许定义外部可见的非宏定义,此处需报错

public macro M(input: Tokens): Tokens { // macro M 外部可见
    return input
}

需要特殊说明的是,在 macro package 中允许其它 macro package 和非 macro package 符号被重导出,在非 macro package 中仅允许非 macro package 符号被重导出。

参考如下示例:

  • 在宏包 A 中定义宏 M1

    macro package A
    import std.ast.*
    
    public macro M1(input: Tokens): Tokens {
        return input
    }

    编译命令如下:

    cjc A.cj --compile-macro
  • 在非宏包 B 中定义一个 public 函数 F1。注意在非 macro package 中无法重导出 macro package 的符号

    package B
    // public import A.* // Error, it is not allowed to re-export a macro package in a package.
    
    public func F1(input: Int64): Int64 {
        return input
    }

    编译命令如下,这里选择使用 --output-type 选项将 B 包编译成到动态库,关于 cjc 编译选项介绍可以参考cjc 编译选项章节。

    cjc B.cj --output-type=dylib -o libB.so
  • 在宏包 C 中定义宏 M2,依赖了 A 包和 B 包的内容。可以看到 macro package 中可以重导出 macro package 和非 macro package 的符号

    macro package C
    public import A.* // correct: macro package is allowed to re-export in a macro package.
    public import B.* // correct: non-macro package is also allowed to re-export in a macro package.
    import std.ast.*
    
    public macro M2(input: Tokens): Tokens {
        return @M1(input) + Token(TokenKind.NL) + quote(F1(1))
    }

    编译命令如下,注意这里需要显式链接 B 包动态库:

    cjc C.cj --compile-macro -L. -lB
  • 在 main.cj 中使用 M2 宏

    import C.*
    
    main() {
        @M2(let a = 1)
    }

    编译命令如下:

    cjc main.cj -o main -L. -lB

    main.cj中 M2 宏展开后的结果如下:

    import C.*
    
    main() {
        let a = 1
        F1(1)
    }

可以看到 main.cj 中出现了来自于 B 包的符号 F1。宏的编写者可以在 C 包中重导出 B 包里的符号,这样宏的使用者仅需导入宏包,就可以正确的编译宏展开后的代码。如果在 main.cj 中仅使用 import C.M2 导入宏符号,则会报 undeclared identifier 'F1' 的错误信息。


 看完三件事❤️

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注作者公众皓 『 蜀道衫 』,不定期分享原创知识。
  • 关注后回复【666】扫码即可获取学习资料包。
  • 同时可以期待后续文章ing🚀。

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值