Skip to content

Commit

Permalink
修复几处不应有的const追溯
Browse files Browse the repository at this point in the history
- ArgsRepeat 的二次追溯
  • Loading branch information
A4-Tacks committed Jan 16, 2024
1 parent 0305889 commit cfe03cd
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 52 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.10"
version = "0.14.11"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
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.6"
version = "0.1.7"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
62 changes: 62 additions & 0 deletions tools/parser/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4411,6 +4411,68 @@ fn match_test() {
"print 4",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
# 关于二次追溯
{
const X = 2;
const Y = `X`;
const F = (
print _0 @;
);
take F[Y];
}
{
const X = 2;
const F = (
const Y = `X`;
print _0 @;
);
take F[Y];
}
"#).unwrap()).compile().unwrap(),
vec![
"print X",
"print X",
"print Y",
"print Y",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
# 关于二次追溯
{
const X = 2;
const Y = `X`;
const F = (
print _0;
match @ {
V { print V; }
}
);
take F[Y];
}
{
const X = 2;
const F = (
const Y = `X`;
print _0;
match @ {
V { print V; }
}
);
take F[Y];
}
"#).unwrap()).compile().unwrap(),
vec![
"print X",
"print X",
"print Y",
"print Y",
],
);
}

#[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.7"
version = "0.2.8"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
93 changes: 47 additions & 46 deletions tools/syntax/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,13 @@ pub const FALSE_VAR: &str = "false";
pub const ZERO_VAR: &str = "0";
pub const UNUSED_VAR: &str = "0";

pub trait TakeHandle {
pub trait TakeHandle: Sized {
/// 编译依赖并返回句柄
fn take_handle(self, meta: &mut CompileMeta) -> Var;
/// 编译并拿取句柄, 但是是在被const的值的情况下
fn take_handle_with_consted(self, meta: &mut CompileMeta) -> Var {
self.take_handle(meta)
}
}

impl TakeHandle for Var {
Expand All @@ -143,6 +147,9 @@ impl TakeHandle for Var {
self
}
}
fn take_handle_with_consted(self, _meta: &mut CompileMeta) -> Var {
self
}
}

#[derive(Debug, PartialEq, Clone)]
Expand Down Expand Up @@ -178,17 +185,6 @@ impl Value {
None
}
}

/// 编译并拿取句柄, 但是是在被const的值的情况下
pub fn take_handle_with_consted(self, meta: &mut CompileMeta) -> Var {
if let Some(var) = self.try_eval_const_num_to_var(meta) {
return var;
}
match self {
Self::Var(var) => var,
other => other.take_handle(meta),
}
}
}
impl TakeHandle for Value {
fn take_handle(self, meta: &mut CompileMeta) -> Var {
Expand Down Expand Up @@ -218,6 +214,18 @@ impl TakeHandle for Value {
Self::BuiltinFunc(func) => func.call(meta),
}
}
fn take_handle_with_consted(self, meta: &mut CompileMeta) -> Var {
if let Some(var) = self.try_eval_const_num_to_var(meta) {
return var;
}
match self {
Self::Var(var) => var,
Self::ReprVar(var) => {
panic!("Fail const reprvar {}, meta: {:#?}", var, meta);
},
other => other.take_handle(meta),
}
}
}
impl Default for Value {
/// 默认的占位值, 它是无副作用的, 不会被常量展开
Expand Down Expand Up @@ -2079,33 +2087,13 @@ pub enum Args {
Expanded(Vec<Value>, Vec<Value>),
}
impl Args {
/// 获取参数引用
pub fn get_value_args<'a>(&'a self, meta: &'a CompileMeta) -> Vec<&'a Value> {
match self {
Self::Normal(args) => args.iter().collect(),
Self::Expanded(left, right) => {
left.iter()
.chain(meta.get_env_args().iter()
.map(|var| meta.get_const_value(var)
.unwrap()
.value()))
.chain(right)
.collect()
},
}
}

/// 获取值
pub fn into_value_args(self, meta: &CompileMeta) -> Vec<Value> {
match self {
Self::Normal(args) => args,
Self::Expanded(left, right) => {
left.into_iter()
.chain(meta.get_env_args().iter()
.map(|var| meta.get_const_value(var)
.unwrap()
.value()
.clone()))
.chain(meta.get_env_args().iter().cloned().map(Into::into))
.chain(right)
.collect()
},
Expand All @@ -2115,7 +2103,7 @@ impl Args {
/// 获取句柄, 但是假定环境中的args已经const过了
///
/// 这不包括左部分和右部分
pub fn into_args_handle(self, meta: &mut CompileMeta) -> Vec<Var> {
pub fn into_taked_args_handle(self, meta: &mut CompileMeta) -> Vec<Var> {
match self {
Args::Normal(args) => {
args.into_iter()
Expand Down Expand Up @@ -2166,7 +2154,7 @@ impl Args {
}
}

pub fn into_normal(self) -> Result<Vec<Value>, Self> {
pub fn try_into_normal(self) -> Result<Vec<Value>, Self> {
match self {
Self::Normal(args) => Ok(args),
this => Err(this),
Expand Down Expand Up @@ -2219,12 +2207,12 @@ impl ArgsRepeat {
}
impl Compile for ArgsRepeat {
fn compile(self, meta: &mut CompileMeta) {
let chunks: Vec<Vec<Value>> = meta.get_env_args().chunks(self.count)
let chunks: Vec<Vec<Value>> = meta.get_env_args()
.chunks(self.count)
.map(|chunks| chunks.iter()
.map(|var| meta.get_const_value(var)
.unwrap()
.value())
.cloned().collect())
.cloned()
.map(Into::into)
.collect())
.collect();
for args in chunks {
let args = Vec::from_iter(args.iter().cloned());
Expand All @@ -2243,7 +2231,7 @@ pub struct Match {
}
impl Compile for Match {
fn compile(self, meta: &mut CompileMeta) {
let args = self.args.into_args_handle(meta);
let args = self.args.into_taked_args_handle(meta);
let mut iter = self.cases.into_iter();
loop {
let Some(case) = iter.next() else { break };
Expand Down Expand Up @@ -2405,21 +2393,32 @@ impl Compile for LogicLine {
meta.push(data)
},
Self::Other(args) => {
let handles: Vec<String> = args.into_args_handle(meta);
let handles: Vec<String> = args.into_taked_args_handle(meta);
meta.push(TagLine::Line(handles.join(" ").into()));
},
Self::SetResultHandle(value) => {
let new_dexp_handle = value.take_handle(meta);
meta.set_dexp_handle(new_dexp_handle);
},
Self::SetArgs(args) => {
fn iarg(i: usize) -> Var {
format!("_{i}")
}
let expand_args = args.into_value_args(meta);
meta.set_env_args(expand_args.clone());
let len = expand_args.len();
let mut f = |r#const: Const| r#const.compile(meta);
for (i, value) in expand_args.into_iter().enumerate() {
let name = format!("_{}", i);
f(Const(name.into(), value, Vec::with_capacity(0)).into());
let iter = expand_args.into_iter().enumerate();
for (i, value) in iter {
f(Const(
iarg(i).into(),
value.into(),
Vec::with_capacity(0),
).into());
}
meta.set_env_args((0..len)
.map(iarg)
.map(Into::into)
.collect());
},
Self::Select(select) => select.compile(meta),
Self::Expand(expand) => expand.compile(meta),
Expand Down Expand Up @@ -3141,6 +3140,8 @@ impl CompileMeta {
}

/// 设置最内层args, 返回旧值
///
/// 这将进行const的追溯
pub fn set_env_args(&mut self, expand_args: Vec<Value>) -> Option<Vec<Var>> {
let vars: Vec<Var> = expand_args.into_iter()
.map(|value| {
Expand Down

0 comments on commit cfe03cd

Please sign in to comment.