Skip to content

Commit

Permalink
增加闭包捕获环境参数的能力
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Nov 14, 2024
1 parent 4cb4eb0 commit 3407690
Show file tree
Hide file tree
Showing 12 changed files with 347 additions and 58 deletions.
10 changes: 5 additions & 5 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.17.9"
version = "0.17.10"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
18 changes: 18 additions & 0 deletions examples/closured_value.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,21 @@ print "expected"
print "unexpected"
jump 4 always 0 0
*#


# 在0.17.10版本添加了捕获环境参数的功能, 会在展开闭包前设置环境参数
const Builder = (
const X = 2;
const $.F = ([X @](
print X @;
));
);

const Clos = Builder[a b c]->F;
take Clos[d e f];
#* >>>
print 2
print a
print b
print c
*#
2 changes: 1 addition & 1 deletion tools/display_source/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "display_source"
version = "0.3.24"
version = "0.3.25"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
87 changes: 59 additions & 28 deletions tools/display_source/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,18 @@ impl DisplaySource for ClosuredValue {
catch_labels,
value,
labels,
catch_args,
} => {
meta.push("([");
meta.display_source_iter_by_splitter(
|meta| {
meta.display_source_iter_by_space(catch_values);
if *catch_args {
if !catch_values.is_empty() {
meta.add_space();
},
catch_values,
);
}
meta.push("@");
}
if !catch_labels.is_empty() {
if !catch_values.is_empty() {
if !catch_values.is_empty() || *catch_args {
meta.add_space();
}
meta.push("|");
Expand All @@ -100,6 +102,7 @@ impl DisplaySource for ClosuredValue {
bind_handle,
rename_labels,
vars,
reset_argc: reset_args,
} => {
struct CatchedVar<'a>(&'a Var);
impl DisplaySource for CatchedVar<'_> {
Expand All @@ -114,14 +117,17 @@ impl DisplaySource for ClosuredValue {
let catcheds = vars.iter()
.map(|var| CatchedVar(var));
meta.push("([");
meta.display_source_iter_by_splitter(
|meta| {
meta.display_source_iter_by_space(catcheds);
if let Some(args) = reset_args {
if !vars.is_empty() {
meta.add_space();
},
catcheds,
);
}
meta.push("@(");
meta.push_fmt(args);
meta.push(")");
}
if !rename_labels.is_empty() {
if !vars.is_empty() {
if !vars.is_empty() || reset_args.is_some() {
meta.add_space();
}
meta.push("|");
Expand Down Expand Up @@ -525,8 +531,7 @@ impl DisplaySource for Args {
fn display_source(&self, meta: &mut DisplaySourceMeta) {
match self {
Args::Normal(args) => {
meta.display_source_iter_by_splitter(
DisplaySourceMeta::add_space, args);
meta.display_source_iter_by_space(args);
},
Args::Expanded(prefix, suffix) => {
prefix.iter().for_each(|arg| {
Expand Down Expand Up @@ -570,10 +575,7 @@ impl DisplaySource for MatchPatAtom {
}
if show_list {
meta.push("[");
meta.display_source_iter_by_splitter(
DisplaySourceMeta::add_space,
self.pattern()
);
meta.display_source_iter_by_space(self.pattern());
meta.push("]");
}
}
Expand All @@ -582,10 +584,7 @@ impl DisplaySource for MatchPat {
fn display_source(&self, meta: &mut DisplaySourceMeta) {
match self {
MatchPat::Normal(args) => {
meta.display_source_iter_by_splitter(
DisplaySourceMeta::add_space,
args,
)
meta.display_source_iter_by_space(args)
},
MatchPat::Expanded(prefix, suffix) => {
for s in prefix {
Expand Down Expand Up @@ -654,8 +653,7 @@ impl DisplaySource for ConstMatchPatAtom {
if self.pattern().is_right() {
meta.push("?");
}
meta.display_source_iter_by_splitter(
DisplaySourceMeta::add_space,
meta.display_source_iter_by_space(
self.pattern()
.as_ref()
.map_right(Some)
Expand All @@ -669,10 +667,7 @@ impl DisplaySource for ConstMatchPat {
fn display_source(&self, meta: &mut DisplaySourceMeta) {
match self {
ConstMatchPat::Normal(args) => {
meta.display_source_iter_by_splitter(
DisplaySourceMeta::add_space,
args,
)
meta.display_source_iter_by_space(args)
},
ConstMatchPat::Expanded(prefix, suffix) => {
for s in prefix {
Expand Down Expand Up @@ -1176,6 +1171,42 @@ fn display_source_test() {
"const X = ([A:A B:B | :c :d]2);"
);

assert_eq!(
parse!(line_parser, r#"
const X = ([@]2);
"#)
.unwrap()
.display_source_and_get(&mut meta),
"const X = ([@]2);"
);

assert_eq!(
parse!(line_parser, r#"
const X = ([A @]2);
"#)
.unwrap()
.display_source_and_get(&mut meta),
"const X = ([A:A @]2);"
);

assert_eq!(
parse!(line_parser, r#"
const X = ([A @ | :c]2);
"#)
.unwrap()
.display_source_and_get(&mut meta),
"const X = ([A:A @ | :c]2);"
);

assert_eq!(
parse!(line_parser, r#"
const X = ([@ | :c]2);
"#)
.unwrap()
.display_source_and_get(&mut meta),
"const X = ([@ | :c]2);"
);

assert_eq!(
parse!(line_parser, r#"
(a:) (`b`:);
Expand Down
20 changes: 19 additions & 1 deletion tools/display_source/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{ops::Deref, mem};
use core::fmt;
use std::{fmt::Write, mem, ops::Deref};
pub mod impls;

pub const LF: char = '\n';
Expand Down Expand Up @@ -85,6 +86,12 @@ impl DisplaySourceMeta {
self.buffer.push_str(s)
}

/// 添加字符串到缓冲区
pub fn push_fmt(&mut self, f: impl fmt::Display) {
self.check_indent();
self.buffer.write_fmt(format_args!("{f}")).unwrap()
}

/// 如果缩进标志位打开, 则向缓冲区加入缩进
pub fn check_indent(&mut self) {
if self.do_indent_flag {
Expand Down Expand Up @@ -179,6 +186,17 @@ impl DisplaySourceMeta {
s.display_source(self)
})
}

/// 从可迭代对象中生成, 以空格分割
pub fn display_source_iter_by_space<'a, T: DisplaySource + 'a>(
&mut self,
iter: impl IntoIterator<Item = T>
) {
self.display_source_iter_by_splitter(
|meta| meta.add_space(),
iter,
)
}
}

pub trait DisplaySource {
Expand Down
2 changes: 1 addition & 1 deletion tools/parser/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "parser"
version = "0.3.22"
version = "0.3.23"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
4 changes: 3 additions & 1 deletion tools/parser/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -1028,16 +1028,18 @@ ClosuredValue: ClosuredValue = {
MLTuple<
(
ClosuredValueCatch*
Opt<"@">
("|" <Label*>)?
),
(ConstStart <Value> <ConstStop>),
> => {
let ((catchs, catch_labels), (value, labels)) = <>;
let ((catchs, catch_args, catch_labels), (value, labels)) = <>;
ClosuredValue::Uninit {
catch_values: catchs,
catch_labels: catch_labels.unwrap_or_default(),
value: value.into(),
labels,
catch_args,
}
},
}
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.38"
version = "0.1.39"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
Loading

0 comments on commit 3407690

Please sign in to comment.