From 3737172afc9831413817eece82eef28224722b0b Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Fri, 29 Mar 2024 12:48:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8F=AF=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=86=85=E5=BB=BA=E5=87=BD=E6=95=B0=E6=89=8B=E5=8A=A8=E5=BC=80?= =?UTF-8?q?=E5=90=AF=E7=9A=84match=E6=9C=AA=E5=91=BD=E4=B8=AD=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 稍微修改语法, 使do-while中可以包含if语句 为了语法的明确性, 我们不会在do-while或if中引入LogicLine, 尽管可以 --- Cargo.lock | 8 +++--- Cargo.toml | 2 +- examples/builtin_functions.mdtlbl | 1 + examples/control.mdtlbl | 1 + tools/parser/Cargo.toml | 2 +- tools/parser/src/parser.lalrpop | 2 +- tools/parser/tests/Cargo.toml | 2 +- tools/parser/tests/src/lib.rs | 14 ++++++++++ tools/syntax/Cargo.toml | 2 +- tools/syntax/src/builtins.rs | 7 +++++ tools/syntax/src/lib.rs | 43 ++++++++++++++++++++++--------- 11 files changed, 63 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6caa3d..8a1134b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,7 +301,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mindustry_logic_bang_lang" -version = "0.15.4" +version = "0.15.5" dependencies = [ "display_source", "logic_lint", @@ -347,7 +347,7 @@ dependencies = [ [[package]] name = "parser" -version = "0.3.6" +version = "0.3.7" dependencies = [ "lalrpop", "lalrpop-util", @@ -358,7 +358,7 @@ dependencies = [ [[package]] name = "parser-tests" -version = "0.1.17" +version = "0.1.18" dependencies = [ "parser", "syntax", @@ -535,7 +535,7 @@ dependencies = [ [[package]] name = "syntax" -version = "0.2.15" +version = "0.2.16" dependencies = [ "either", "tag_code", diff --git a/Cargo.toml b/Cargo.toml index ce44294..b9e7f98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.15.4" +version = "0.15.5" edition = "2021" authors = ["A4-Tacks "] diff --git a/examples/builtin_functions.mdtlbl b/examples/builtin_functions.mdtlbl index ed998e5..f141c30 100644 --- a/examples/builtin_functions.mdtlbl +++ b/examples/builtin_functions.mdtlbl @@ -28,6 +28,7 @@ * * `EvalNum[num]`: 尝试常量计算一个值, 失败则返回`__` * * `IsString[str]`: 返回给定量是否是一个字符串 * * `RefArg`: 返回指定下标的上层参数句柄, 一般再用Const解开 +* * `MissesMatch[enable]`: 当enable非0时, 将match失配打印日志功能开启 *# print Builtin.Type[x]; diff --git a/examples/control.mdtlbl b/examples/control.mdtlbl index 7bd6c73..361b352 100644 --- a/examples/control.mdtlbl +++ b/examples/control.mdtlbl @@ -143,3 +143,4 @@ print 1 jump 0 lessThan c d jump 0 lessThan a b *# +# 在0.15.5中, if也可以写进do_while了 diff --git a/tools/parser/Cargo.toml b/tools/parser/Cargo.toml index 61fe5a1..3a7dafb 100644 --- a/tools/parser/Cargo.toml +++ b/tools/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser" -version = "0.3.6" +version = "0.3.7" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/parser/src/parser.lalrpop b/tools/parser/src/parser.lalrpop index 8db0d1f..2d1f1c3 100644 --- a/tools/parser/src/parser.lalrpop +++ b/tools/parser/src/parser.lalrpop @@ -830,7 +830,7 @@ pub Control: LogicLine = { ControlWithOptionalEnd, } ControlBody: LogicLine = { - ControlWithoutOptionalEnd, + Control, Block, } ControlWithoutOptionalEnd: LogicLine = { diff --git a/tools/parser/tests/Cargo.toml b/tools/parser/tests/Cargo.toml index f6ee40b..d7787df 100644 --- a/tools/parser/tests/Cargo.toml +++ b/tools/parser/tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser-tests" -version = "0.1.17" +version = "0.1.18" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/parser/tests/src/lib.rs b/tools/parser/tests/src/lib.rs index 2fe2b04..7027407 100644 --- a/tools/parser/tests/src/lib.rs +++ b/tools/parser/tests/src/lib.rs @@ -265,6 +265,20 @@ fn control_test() { print 3; } "#).unwrap(); + + let _ = parse!(parser, r#" + do if c < d { + print 1; + } elif e < f { + print 2; + } else { + print 3; + } while a < b; + "#).unwrap(); + + let _ = parse!(parser, r#" + do print; while a < b; + "#).unwrap_err(); } #[test] diff --git a/tools/syntax/Cargo.toml b/tools/syntax/Cargo.toml index 8e94f8b..363d5e1 100644 --- a/tools/syntax/Cargo.toml +++ b/tools/syntax/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "syntax" -version = "0.2.15" +version = "0.2.16" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/syntax/src/builtins.rs b/tools/syntax/src/builtins.rs index 06a95fe..9a7337e 100644 --- a/tools/syntax/src/builtins.rs +++ b/tools/syntax/src/builtins.rs @@ -359,5 +359,12 @@ pub fn build_builtins() -> Vec { }) }) } + + fn misses_match:MissesMatch(meta) [v:enable] { + check_type!("var" Value::Var(enable) = enable.value() => { + meta.enable_misses_match_log_info = enable != "0"; + Ok("__".into()) + }) + } } } diff --git a/tools/syntax/src/lib.rs b/tools/syntax/src/lib.rs index 0bf3ffc..7d88a14 100644 --- a/tools/syntax/src/lib.rs +++ b/tools/syntax/src/lib.rs @@ -3,7 +3,7 @@ mod builtins; mod tests; use std::{ - borrow::Borrow, + borrow::{Borrow, Cow}, collections::{HashMap, HashSet}, convert::identity, fmt::{self, Debug, Display}, @@ -79,6 +79,17 @@ macro_rules! do_return { } }; } +macro_rules! csi { + (@ignore($($i:tt)*) $($t:tt)*) => ($($t)*); + ($fcode:expr $(, $code:expr)*; $($arg:tt)*) => { + format_args!( + concat!("\x1b[{}", $(csi!(@ignore($code) ";{}"), )* "m{}\x1b[0m"), + $fcode, + $($code,)* + format_args!($($arg)*), + ) + }; +} #[derive(Debug, PartialEq, Clone)] pub struct Error { @@ -2500,15 +2511,16 @@ pub struct Match { impl Compile for Match { fn compile(self, meta: &mut CompileMeta) { let args = self.args.into_taked_args_handle(meta); - let mut iter = self.cases.into_iter(); - loop { - let Some(case) = iter.next() else { break }; - let (pat, block) = case; + for (pat, block) in self.cases { if pat.do_pattern(&args, meta) { block.compile(meta); - break; + return; } } + if meta.enable_misses_match_log_info { + meta.log_info(format_args!("Misses match, [{}]", args.join(" "))); + meta.log_expand_stack(); + } } } impl Match { @@ -3009,6 +3021,7 @@ pub struct CompileMeta { /// 值绑定全局常量表, 只有值绑定在使用它 value_bind_global_consts: HashMap, last_builtin_exit_code: u8, + enable_misses_match_log_info: bool, } impl Debug for CompileMeta { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -3033,6 +3046,7 @@ impl Debug for CompileMeta { .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("enable_misses_match_log_info", &self.enable_misses_match_log_info) .field("..", &DotDot) .finish() } @@ -3064,6 +3078,7 @@ impl CompileMeta { value_binds: HashMap::new(), value_bind_global_consts: HashMap::new(), last_builtin_exit_code: 0, + enable_misses_match_log_info: false, }; let builtin = String::from("Builtin"); for builtin_func in build_builtins() { @@ -3506,20 +3521,24 @@ impl CompileMeta { } pub fn log_info(&mut self, s: impl std::fmt::Display) { - eprintln!("\x1b[1m[I] {}\x1b[0m", s.to_string() - .trim_end().replace('\n', "\n ")) + eprintln!("{}", csi!(1; "[I] {}", + s.to_string().trim_end().replace('\n', "\n "))) } pub fn log_err(&mut self, s: impl std::fmt::Display) { - eprintln!("\x1b[1;91m[E] {}\x1b[0m", s.to_string() - .trim_end().replace('\n', "\n ")) + eprintln!("{}", csi!(1, 91; "[E] {}", + s.to_string().trim_end().replace('\n', "\n "))) } - pub fn debug_expand_stack(&self) -> impl Iterator + '_ { + pub fn debug_expand_stack(&self) -> impl Iterator< + Item = Cow<'_, str> + > + '_ { self.const_expand_names().iter() .zip(&self.dexp_expand_binders) .map(|x| match x { - (name, Some(binder)) => format!("{name} ..{binder}"), + (name, Some(binder)) => { + format!("{name} ..{binder}").into() + }, (name, None) => name.into(), }) }