Skip to content

Commit

Permalink
添加gswitch的append忽略语法, 并改善一点点报错
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed May 8, 2024
1 parent 26a72f0 commit 0cd340a
Show file tree
Hide file tree
Showing 14 changed files with 102 additions and 34 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.16.3"
version = "0.16.4"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
2 changes: 1 addition & 1 deletion README-en_US.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ printflush message1
# Project Build
Building this project will be relatively slow due to the following reasons:
1. Compile using `rustc`, which is slightly slower compared to `gcc` and `clang`
2. Using the large syntax analysis framework 'lalrpop', which generates over 400000 lines of code and works together with 'rustc' to make compilation slower
2. Using the large syntax analysis framework 'lalrpop', which generates over 500000 lines of code and works together with 'rustc' to make compilation slower

You can first check the Releases to see if there is a built program,
and if it does not exist or cannot be used, try building it yourself
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ printflush message1
# 项目构建
构建这个项目将会比较慢, 原因如下:
1. 使用`rustc`进行编译, 而它略慢, 相对于`gcc` `clang`
2. 使用了大型语法分析框架`lalrpop`, 它会生成四十多万行代码, 再叠加上`rustc`编译更慢
2. 使用了大型语法分析框架`lalrpop`, 它会生成五十多万行代码, 再叠加上`rustc`编译更慢

你可以先翻一翻Releases, 看一看有没有已构建的程序, 如果没有或无法使用再尝试自己构建.

Expand Down
3 changes: 3 additions & 0 deletions examples/gswitch.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
* 将仅在成立时执行这个case.
* 当然不设计为为同一个case中每个匹配使用不同的守卫支持, 也是类似上面的原因.
* 实在要使用也可以使用类似上面的解决方法
*
* 在0.16.4新增了一个便捷语法, 在case后面加上星号可以忽略append,
* 这可以既享受append的便利, 又为一些特化场景做优化
*#

# 一个例子
Expand Down
5 changes: 4 additions & 1 deletion syntax/vim/mdtlbl.vim
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ syn case match

" 一些关键字 {{{1
syn keyword mdtlblKeyword
\ while gwhile do skip goto if elif else switch gswitch case break continue
\ while gwhile do skip goto if elif else switch gswitch break continue
\ const take setres select match
\ inline
\ op set noop print
syn keyword mdtlblKeyword case nextgroup=mdtlblStar skipwhite
syn match mdtlblStar /\*/ contained

syn keyword mdtlblOpFunKeyword
\ add sub mul div idiv mod pow
Expand Down Expand Up @@ -133,6 +135,7 @@ setlocal indentkeys+==:

" END And Color Links {{{1
hi def link mdtlblKeyword Keyword
hi def link mdtlblStar Keyword
hi def link mdtlblOpFunKeyword Operator
hi def link mdtlblCmpTreeOper Operator
hi def link mdtlblComment Comment
Expand Down
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.13"
version = "0.3.14"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
18 changes: 14 additions & 4 deletions tools/display_source/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,13 +635,17 @@ impl DisplaySource for ConstMatch {
}
impl DisplaySource for GSwitchCase {
fn display_source(&self, meta: &mut DisplaySourceMeta) {
match self {
&Self::Catch {
match *self {
Self::Catch {
skip_extra,
underflow,
missed,
overflow,
ref to,
} => {
if skip_extra {
meta.push("*");
}
meta.add_space();
if underflow {
meta.push("<");
Expand All @@ -657,7 +661,14 @@ impl DisplaySource for GSwitchCase {
key.display_source(meta);
}
},
Self::Normal { ids, guard } => {
Self::Normal {
skip_extra,
ref ids,
ref guard
} => {
if skip_extra {
meta.push("*");
}
if !ids.as_normal().map(Vec::is_empty).unwrap_or_default() {
meta.add_space();
ids.display_source(meta);
Expand All @@ -682,7 +693,6 @@ impl DisplaySource for GSwitch {
meta.add_lf();
meta.do_block(|meta| {
self.extra.display_source(meta);
meta.add_lf();
});
for (case, expand) in &self.cases {
meta.push("case");
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.10"
version = "0.3.11"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
18 changes: 8 additions & 10 deletions tools/parser/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -915,16 +915,14 @@ ControlBody: LogicLine = {
Block,
}
GSwitchCase: GSwitchCase = {
<ids:Args?> <guard:("if" <JumpCmp>)?> => {
GSwitchCase::Normal { ids: ids.unwrap_or_default(), guard }
},
"<" <to:ConstKey?> => GSwitchCase::Catch { underflow: true, missed: false, overflow: false, to },
"!" <to:ConstKey?> => GSwitchCase::Catch { underflow: false, missed: true, overflow: false, to },
">" <to:ConstKey?> => GSwitchCase::Catch { underflow: false, missed: false, overflow: true, to },
"<" "!" <to:ConstKey?> => GSwitchCase::Catch { underflow: true, missed: true, overflow: false, to },
"!" ">" <to:ConstKey?> => GSwitchCase::Catch { underflow: false, missed: true, overflow: true, to },
"<" ">" <to:ConstKey?> => GSwitchCase::Catch { underflow: true, missed: false, overflow: true, to },
"<" "!" ">" <to:ConstKey?> => GSwitchCase::Catch { underflow: true, missed: true, overflow: true, to },
<skip_extra:Opt<"*">> <ids:Args?> <guard:("if" <JumpCmp>)?> => GSwitchCase::Normal { skip_extra, ids: ids.unwrap_or_default(), guard },
<skip_extra:Opt<"*">> "<" <to:ConstKey?> => GSwitchCase::Catch { skip_extra, underflow: true, missed: false, overflow: false, to },
<skip_extra:Opt<"*">> "!" <to:ConstKey?> => GSwitchCase::Catch { skip_extra, underflow: false, missed: true, overflow: false, to },
<skip_extra:Opt<"*">> ">" <to:ConstKey?> => GSwitchCase::Catch { skip_extra, underflow: false, missed: false, overflow: true, to },
<skip_extra:Opt<"*">> "<" "!" <to:ConstKey?> => GSwitchCase::Catch { skip_extra, underflow: true, missed: true, overflow: false, to },
<skip_extra:Opt<"*">> "!" ">" <to:ConstKey?> => GSwitchCase::Catch { skip_extra, underflow: false, missed: true, overflow: true, to },
<skip_extra:Opt<"*">> "<" ">" <to:ConstKey?> => GSwitchCase::Catch { skip_extra, underflow: true, missed: false, overflow: true, to },
<skip_extra:Opt<"*">> "<" "!" ">" <to:ConstKey?> => GSwitchCase::Catch { skip_extra, underflow: true, missed: true, overflow: true, to },
}
ControlWithoutOptionalEnd: LogicLine = {
"goto" <Label> <AlwaysJumpCmp> LEnd => {
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.22"
version = "0.1.23"
edition = "2021"

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

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
gswitch x {
break;
case 1 2: print x;
case*3: print end;
}
end;
"#).unwrap()).compile().unwrap(),
vec![
r#"op add @counter @counter x"#,
r#"jump 8 always 0 0"#,
r#"jump 5 always 0 0"#,
r#"jump 5 always 0 0"#,
r#"jump 7 always 0 0"#,
r#"print x"#,
r#"jump 8 always 0 0"#,
r#"print end"#,
r#"end"#,
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
gswitch x {
break;
case*1 2: print x;
case 3: print end;
}
end;
"#).unwrap()).compile().unwrap(),
vec![
r#"op add @counter @counter x"#,
r#"jump 8 always 0 0"#,
r#"jump 5 always 0 0"#,
r#"jump 5 always 0 0"#,
r#"jump 6 always 0 0"#,
r#"print x"#,
r#"print end"#,
r#"jump 8 always 0 0"#,
r#"end"#,
],
);
}
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.22"
version = "0.2.23"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
24 changes: 17 additions & 7 deletions tools/syntax/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3114,12 +3114,14 @@ impl ConstMatchPatAtom {
#[derive(Debug, PartialEq, Clone)]
pub enum GSwitchCase {
Catch {
skip_extra: bool,
underflow: bool,
missed: bool,
overflow: bool,
to: Option<ConstKey>,
},
Normal {
skip_extra: bool,
/// 如果为空, 那么则继承上一个的编号
ids: Args,
guard: Option<CmpTree>,
Expand Down Expand Up @@ -3177,12 +3179,12 @@ impl GSwitch {
.map(|x| match x.0.round() {
n if n < 0. => {
meta.log_expand_stack::<true>();
err!("小于0的gswitch id");
err!("小于0的gswitch id: {}", n);
exit(4);
},
n if n >= GSwitch::MAX_CONST_ID as f64 => {
meta.log_expand_stack::<true>();
err!("过大的gswitch id");
err!("过大的gswitch id: {}", n);
exit(4);
},
n => n as usize,
Expand Down Expand Up @@ -3236,8 +3238,13 @@ impl Compile for GSwitch {
let [mut prev_case, mut max_case] = [-1isize; 2];
let mut case_lines = vec![];
for (case, code) in self.cases {
let GSC::Normal { mut ids, guard } = case else {
let GSC::Normal {
skip_extra,
mut ids,
guard
} = case else {
let GSwitchCase::Catch {
skip_extra,
underflow,
missed,
overflow,
Expand All @@ -3259,7 +3266,9 @@ impl Compile for GSwitch {
.chain(to.into_iter()
.map(|k| Take(k, val_h.clone().into()).into()))
.chain(once(code.into()))
.chain(self.extra.0.iter().cloned())
.chain((!skip_extra)
.then(|| self.extra.0.iter().cloned())
.into_iter().flatten())
.collect()
));
continue;
Expand All @@ -3281,11 +3290,12 @@ impl Compile for GSwitch {
prev_case = id.try_into().unwrap();
max_case = max_case.max(prev_case);
});
case_lines.push(LogicLine::Expand(vec![
let mut lines = vec![
LogicLine::Label(lab),
code.into(),
self.extra.clone().into(),
].into()));
];
if !skip_extra { lines.push(self.extra.clone().into()) }
case_lines.push(LogicLine::Expand(lines.into()));
}
let mut default_missed_catch = false;
for to_case in &mut *head.1 {
Expand Down

0 comments on commit 0cd340a

Please sign in to comment.