From 39394862ea76831f35bb864aa7d5cfe2ed75eae2 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 3 Sep 2023 13:38:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86select=E5=9C=A80?= =?UTF-8?q?=E8=A1=8C=E5=92=8C1=E8=A1=8C=E4=B8=8B=E7=9A=84=E8=A1=8C?= =?UTF-8?q?=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/syntax.rs | 100 +++++++++++++++++++++++++++++++++-------- src/syntax_def.lalrpop | 2 +- 4 files changed, 85 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec9ff4c..f20db23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,7 +265,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mindustry_logic_bang_lang" -version = "0.11.3" +version = "0.11.4" dependencies = [ "display_source", "lalrpop", diff --git a/Cargo.toml b/Cargo.toml index ce54785..cc5b10a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.11.3" +version = "0.11.4" edition = "2021" authors = ["A4-Tacks "] diff --git a/src/syntax.rs b/src/syntax.rs index d225fb8..47cd9df 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -1472,21 +1472,39 @@ impl Compile for Select { ) .count() }).collect(); - let max_len = lens.iter().copied().max().unwrap(); + let max_len = lens.iter().copied().max().unwrap_or_default(); + + let counter = Value::ReprVar(COUNTER.into()); // build head - let tmp_var = meta.get_tmp_var(); - let mut head = Op::Mul( - tmp_var.clone().into(), - self.0, - max_len.to_string().into() - ).compile_take(meta); - let head_1 = Op::Add( - COUNTER.into(), - COUNTER.into(), - tmp_var.into() - ).compile_take(meta); - head.extend(head_1); + let head = match max_len { + 0 => { // no op + Take("__".into(), self.0).compile_take(meta) + }, + 1 => { // no mul + Op::Add( + counter.clone(), + counter, + self.0 + ).compile_take(meta) + }, + // normal + _ => { + let tmp_var = meta.get_tmp_var(); + let mut head = Op::Mul( + tmp_var.clone().into(), + self.0, + Value::ReprVar(max_len.to_string()) + ).compile_take(meta); + let head_1 = Op::Add( + counter.clone(), + counter, + tmp_var.into() + ).compile_take(meta); + head.extend(head_1); + head + } + }; // 填补不够长的`case` for (len, case) in zip(lens, &mut cases) { @@ -2710,13 +2728,13 @@ mod tests { Select( "2".into(), Expand(vec![ - LogicLine::NoOp, + LogicLine::Ignore, Expand(vec![LogicLine::Other(vec![Value::ReprVar("print".into()), "1".into()])]).into(), Expand(vec![ LogicLine::Other(vec![Value::ReprVar("print".into()), "2".into()]), LogicLine::Other(vec![Value::ReprVar("print".into()), "4".into()]), ]).into(), - LogicLine::NoOp, + LogicLine::Ignore, Expand(vec![ LogicLine::Other(vec![Value::ReprVar("print".into()), "2".into()]), LogicLine::Other(vec![Value::ReprVar("print".into()), "4".into()]), @@ -3861,9 +3879,7 @@ mod tests { let logic_lines = CompileMeta::new().compile(parse!(parser, r#" select 1 { print 0; - { - print 1 " is one!"; - } + print 1 " is one!"; print 2; } "#).unwrap()).compile().unwrap(); @@ -3878,6 +3894,32 @@ mod tests { "noop", ]); + let logic_lines = CompileMeta::new().compile(parse!(parser, r#" + select x { + print 0; + print 1; + print 2; + } + "#).unwrap()).compile().unwrap(); + assert_eq!(logic_lines, vec![ + "op add @counter @counter x", + "print 0", + "print 1", + "print 2", + ]); + + let logic_lines = CompileMeta::new().compile(parse!(parser, r#" + select (y: op $ x + 2;) {} + "#).unwrap()).compile().unwrap(); + assert_eq!(logic_lines, vec![ + "op add y x 2", + ]); + + let logic_lines = CompileMeta::new().compile(parse!(parser, r#" + select x {} + "#).unwrap()).compile().unwrap(); + assert_eq!(logic_lines, Vec::<&str>::new()); + } #[test] @@ -4174,6 +4216,28 @@ mod tests { } } "#).unwrap()); + + let logic_lines = CompileMeta::new().compile(parse!(parser, r#" + switch (op $ x + 2;) { + case !: + stop; + case 1: + case 3: + } + "#).unwrap()).compile().unwrap(); + assert_eq!(logic_lines, CompileMeta::new().compile(parse!(parser, r#" + take tmp = (op $ x + 2;); + skip _ { + :mis + stop; + } + select tmp { + goto :mis _; + noop; + goto :mis _; + noop; + } + "#).unwrap()).compile().unwrap()); } #[test] diff --git a/src/syntax_def.lalrpop b/src/syntax_def.lalrpop index 1607285..5835b59 100644 --- a/src/syntax_def.lalrpop +++ b/src/syntax_def.lalrpop @@ -574,7 +574,7 @@ pub Control: LogicLine = { let mut fill_line = append .as_ref() .map(|line| Expand(vec![line.clone()]).into()) - .unwrap_or(LogicLine::NoOp); + .unwrap_or(LogicLine::Ignore); // 用于添加到头部的捕获块 let mut catch_lines = Vec::new();