Skip to content

Commit

Permalink
添加max和min的自运算
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Sep 20, 2024
1 parent a6d8dc3 commit 974bd6b
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 23 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.17.3"
version = "0.17.4"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
1 change: 1 addition & 0 deletions examples/op_expr.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ a, b, c = 1 + 2 * 3;

#**
* 在0.14.17版本, 可以对常见的运算使用自运算格式, 这会简化一些代码
* 这些运算包括+-*///%等运算, 同时也支持min和max
*#
x += n*2;

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.20"
version = "0.3.21"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
33 changes: 18 additions & 15 deletions tools/parser/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use ::syntax::{
ClosuredValueMethod,
op_expr_build_op,
op_expr_build_results,
op_expr_tools::top_assign_oper,
op_expr_tools::TOP_ASSIGN_OPER,
make_assign_oper,
OpExprInfo,
OpExprAOperFun,
JumpCmp,
Expand Down Expand Up @@ -596,20 +597,22 @@ OpExprDExp: DExp = METuple<MakeDExpBody<OpExprBodySetR>>;
OpExprToValue: Value = MTuple<("*" <OpExprBodyToValue>)>;

OpExprAssignOper: OpExprAOperFun = {
"+=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Add (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"-=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Sub (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"*=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Mul (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"/=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Div (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"//=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Idiv(tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"%=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Mod (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"**=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Pow (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"&&=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Land(tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"<<=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Shl (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
">>=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Shr (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"|=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Or (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"&=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::And (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"^=" => { |meta, res, v| { let tres = meta.get_tmp_var(); Expand(vec![Take(tres.clone().into(), res).into(), Op::Xor (tres.clone().into(), tres.into(), v.into_value(meta)).into()]).into() } },
"=" => { top_assign_oper },
"+=" => { make_assign_oper!(Op::Add ) },
"-=" => { make_assign_oper!(Op::Sub ) },
"*=" => { make_assign_oper!(Op::Mul ) },
"/=" => { make_assign_oper!(Op::Div ) },
"//=" => { make_assign_oper!(Op::Idiv ) },
"%=" => { make_assign_oper!(Op::Mod ) },
"**=" => { make_assign_oper!(Op::Pow ) },
"&&=" => { make_assign_oper!(Op::Land ) },
"<<=" => { make_assign_oper!(Op::Shl ) },
">>=" => { make_assign_oper!(Op::Shr ) },
"|=" => { make_assign_oper!(Op::Or ) },
"&=" => { make_assign_oper!(Op::And ) },
"^=" => { make_assign_oper!(Op::Xor ) },
"max" "=" => { make_assign_oper!(Op::Max ) },
"min" "=" => { make_assign_oper!(Op::Min ) },
"=" => { TOP_ASSIGN_OPER },
}

// 多个接收者的OpExpr, 例如`a, b, c = 1;`
Expand Down
49 changes: 49 additions & 0 deletions tools/parser/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2538,6 +2538,55 @@ fn op_expr_test() {
"#).unwrap(),
);

assert_eq!(
parse!(parser, r#"
a, b min= 2, 3;
"#).unwrap(),
parse!(parser, r#"
{
a min= 2;
b min= 3;
}
"#).unwrap(),
);

assert_eq!(
parse!(parser, r#"
a, b max= 2, 3;
"#).unwrap(),
parse!(parser, r#"
{
a max= 2;
b max= 3;
}
"#).unwrap(),
);

assert_eq!(
parse!(parser, r#"
x min= 2;
"#).unwrap(),
parse!(parser, r#"
{
take ___0 = x;
op ___0 min ___0 2;
}
"#).unwrap(),
);

assert_eq!(
parse!(parser, r#"
a, b min= 2;
"#).unwrap(),
parse!(parser, r#"
{
take ___0 = 2;
{take ___1 = a; op ___1 min ___1 ___0;}
{take ___2 = b; op ___2 min ___2 ___0;}
}
"#).unwrap(),
);

assert_eq!(
parse!(parser, r#"
x = ++i;
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.40"
version = "0.2.41"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
24 changes: 22 additions & 2 deletions tools/syntax/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4656,7 +4656,7 @@ pub fn op_expr_build_results(
f(meta, result, value)
},
(len, 1)
if f as *const () == op_expr_tools::top_assign_oper as *const () => {
if f as *const () == op_expr_tools::TOP_ASSIGN_OPER as *const () => {
let mut lines = Vec::with_capacity(len + 1);
let value = values.pop().unwrap();
let mut results = results.into_iter();
Expand Down Expand Up @@ -4704,8 +4704,28 @@ pub fn op_expr_build_results(
}
}

#[macro_export]
macro_rules! make_assign_oper {
($oper:path) => {
|meta, res, v| {
let tres = meta.get_tmp_var();
$crate::Expand(::std::vec![
$crate::Take(tres.clone().into(), res).into(),
$oper(
tres.clone().into(),
tres.into(),
v.into_value(meta),
).into(),
]).into()
}
};
}

pub mod op_expr_tools {
use super::{Meta, Value, OpExprInfo, LogicLine};
use super::{LogicLine, Meta, OpExprInfo, Value};

pub const TOP_ASSIGN_OPER: fn(&mut Meta, Value, OpExprInfo) -> LogicLine
= top_assign_oper;

pub fn top_assign_oper(
meta: &mut Meta,
Expand Down

0 comments on commit 974bd6b

Please sign in to comment.