Skip to content

Commit

Permalink
为op-expr添加如i++ ++i等操作
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Jul 6, 2024
1 parent 1742536 commit be20d27
Show file tree
Hide file tree
Showing 9 changed files with 354 additions and 51 deletions.
8 changes: 4 additions & 4 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.15"
version = "0.16.16"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
104 changes: 77 additions & 27 deletions examples/op_expr.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,36 @@
* 以下为各种运算符的优先级与结合性:
* | 符号 | 实际运算(op) | 优先级 | 结合性 |
* | ---------- | ------------ | ------ | ------ |
* | `a ** b` | `a ** b` | -1 | RL |
* | `! x` | `x != false` | -2 | R |
* | `- x` | `0 - x` | -2 | R |
* | `~ x` | `~ x` | -2 | R |
* | `a * b` | `a * b` | -3 | LR |
* | `a / b` | `a / b` | -3 | LR |
* | `a % b` | `a % b` | -3 | LR |
* | `a // b` | `a // b` | -3 | LR |
* | `a + b` | `a + b` | -4 | LR |
* | `a - b` | `a - b` | -4 | LR |
* | `a << b` | `a << b` | -5 | LR |
* | `a >> b` | `a >> b` | -5 | LR |
* | `a & b` | `a & b` | -6 | LR |
* | `a ^ b` | `a ^ b` | -7 | LR |
* | `a | b` | `a | b` | -8 | LR |
* | `a < b` | `a < b` | -9 | - |
* | `a > b` | `a > b` | -9 | - |
* | `a <= b` | `a <= b` | -9 | - |
* | `a >= b` | `a >= b` | -9 | - |
* | `a == b` | `a == b` | -10 | - |
* | `a != b` | `a != b` | -10 | - |
* | `a === b` | `a === b` | -10 | - |
* | `a !== b` | `a !== b` | -10 | - |
* | `a && b` | `a && b` | -11 | LR |
* | `a || b` | `a + b` | -12 | LR |
* | `if c?a:b` | ... | -13 | LR |
* | `++ a` | `++ a` | -1 | - |
* | `-- a` | `-- a` | -1 | - |
* | `a ++` | `a ++` | -1 | - |
* | `a --` | `a --` | -1 | - |
* | `a ** b` | `a ** b` | -2 | RL |
* | `! x` | `x != false` | -3 | R |
* | `- x` | `0 - x` | -3 | R |
* | `~ x` | `~ x` | -3 | R |
* | `a * b` | `a * b` | -4 | LR |
* | `a / b` | `a / b` | -4 | LR |
* | `a % b` | `a % b` | -4 | LR |
* | `a // b` | `a // b` | -4 | LR |
* | `a + b` | `a + b` | -5 | LR |
* | `a - b` | `a - b` | -5 | LR |
* | `a << b` | `a << b` | -6 | LR |
* | `a >> b` | `a >> b` | -6 | LR |
* | `a & b` | `a & b` | -7 | LR |
* | `a ^ b` | `a ^ b` | -8 | LR |
* | `a | b` | `a | b` | -9 | LR |
* | `a < b` | `a < b` | -10 | - |
* | `a > b` | `a > b` | -10 | - |
* | `a <= b` | `a <= b` | -10 | - |
* | `a >= b` | `a >= b` | -10 | - |
* | `a == b` | `a == b` | -11 | - |
* | `a != b` | `a != b` | -11 | - |
* | `a === b` | `a === b` | -11 | - |
* | `a !== b` | `a !== b` | -11 | - |
* | `a && b` | `a && b` | -12 | LR |
* | `a || b` | `a + b` | -13 | LR |
* | `if c?a:b` | ... | -14 | LR |
*
* 结合性的`LR`指左结合 比如`a+b+c`结合为`(a+b)+c`
* 而结合性为`-`指不发生结合, 将需要添加括号
Expand Down Expand Up @@ -170,7 +174,7 @@ x += n*2;


#**
* 在0.16.15版本, 这些自运算可以使用顶层赋值可用的操作了,
* 在0.16.15版本, 这些顶层自运算可以使用顶层赋值可用的操作了,
* 例如
*#
a, b += c + d;
Expand All @@ -183,3 +187,49 @@ op add b b __0
op add x x w
op add y y h
*#


#**
* 在0.16.16版本添加了单元自运算, 熟悉的++ --终于登场了
*#

j = i++;
k = ++i;
#* >>>
set j i
op add i i 1
op add i i 1
set k i
*#

# 同时还有一个扩展用法, 因为如`x+i++`这种情况`i++`被展开为值而非行,
# 则可能产生不希望的set, 所以可以使用扩展语法将外层操作挪到内层去
a = x + i++;
#* >>>
set __0 i
op add i i 1
op add a x __0
*#
b = i++(x + _);
#* >>>
op add b x i
op add i i 1
*#
# 可以看到, 使用这种方式使`i++`操作又回到了顶层, 从而被展开成行, 保证了性能
# 这个问题在if else也有类似例子.
# `_`是占位表达式, 它会构建时被替换为外层的`i++`中i被take的句柄
# `i++(...)`中的`(...)`接受正常的op-expr, 然后会将其展开成行,
# 返回句柄视外层的`i++`而定, 如果外层不是展开成行, 那么它会直接赋给`$`

# 还有一个单独的简单用法, 比如
i++; j--;
#* A >>>
{
take ___0 = i;
op ___0 ___0 + `1`;
}
{
take ___1 = j;
op ___1 ___1 - `1`;
}
*#
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.15"
version = "0.3.16"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
66 changes: 59 additions & 7 deletions tools/parser/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ MakeDExpBody<T>: DExp = {
"`" <var:Var> "`" ":" <value:T>
=> DExp::new_notake(var, value.into()),
}
#[inline]
Boxed<T>: Box<T> = T => Box::new(<>);

CtrlBreakStart: () = () => meta.add_control_break_level(None);
CtrlContinueStart: () = () => meta.add_control_continue_level(None);
Expand Down Expand Up @@ -160,7 +162,7 @@ NonConstRangeValue: Value = {
"$" => ResultHandle,
<value:NonConstRangeValue> <args:MList<Args?>> => {
// QuickDExpTake
DExp::new("__".into(), vec![
DExp::new(meta.unnamed_var(), vec![
LogicLine::SetArgs(args.unwrap_or_default()),
LogicLine::SetResultHandle(value),
].into()).into()
Expand All @@ -183,7 +185,7 @@ NonConstRangeValue: Value = {
},
<value:NonConstRangeValue> "->" <args:MList<Args?>> => {
// Refed QuickDExpTake
let value = DExp::new("__".into(), vec![
let value = DExp::new(meta.unnamed_var(), vec![
LogicLine::SetArgs(args.unwrap_or_default()),
LogicLine::SetResultHandle(value),
].into()).into();
Expand All @@ -202,7 +204,7 @@ pub Value: Value = {
"const" ConstStart <value:Or<ValueDExp, ("!" <Value>)>> <labels:ConstStop> => {
let tmp_name = meta.get_tmp_var();
let dexp_const = Const(tmp_name.clone().into(), value.into(), labels);
DExp::new("__".into(), vec![
DExp::new(meta.unnamed_var(), vec![
dexp_const.into(),
LogicLine::SetResultHandle(tmp_name.into()),
].into()).into()
Expand Down Expand Up @@ -416,7 +418,7 @@ ConstMatchPatAtom: ConstMatchPatAtom = {
ConstMatchPatAtom::new_guard(
dotake,
name.unwrap_or_default(),
DExp::new("__".into(), vec![
DExp::new(meta.unnamed_var(), vec![
LogicLine::from(Match::new(
Args::GLOB_ONLY,
vec![
Expand Down Expand Up @@ -559,6 +561,7 @@ OpExpr: LogicLine = {
results.reverse();
op_expr_build_results(meta, results, values, oper)
},
<OpExprTopSelfOps> LEnd,
}
#[inline]
OpExprBodySetR: Expand = OpExprBody => {
Expand Down Expand Up @@ -813,8 +816,57 @@ OpExprCallOp: OpExprInfo = {

OpExprAtom: OpExprInfo = {
Value => OpExprInfo::Value(<>),
OpExprValueSelfOps,
MTuple<OpExprBody>,
OpExprCallOp,
"_" => OpExprInfo::Ref(meta.op_expr_ref()),
}
OpExprTopSelfOps: LogicLine = {
<Value> "++" => {
let tmp = meta.get_tmp_var();
Expand(vec![
Take(tmp.clone().into(), <>).into(),
Op::Add(tmp.clone().into(), tmp.into(), ReprVar("1".into())).into(),
]).into()
},
<Value> "--" => {
let tmp = meta.get_tmp_var();
Expand(vec![
Take(tmp.clone().into(), <>).into(),
Op::Sub(tmp.clone().into(), tmp.into(), ReprVar("1".into())).into(),
]).into()
},
}
OpExprSelfOpsSuf<O>: () = O => {
OpExprInfo::add_suf_selfop_handle_to_meta(meta);
};
OpExprValueSelfOps: OpExprInfo = {
"++" <Value> => {
OpExprInfo::Value(DExp::new(meta.unnamed_var(), vec![
LogicLine::SetResultHandle(<>),
Op::Add(ResultHandle, ResultHandle, ReprVar("1".into())).into(),
].into()).into())
},
"--" <Value> => {
OpExprInfo::Value(DExp::new(meta.unnamed_var(), vec![
LogicLine::SetResultHandle(<>),
Op::Sub(ResultHandle, ResultHandle, ReprVar("1".into())).into(),
].into()).into())
},
<Value> OpExprSelfOpsSuf<"++"> <MTuple<Boxed<OpExprBody>>?> => {
OpExprInfo::new_suf_selfop(
meta,
Op::Add(ResultHandle, ResultHandle, ReprVar("1".into())),
<>,
)
},
<Value> OpExprSelfOpsSuf<"--"> <MTuple<Boxed<OpExprBody>>?> => {
OpExprInfo::new_suf_selfop(
meta,
Op::Sub(ResultHandle, ResultHandle, ReprVar("1".into())),
<>,
)
},
}

// 开始一个const, 开启了必须负责清理
Expand Down Expand Up @@ -842,7 +894,7 @@ pub BuiltinCommand: LogicLine = {

Take::new(
args.unwrap_or_default(),
var.unwrap_or_else(|| "__".into()),
var.unwrap_or_else(|| meta.unnamed_var()),
do_leak_res,
value
)
Expand All @@ -853,12 +905,12 @@ pub BuiltinCommand: LogicLine = {
LEnd => {
if takes.len() == 1 {
let (res, value) = takes.pop().unwrap();
let res = res.unwrap_or_else(|| "__".into());
let res = res.unwrap_or_else(|| meta.unnamed_var().into());
return Take(res, value).into();
}
let mut lines = Vec::with_capacity(takes.len());
for (res, value) in takes.into_iter() {
let res = res.unwrap_or_else(|| "__".into());
let res = res.unwrap_or_else(|| meta.unnamed_var().into());
let take = Take(res, value);
lines.push(take.into())
}
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.29"
version = "0.1.30"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
Loading

0 comments on commit be20d27

Please sign in to comment.