1 个不稳定版本
0.1.0 | 2024年4月28日 |
---|
#105 in #语义
用于 langmeantree
41KB
956 行
SModel
SModel (语义建模) 为 Rust 提供了一种使用动态分派和层次定义通过允许循环引用的竞技场来描述语言语义符号的便捷方式。
定义顺序
定义顺序很重要。在使用 struct
关键字时,先定义继承的数据类型,然后定义子类型。
如果您以任何顺序定义 struct
,可能会得到一个导致宏终止的 未找到 错误。
示例
最基本的数据类型是最先出现的。您可以根据自己的喜好为其命名。通常可以将其称为 符号 或 东西(根据微软 Roslyn 的工程师的说法,符号 应该被称为 东西)。
use smodel::smodel;
smodel! {
type Arena = Arena;
struct Thingy {
let x: f64 = 0.0;
let ref y: String = "".into();
pub fn Thingy() {
super();
println!("{}", self.m());
}
pub fn m(&self) -> String {
"".into()
}
pub fn m1(&self) {
println!("base");
}
}
struct Foo: Thingy {
pub fn Foo() {
super();
}
pub override fn m(&self) -> String {
"Foo".into()
}
pub override fn m1(&self) {
if true {
super.m1();
}
}
}
}
fn main() {
let arena = Arena::new();
let thingy = Foo::new(&arena);
println!("{}", thingy.m());
}
竞技场
竞技场的名称定义为第一个 type Arena = ArenaName1;
指令的右侧。
字段
字段(一个 let
声明)有一个可选的 ref
修饰符,指示是否使用 RefCell
或 Cell
。对于所有类型,在读取时都会克隆或复制。对于堆分配的资源,如 String
,请使用 ref
。
字段有一对获取器(fieldname()
)和设置器(set_fieldname(value)
)。
对于可变哈希映射或向量,建议使用一个 共享容器(见下文),该容器通过引用克隆,而不是通过内容克隆。
字段始终位于封装的模块内部,因此没有属性;字段定义始终以 let
关键字开始,没有 RustDoc 注释。
建议字段始终以下划线 _
或私有前缀,如 m_
开头,并且相应地使用 _x()
和 set__x(v)
,或者分别使用 m_x()
和 set_m_x()
。
然后,在基类型中实现可能被子类型重写的方法,允许实现一个支持在多个变体上操作的方法的 统一 数据类型。
共享容器
此包提供了两种通过引用复制的容器数据类型,分别是 SharedArray
和 SharedMap
,以及 shared_array!
和 shared_map!
字面量。
SharedArray
是一个由引用计数管理的可变向量。SharedMap
是一个由引用计数管理的可变哈希表。
有关使用细节,请参阅包文档。
构造函数
构造函数是一个名称与数据类型名称匹配的方法。参数列表中将隐式地添加 arena
参数。
构造函数被转换为一个静态的 new
方法。
构造函数包含一个局部变量 self
,其数据类型是封装数据类型的实例。
子类型
symbol.is::<T>()
测试symbol
是否是T
子类型。symbol.to::<T>()
转换为T
子类型,返回Ok(m)
或Err
。它可能是一个逆变转换。symbol.into()
是一个协变转换。
超表达式
super.f()
表达式通过预处理方法标记序列并转换为其他Rust代码来支持;因此,它可以在实例方法的任何地方使用。
super.f()
以降序方式在基数据类型的方法列表中进行查找。
继承文档
使用 #[inheritdoc]
属性来继承被重写方法的 RustDoc 注释。
#[inheritdoc]
pub override fn m(&self) {
// Action
}
方法参数
目前,重写方法中的方法参数名称应与子类型方法的名称匹配,否则可能会发生宏卫生错误,指示参数不在子类型的方法中。
许可证
Apache 2.0,版权所有 © Hydroper
依赖关系
~285–730KB
~17K SLoC