Skip to content

Commit

Permalink
添加两个值绑定相关内置函数, 修改常量绑定者跟踪机制
Browse files Browse the repository at this point in the history
- 还添加了编译时元数据调试输出内置函数
- 更新了编译时元数据的调试输出
  • Loading branch information
A4-Tacks committed Jan 16, 2024
1 parent 23c22ba commit 0305889
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 23 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mindustry_logic_bang_lang"
version = "0.14.9"
version = "0.14.10"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
4 changes: 4 additions & 0 deletions examples/builtin_functions.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
* * `Unbind[var]`: 传入一个值绑定, 返回绑定者
* * `Const[name value]`: 动态目标的进行一个const, 并泄露到上层
* * `Binder[name value]`: 传入一个值绑定, 将其被绑定值const给给定名称
* * `BindHandle[value]`: 直接获取值绑定的句柄, 但是不进行最后一层全局常量域追踪
* * `BindHandle2[value name]`: 直接获取值绑定的句柄, 但是不进行最后一层全局常量域追踪.
* 与另一个不同的是它使用被绑定值和绑定量两个参数
* * `Debug[value]`: 以debug形式将传入值输出到日志
* * `Exit[code]`: 直接使编译器以给定的退出码值退出
* * `Status[]`: 获取上一个内置函数的退出代码, 通常情况下, 零代表正常, 非零即异常
* * `ArgsLen[]`: 获取上层有效参数表长度
* * `SliceArgs[start end]`: 将参数切分, 但不take
* * `ArgsHandle[idx]`: 拿到指定下标的参数的const句柄, 配合Const内置函数转移其值
* * `MetaDebug[]`: 以调试形式输出编译时元数据
*#

print Builtin.Type[x];
Expand Down
2 changes: 1 addition & 1 deletion tools/parser/tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "parser-tests"
version = "0.1.5"
version = "0.1.6"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
48 changes: 47 additions & 1 deletion tools/parser/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4461,7 +4461,7 @@ fn value_bind_of_constkey_test() {
}

#[test]
fn dexp_expand_binder_test() {
fn const_value_expand_binder_test() {
let parser = TopLevelParser::new();

assert_eq!(
Expand Down Expand Up @@ -4629,6 +4629,52 @@ fn dexp_expand_binder_test() {
"print 3",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
const a.X = (
print ..;
);
const b.X = a.X;
take a.X;
take b.X;
"#).unwrap()).compile().unwrap(),
vec![
"print a",
"print a",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
const A = a;
const A.X = (
print ..;
);
take A.X;
"#).unwrap()).compile().unwrap(),
vec![
"print a",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
const a.X = (
print ..;
);
take Handle = Builtin.BindHandle2[`a` `X`];
take Builtin.Const[`Handle` Handle];
const b.X = Handle;
take a.X;
const a.X = 2;
take b.X;
"#).unwrap()).compile().unwrap(),
vec![
"print a",
"print a",
],
);
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion tools/syntax/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "syntax"
version = "0.2.6"
version = "0.2.7"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
23 changes: 23 additions & 0 deletions tools/syntax/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,23 @@ pub fn build_builtins() -> Vec<BuiltinFunc> {
})
}

fn bind_handle:BindHandle(meta) [v:value] {
check_type!("valuebind" Value::ValueBind(bind) = value.value() => {
let handle = bind.clone().take_unfollow_handle(meta);
Ok(handle)
})
}

fn bind_handle2:BindHandle2(meta) [b:binder n:name] {
check_type!("var" Value::Var(name) = name.value() => {
let bind = ValueBind(
binder.value().clone().into(),
name.clone(),
);
Ok(bind.take_unfollow_handle(meta))
})
}

fn exit:Exit(meta) [n:code] {
check_type!("var" Value::Var(code) = code.value() => {
let num_code = match code.parse() {
Expand Down Expand Up @@ -282,5 +299,11 @@ pub fn build_builtins() -> Vec<BuiltinFunc> {
.unwrap_or_else(|| "__".into()))
})
}

fn meta_dbg:MetaDebug(meta) [] {
let msg = format!("{:#?}", meta);
meta.log_info(msg);
Ok("__".into())
}
}
}
64 changes: 48 additions & 16 deletions tools/syntax/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,14 +488,16 @@ impl_derefs!(impl for DExp => (self: self.lines): Expand);
/// 可完成如属性调用的功能
#[derive(Debug, PartialEq, Clone)]
pub struct ValueBind(pub Box<Value>, pub Var);
impl ValueBind {
pub fn take_unfollow_handle(self, meta: &mut CompileMeta) -> Var {
let handle = self.0.take_handle(meta);
meta.get_value_binded(handle, self.1).clone()
}
}
impl TakeHandle for ValueBind {
fn take_handle(self, meta: &mut CompileMeta) -> Var {
let handle = self.0.take_handle(meta);
assert!(! Value::is_string(&self.1));
let binded
= meta.get_value_binded(handle, self.1).clone();
// 进行常量表查询
binded.take_handle(meta)
self.take_unfollow_handle(meta)
.take_handle(meta) // 进行通常是全局表的常量表查询
}
}

Expand Down Expand Up @@ -1987,8 +1989,8 @@ impl Const {
Self(var, value, Default::default())
}

/// 在const编译前对右部分进行处理
pub fn run_value(&mut self, meta: &mut CompileMeta) {
/// 在const编译前对右部分进行处理, 如果目标有的话, 返回绑定者
pub fn run_value(&mut self, meta: &mut CompileMeta) -> Option<Var> {
let value = &mut self.1;
match value {
Value::ReprVar(var) => {
Expand All @@ -1997,21 +1999,27 @@ impl Const {
},
Value::Var(var) => {
if let Some(data) = meta.get_const_value(var) {
let ConstData { value, labels, .. } = data;
let ConstData {
value,
labels,
binder,
} = data;
self.1 = value.clone();
self.2 = labels.clone();
return binder.as_ref().cloned();
}
},
_ => (),
}
None
}
}
impl Compile for Const {
fn compile(mut self, meta: &mut CompileMeta) {
// 对同作用域定义过的常量形成覆盖
// 如果要进行警告或者将信息传出则在此处理
self.run_value(meta);
meta.add_const_value(self);
let extra_binder = self.run_value(meta);
meta.add_const_value_with_extra_binder(self, extra_binder);
}
}

Expand Down Expand Up @@ -2712,11 +2720,15 @@ impl Debug for CompileMeta {
.field("tag_count", &self.tag_count)
.field("tag_codes", &self.tag_codes)
.field("tmp_var_count", &self.tmp_var_count.counter())
.field("const_var_namespace", &self.expand_env)
.field("expand_env", &self.expand_env)
.field("env_args", &self.env_args)
.field("dexp_result_handles", &self.dexp_result_handles)
.field("dexp_expand_binders", &self.dexp_expand_binders)
.field("tmp_tag_count", &self.tmp_tag_count.counter())
.field("const_expand_tag_name_map", &self.const_expand_tag_name_map)
.field("value_binds", &self.value_binds)
.field("value_bind_global_consts", &self.value_bind_global_consts)
.field("last_builtin_exit_code", &self.last_builtin_exit_code)
.field("..", &DotDot)
.finish()
}
Expand Down Expand Up @@ -2924,23 +2936,43 @@ impl CompileMeta {
}

/// 新增一个常量到值的映射, 如果当前作用域已有此映射则返回旧的值并插入新值
pub fn add_const_value(&mut self, Const(var, value, labels): Const)
pub fn add_const_value(&mut self, r#const: Const)
-> Option<ConstData> {
self.add_const_value_with_extra_binder(r#const, None)
}

/// 新增一个常量到值的映射, 如果当前作用域已有此映射则返回旧的值并插入新值
///
/// 如果扩展绑定者存在的话, 忽略键中的绑定者而采用扩展绑定者
pub fn add_const_value_with_extra_binder(
&mut self,
Const(var, value, labels): Const,
extra_binder: Option<Var>,
) -> Option<ConstData> {
match var {
ConstKey::Var(_) => {
let var = var.take_handle(self);

let mut data = ConstData::new(value, labels);
if let Some(extra_binder) = extra_binder {
data = data.set_binder(extra_binder)
}
self.expand_env
.last_mut()
.unwrap()
.consts
.insert(var, ConstData::new(value, labels))
.insert(var, data)
},
ConstKey::ValueBind(ValueBind(binder, name)) => {
assert!(! Value::is_string(&name));
let binder_handle = binder.take_handle(self);
let binder
= if let Some(extra_binder) = extra_binder {
extra_binder
} else {
binder_handle.clone()
};
let data = ConstData::new(value, labels)
.set_binder(binder_handle.clone());
.set_binder(binder);
let binded = self.get_value_binded(
binder_handle, name).clone();
self.value_bind_global_consts
Expand Down

0 comments on commit 0305889

Please sign in to comment.