From e4ddd1562f9f3959110c6f6104e718af07777377 Mon Sep 17 00:00:00 2001 From: fy Date: Fri, 7 Jun 2024 21:02:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A0=A1=E6=AD=A3st=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=EF=BC=8C=E5=90=8C=E6=97=B6=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roll.peg | 118 +++---- roll.peg.go | 858 ++++++++++++++++++++++++++-------------------- rollvm.go | 8 +- rollvm_st_test.go | 153 ++++++++- rollvm_test.go | 8 + types.go | 6 +- valuemap.go | 35 ++ 7 files changed, 748 insertions(+), 438 deletions(-) diff --git a/roll.peg b/roll.peg index 0b695fb0..1c21e071 100644 --- a/roll.peg +++ b/roll.peg @@ -84,7 +84,7 @@ stmtContinue <- "continue" sp { stmtReturn <- "return" sp1x exprRoot { c.data.AddOp(typeReturn); } / "return" sp { c.data.PushNull(); c.data.AddOp(typeReturn); } -stmtWhile <- "while" { c.data.LoopBegin(); c.data.OffsetPush() } sp1x exprRoot { c.data.AddOp(typeJne); c.data.OffsetPush() } +stmtWhile <- "while" { c.data.LoopBegin(); c.data.OffsetPush() } sp1x exprRoot sp { c.data.AddOp(typeJne); c.data.OffsetPush() } block { c.data.AddOp(typeJmp); c.data.OffsetPush(); c.data.OffsetJmpSetX(0, 2, true); c.data.OffsetJmpSetX(1, 1, false); c.data.ContinueSet(2); c.data.BreakSet(); c.data.OffsetPopN(3);c.data.LoopEnd(); } // push xxx // 这里是while后面的exprRoot // jne 1 @@ -93,7 +93,7 @@ stmtWhile <- "while" { c.data.LoopBegin(); c.data.OffsetPush() } sp1x exprRoot { block <- ( '{' sp '}' / '{' sp stmtRoot '}' ) sp stmtElse <- "else" (sp block / sp1x stmtIf) -stmtIf <- "if" sp1x exprRoot { c.data.AddOp(typeJne); c.data.OffsetPush() } block { c.data.AddOp(typeJmp); c.data.OffsetPopAndSet(); c.data.OffsetPush(); } +stmtIf <- "if" sp1x exprRoot sp { c.data.AddOp(typeJne); c.data.OffsetPush() } block { c.data.AddOp(typeJmp); c.data.OffsetPopAndSet(); c.data.OffsetPush(); } stmtElse? { c.data.OffsetPopAndSet(); } // 'if' exprRoot block @@ -134,10 +134,10 @@ stmtAssign <- &stmtAssignType1 stmtAssignType1 // exprRoot <- exprSlice sp nestedBoost <- &(subX sp [-+*/%^dDcCaA&|?<>=]) exprSlice / &subX subX -exprRoot <- (nestedBoost / exprSlice) sp +exprRoot <- (nestedBoost / exprSlice) _step <- (':' sp (exprRoot / sp { c.data.PushNull() }) / sp { c.data.PushNull() }) -_sliceSuffix <- '[' sp (exprRoot / sp { c.data.PushNull() }) ':' sp (exprRoot / sp { c.data.PushNull() }) _step ']' sp +_sliceSuffix <- '[' sp (exprRoot / sp { c.data.PushNull() }) ':' sp (exprRoot / sp { c.data.PushNull() }) _step sp ']' sp exprSliceType1 <- exprTernary _sliceSuffix (!'=') { c.data.AddOp(typeSliceGet) } exprSlice <- &exprSliceType1 exprSliceType1 @@ -166,46 +166,46 @@ exprTernary <- &exprTernaryType1 exprTernaryType1 // 注: 越靠下的算符优先级越高 // 逻辑运算 -exprLogicOr <- exprLogicAnd sp (logicOr {c.data.AddOp(typeJeDup); c.data.OffsetPush()} exprLogicAnd { c.data.AddOp(typeJeDup); c.data.OffsetPush()} { c.data.AddOp(typePushLast); c.data.OffsetPopAndSet(); c.data.OffsetPopAndSet(); } )* -exprLogicAnd <- exprBitwiseOr sp (logicAnd exprBitwiseOr { c.data.AddOp(typeLogicAnd) } )* +exprLogicOr <- exprLogicAnd (sp logicOr {c.data.AddOp(typeJeDup); c.data.OffsetPush()} exprLogicAnd { c.data.AddOp(typeJeDup); c.data.OffsetPush()} { c.data.AddOp(typePushLast); c.data.OffsetPopAndSet(); c.data.OffsetPopAndSet(); } )* +exprLogicAnd <- exprBitwiseOr (sp logicAnd exprBitwiseOr { c.data.AddOp(typeLogicAnd) } )* // 位运算 exprBitwiseOr <- &{return c.data.Config.DisableBitwiseOp} exprCompare // 如果禁止,那么直接向下 - / exprBitwiseAnd sp (bitwiseOr exprBitwiseAnd { c.data.AddOp(typeBitwiseOr) })* -exprBitwiseAnd <- exprCompare sp (bitwiseAnd exprCompare { c.data.AddOp(typeBitwiseAnd) })* + / exprBitwiseAnd (sp bitwiseOr exprBitwiseAnd { c.data.AddOp(typeBitwiseOr) })* +exprBitwiseAnd <- exprCompare (sp bitwiseAnd exprCompare { c.data.AddOp(typeBitwiseAnd) })* // 比较 -exprCompare <- exprAdditive sp ( +exprCompare <- exprAdditive (sp ( lt exprAdditive { c.data.AddOp(typeCompLT) } / le exprAdditive { c.data.AddOp(typeCompLE) } / eq exprAdditive { c.data.AddOp(typeCompEQ) } / ne exprAdditive { c.data.AddOp(typeCompNE) } / ge exprAdditive { c.data.AddOp(typeCompGE) } / gt exprAdditive { c.data.AddOp(typeCompGT) } - )* + ))* // 加减 -exprAdditive <- exprMultiplicative sp ( +exprAdditive <- exprMultiplicative (sp ( add exprMultiplicative { c.data.AddOp(typeAdd) } / minus exprMultiplicative { c.data.AddOp(typeSubtract) } - )* + ))* // 乘除余 -exprMultiplicative <- exprNullCoalescing sp ( +exprMultiplicative <- exprNullCoalescing (sp ( multiply exprExp { c.data.AddOp(typeMultiply) } / divide exprExp { c.data.AddOp(typeDivide) } / modulus exprExp { c.data.AddOp(typeModulus) } - )* + ))* // 空值合并 -exprNullCoalescing <- exprExp sp ( - nullCoalescing exprExp { c.data.AddOp(typeNullCoalescing) } +exprNullCoalescing <- exprExp ( + sp nullCoalescing exprExp { c.data.AddOp(typeNullCoalescing) } )* // 平方 -exprExp <- exprUnaryNeg sp ( - exponentiation exprUnaryNeg { c.data.AddOp(typeExponentiation) } +exprExp <- exprUnaryNeg ( + sp exponentiation exprUnaryNeg { c.data.AddOp(typeExponentiation) } )* // 正数 负数 @@ -281,7 +281,7 @@ exprDice <- &_diceType1 detailStart nos _diceExpr1 detailEnd { c.data.AddOp(type array_call <- "kh" { c.data.WriteCode(typeGetAttr, string("kh")) } (number { c.data.AddInvoke(1) } / {c.data.AddInvoke(0)}) / "kl" { c.data.WriteCode(typeGetAttr, string("kl")) } (number { c.data.AddInvoke(1) } / {c.data.AddInvoke(0)}) - / ('[' sp exprRoot ']' sp { c.data.AddOp(typeItemGet) })+ + / ('[' sp exprRoot sp ']' sp { c.data.AddOp(typeItemGet) })+ // TODO: value 中的 item_get attr_get 连写这种形式处理的很烂,之后改掉 @@ -292,8 +292,8 @@ item_get <- (&&(item_getX) item_getX)? attr_getX <- ('.' (sp id:identifier sp { c.data.WriteCode(typeGetAttr, id.(string)) }) func_invoke? )* attr_get <- (&&attr_getX attr_getX)? -func_invoke <- '(' sp ')' sp { c.data.AddInvoke(0) } - / '(' sp { c.data.CounterPush(); c.data.CounterAdd(1) } exprRoot (',' sp exprRoot {c.data.CounterAdd(1)} )* ')' sp { c.data.AddInvoke(c.data.CounterPop()) } +func_invoke <- '(' sp ')' { c.data.AddInvoke(0) } + / '(' sp { c.data.CounterPush(); c.data.CounterAdd(1) } exprRoot sp (',' sp exprRoot {c.data.CounterAdd(1)} )* sp ')' { c.data.AddInvoke(c.data.CounterPop()) } dict_item <- ((value_id_without_colon / exprRoot) sp ':' sp exprRoot) sp { c.data.CounterAdd(1) } @@ -338,8 +338,8 @@ fstring <- ( / ('\x1e' '\x1e' { c.data.PushStr("") }) / ('"' '"' { c.data.PushStr("") }) / ('`' '`' { c.data.PushStr("") }) - / ('`' { c.data.CounterPush() } ( ('{' sp exprRoot {c.data.CounterAdd(1)} '}') / ("{%" sp exprRoot {c.data.CounterAdd(1)} "%}") / strPart )* '`' { c.data.AddFormatString(c.data.CounterPop()) }) - / ('\x1e' { c.data.CounterPush() } ( ('{' sp exprRoot {c.data.CounterAdd(1)} '}') / ("{%" sp exprRoot {c.data.CounterAdd(1)} "%}") / strPart1 )* '\x1e' { c.data.AddFormatString(c.data.CounterPop()) }) // 特殊标记 0x1E + / ('`' { c.data.CounterPush() } ( ('{' sp exprRoot {c.data.CounterAdd(1)} sp '}') / ("{%" sp exprRoot {c.data.CounterAdd(1)} sp "%}") / strPart )* '`' { c.data.AddFormatString(c.data.CounterPop()) }) + / ('\x1e' { c.data.CounterPush() } ( ('{' sp exprRoot {c.data.CounterAdd(1)} sp '}') / ("{%" sp exprRoot {c.data.CounterAdd(1)} sp "%}") / strPart1 )* '\x1e' { c.data.AddFormatString(c.data.CounterPop()) }) // 特殊标记 0x1E / ('"' { c.data.CounterPush() } strPart2* '"' { c.data.CounterPop() }) / ('\'' { c.data.CounterPush() } strPart3* '\'' { c.data.CounterPop() } ) ) sp @@ -426,57 +426,57 @@ commentLineRest2 <- (![\r\n] .)* [\r\n] st_expr <- st_modify_multi_1 / st_assign_multi - / st_modify_multi_2 -// est <- eDice / &'(' ? e0 -// est <- e0 -e0 <- stmtRoot -est <- ( &'(' e0 ) - / &e0 { c.data.FlagsPush(); c.data.Config.DisableStmts = true; c.data.Config.DisableNDice = true} e0 { c.data.FlagsPop() } +est <- ( &'(' exprRoot ) + / &exprRoot { + c.data.FlagsPush() + c.data.Config.DisableStmts = true + c.data.Config.DisableNDice = true + c.data.Config.DisableBitwiseOp = true + } exprRoot { c.data.FlagsPop() } st_assign_multi <- (st_assign sp ','? sp)+ st_star <- '*' sp (float / number / sub) -st_assign <- st_name2 sp (':' / '=') sp est { c.data.AddStName() } // 射击:弓箭:40 / 射击:弓箭40 - / st_name1 est { c.data.AddStName() } // 测试:力量60 - / st_name2r sp st_star sp (':' / '=') sp est { c.data.AddOp(typeStX1) } // 属性2*2.0: 5 - / st_name2r sp '*' sp (':' / '=') sp est { c.data.AddOp(typeStX0) } // 属性*: 4 - / st_name2r sp (':' / '=') sp est { c.data.AddStName() } // 属性2: 70 - / st_name1r est { c.data.AddStName() } // 力量60 - / '&' st_name2 sp (':' / '=') sp { c.data.CodePush() } text:< est > { c.data.CodePop(); c.data.AddStoreComputedOnStack(text.(string)); c.data.AddStName() } // &手枪 = 1d4 - / '&' st_name2r sp (':' / '=') sp { c.data.CodePush() } text:< est > { c.data.CodePop(); c.data.AddStoreComputedOnStack(text.(string)); c.data.AddStName() } // &手枪 = 1d4 +st_assign <- &(st_name2 sp (':' / '=') sp est) st_name2 sp (':' / '=') sp est { c.data.AddStName() } // 射击:弓箭:40 / 射击:弓箭40 + / &(st_name1 est) st_name1 est { c.data.AddStName() } // 测试:力量60 + / &(st_name2r sp st_star sp (':' / '=') sp est) st_name2r sp st_star sp (':' / '=') sp est { c.data.AddOp(typeStX1) } // 属性2*2.0: 5 + / &(st_name2r sp '*' sp (':' / '=') sp est) st_name2r sp '*' sp (':' / '=') sp est { c.data.AddOp(typeStX0) } // 属性*: 4 + / &(st_name2r sp (':' / '=') sp est) st_name2r sp (':' / '=') sp est { c.data.AddStName() } // 属性2: 70 + / &(st_name1r est) st_name1r est { c.data.AddStName() } // 力量60 + / &('&' st_name2 sp (':' / '=') est) '&' st_name2 sp (':' / '=') sp { c.data.CodePush(); } text:< est > { c.data.AddStoreComputedOnStack(text.(string)); c.data.AddStName() } // &手枪 = 1d4 + / &('&' st_name2r sp (':' / '=') est) '&' st_name2r sp (':' / '=') sp {c.data.CodePush(); } text:< est > { c.data.AddStoreComputedOnStack(text.(string)); c.data.AddStName() } // &手枪 = 1d4 // 第一类: // 力量+1d3 -// 力量123+=1d3 -st_modify_multi_1 <- ((st_name2 st_modify_rest1 / st_name2r st_modify_rest1 / st_name1 st_modify_rest / st_name1r st_modify_rest) sp ','? sp ) st_modify_multi_rest - -st_modify_rest1 <- sp ( - "+=" sp text:< e0 > {c.data.AddStModify("+", text.(string))} / - "-=" sp text:< e0 > {c.data.AddStModify("-", text.(string))} -) +// 力量123+=1d3 // 这种语法已经不支持,原因忘记了 +// '力量123'+=1d3 +st_modify_multi_1 <- (st_modify_lead sp ','? sp) st_modify_multi_rest -// 第二类,在第一种基础上增加: -// 力量123+1d3 +st_modify_lead <- &(st_name2 st_modify_rest1) st_name2 st_modify_rest1 + / &(st_name2r st_modify_rest1) st_name2r st_modify_rest1 + / &(st_name1 st_modify_rest) st_name1 st_modify_rest + / &(st_name1r st_modify_rest) st_name1r st_modify_rest -st_modify_multi_2 <- (st_modify2 sp ','? sp) st_modify_multi_rest +st_modify_multi_rest <- (st_modify_lead sp ','? sp)* -st_modify_multi_rest <- (st_modify2 sp ','? sp)* -st_modify2 <- st_name2 st_modify_rest - / st_name2r st_modify_rest +st_modify_rest1 <- sp ( + "+=" sp text:< exprRoot > {c.data.AddStModify("+", text.(string))} / + "-=" sp text:< exprRoot > {c.data.AddStModify("-", text.(string))} +) st_modify_rest <- sp ( - '+' '='? sp text:< e0 > {c.data.AddStModify("+", text.(string))} / - &( '-' ) sp text:< e0 > {c.data.AddStModify("-", text.(string))} / - '-' '='? sp text:< e0 > {c.data.AddStModify("-", text.(string))} + '+' '='? sp text:< exprRoot > {c.data.AddStModify("+", text.(string))} / + '-' '='? sp text:< exprRoot > {c.data.AddStModify("-", text.(string))} + /// &( '-' ) sp text:< exprRoot > {c.data.AddStModify("-", text.(string))} / ) -st_name1 <- text:<( id_ch0+ ":" id_ch0+ )> { c.data.PushStr(text.(string)) } // 结尾不带数字 -st_name1r <- text: <( id_ch0+ )> { c.data.PushStr(text.(string)) } // 结尾不带数字 +st_name1 <- text:<( id_ch+ ":" id_ch+ )> { c.data.PushStr(text.(string)) } // 结尾不带数字 +st_name1r <- text: <( id_ch+ )> { c.data.PushStr(text.(string)) } // 结尾不带数字 + / '\'' text:< (id_ch / [0-9] / ' ' / ':')+ > '\'' { c.data.PushStr(text.(string)) } // 任意字符,需要框起来 -st_name2 <- text:<( id_ch0 id_ch* (':' id_ch+) )> { c.data.PushStr(text.(string)) } // 结尾可带数字,即常规变量名 -st_name2r <- text:<( id_ch0 id_ch* )> { c.data.PushStr(text.(string)) } // 结尾可带数字,即常规变量名 - / '\'' text:< (id_ch0 / [0-9] / ' ' / ':')+ > '\'' { c.data.PushStr(text.(string)) } // 任意字符 +st_name2 <- st_name1 // 目前和1一样,占位符 +st_name2r <- text:<( id_ch+ )> { c.data.PushStr(text.(string)) } // 结尾可带数字,即常规变量名 + / '\'' text:< (id_ch / [0-9] / ' ' / ':')+ > '\'' { c.data.PushStr(text.(string)) } // 任意字符 -id_ch0 <- xidStart id_ch <- xidStart diff --git a/roll.peg.go b/roll.peg.go index 0577642f..089952b4 100644 --- a/roll.peg.go +++ b/roll.peg.go @@ -267,11 +267,12 @@ var g = &grammar{ exprs: []any{ &ruleIRefExpr{index: 117 /* sp1x */}, &ruleIRefExpr{index: 26 /* exprRoot */}, + &ruleIRefExpr{index: 115 /* sp */}, }, }, }, &actionExpr{ - run: (*parser).call_onstmtWhile_8, + run: (*parser).call_onstmtWhile_9, expr: &ruleIRefExpr{index: 12 /* block */}, }, }, @@ -339,15 +340,16 @@ var g = &grammar{ &litMatcher{val: "if", want: "\"if\""}, &ruleIRefExpr{index: 117 /* sp1x */}, &ruleIRefExpr{index: 26 /* exprRoot */}, + &ruleIRefExpr{index: 115 /* sp */}, }, }, }, &actionExpr{ - run: (*parser).call_onstmtIf_7, + run: (*parser).call_onstmtIf_8, expr: &ruleIRefExpr{index: 12 /* block */}, }, &actionExpr{ - run: (*parser).call_onstmtIf_9, + run: (*parser).call_onstmtIf_10, expr: &zeroOrOneExpr{ expr: &ruleIRefExpr{index: 13 /* stmtElse */}, }, @@ -798,15 +800,10 @@ var g = &grammar{ }, { name: "exprRoot", - expr: &seqExpr{ - exprs: []any{ - &choiceExpr{ - alternatives: []any{ - &ruleIRefExpr{index: 25 /* nestedBoost */}, - &ruleIRefExpr{index: 30 /* exprSlice */}, - }, - }, - &ruleIRefExpr{index: 115 /* sp */}, + expr: &choiceExpr{ + alternatives: []any{ + &ruleIRefExpr{index: 25 /* nestedBoost */}, + &ruleIRefExpr{index: 30 /* exprSlice */}, }, }, }, @@ -863,6 +860,7 @@ var g = &grammar{ }, }, &ruleIRefExpr{index: 27 /* _step */}, + &ruleIRefExpr{index: 115 /* sp */}, &litMatcher{val: "]", want: "\"]\""}, &ruleIRefExpr{index: 115 /* sp */}, }, @@ -1019,20 +1017,24 @@ var g = &grammar{ expr: &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 36 /* exprLogicAnd */}, - &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ expr: &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onexprLogicOr_6, - expr: &ruleIRefExpr{index: 107 /* logicOr */}, + run: (*parser).call_onexprLogicOr_5, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, + &ruleIRefExpr{index: 107 /* logicOr */}, + }, + }, }, &actionExpr{ - run: (*parser).call_onexprLogicOr_8, + run: (*parser).call_onexprLogicOr_9, expr: &ruleIRefExpr{index: 36 /* exprLogicAnd */}, }, &codeExpr{ - run: (*parser).call_onexprLogicOr_10, + run: (*parser).call_onexprLogicOr_11, }, }, }, @@ -1045,12 +1047,12 @@ var g = &grammar{ expr: &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 37 /* exprBitwiseOr */}, - &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ expr: &actionExpr{ - run: (*parser).call_onexprLogicAnd_5, + run: (*parser).call_onexprLogicAnd_4, expr: &seqExpr{ exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, &ruleIRefExpr{index: 108 /* logicAnd */}, &ruleIRefExpr{index: 37 /* exprBitwiseOr */}, }, @@ -1073,12 +1075,12 @@ var g = &grammar{ &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 38 /* exprBitwiseAnd */}, - &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ expr: &actionExpr{ - run: (*parser).call_onexprBitwiseOr_9, + run: (*parser).call_onexprBitwiseOr_8, expr: &seqExpr{ exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, &ruleIRefExpr{index: 105 /* bitwiseOr */}, &ruleIRefExpr{index: 38 /* exprBitwiseAnd */}, }, @@ -1095,12 +1097,12 @@ var g = &grammar{ expr: &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 39 /* exprCompare */}, - &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ expr: &actionExpr{ - run: (*parser).call_onexprBitwiseAnd_5, + run: (*parser).call_onexprBitwiseAnd_4, expr: &seqExpr{ exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, &ruleIRefExpr{index: 106 /* bitwiseAnd */}, &ruleIRefExpr{index: 39 /* exprCompare */}, }, @@ -1115,61 +1117,65 @@ var g = &grammar{ expr: &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 40 /* exprAdditive */}, - &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ - expr: &choiceExpr{ - alternatives: []any{ - &actionExpr{ - run: (*parser).call_onexprCompare_6, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 109 /* lt */}, - &ruleIRefExpr{index: 40 /* exprAdditive */}, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ + &actionExpr{ + run: (*parser).call_onexprCompare_7, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 109 /* lt */}, + &ruleIRefExpr{index: 40 /* exprAdditive */}, + }, + }, }, - }, - }, - &actionExpr{ - run: (*parser).call_onexprCompare_10, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 111 /* le */}, - &ruleIRefExpr{index: 40 /* exprAdditive */}, + &actionExpr{ + run: (*parser).call_onexprCompare_11, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 111 /* le */}, + &ruleIRefExpr{index: 40 /* exprAdditive */}, + }, + }, }, - }, - }, - &actionExpr{ - run: (*parser).call_onexprCompare_14, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 113 /* eq */}, - &ruleIRefExpr{index: 40 /* exprAdditive */}, + &actionExpr{ + run: (*parser).call_onexprCompare_15, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 113 /* eq */}, + &ruleIRefExpr{index: 40 /* exprAdditive */}, + }, + }, }, - }, - }, - &actionExpr{ - run: (*parser).call_onexprCompare_18, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 114 /* ne */}, - &ruleIRefExpr{index: 40 /* exprAdditive */}, + &actionExpr{ + run: (*parser).call_onexprCompare_19, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 114 /* ne */}, + &ruleIRefExpr{index: 40 /* exprAdditive */}, + }, + }, }, - }, - }, - &actionExpr{ - run: (*parser).call_onexprCompare_22, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 112 /* ge */}, - &ruleIRefExpr{index: 40 /* exprAdditive */}, + &actionExpr{ + run: (*parser).call_onexprCompare_23, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 112 /* ge */}, + &ruleIRefExpr{index: 40 /* exprAdditive */}, + }, + }, }, - }, - }, - &actionExpr{ - run: (*parser).call_onexprCompare_26, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 110 /* gt */}, - &ruleIRefExpr{index: 40 /* exprAdditive */}, + &actionExpr{ + run: (*parser).call_onexprCompare_27, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 110 /* gt */}, + &ruleIRefExpr{index: 40 /* exprAdditive */}, + }, + }, }, }, }, @@ -1184,25 +1190,29 @@ var g = &grammar{ expr: &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 41 /* exprMultiplicative */}, - &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ - expr: &choiceExpr{ - alternatives: []any{ - &actionExpr{ - run: (*parser).call_onexprAdditive_6, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 98 /* add */}, - &ruleIRefExpr{index: 41 /* exprMultiplicative */}, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ + &actionExpr{ + run: (*parser).call_onexprAdditive_7, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 98 /* add */}, + &ruleIRefExpr{index: 41 /* exprMultiplicative */}, + }, + }, }, - }, - }, - &actionExpr{ - run: (*parser).call_onexprAdditive_10, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 99 /* minus */}, - &ruleIRefExpr{index: 41 /* exprMultiplicative */}, + &actionExpr{ + run: (*parser).call_onexprAdditive_11, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 99 /* minus */}, + &ruleIRefExpr{index: 41 /* exprMultiplicative */}, + }, + }, }, }, }, @@ -1217,34 +1227,38 @@ var g = &grammar{ expr: &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 42 /* exprNullCoalescing */}, - &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ - expr: &choiceExpr{ - alternatives: []any{ - &actionExpr{ - run: (*parser).call_onexprMultiplicative_6, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 100 /* multiply */}, - &ruleIRefExpr{index: 43 /* exprExp */}, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ + &actionExpr{ + run: (*parser).call_onexprMultiplicative_7, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 100 /* multiply */}, + &ruleIRefExpr{index: 43 /* exprExp */}, + }, + }, }, - }, - }, - &actionExpr{ - run: (*parser).call_onexprMultiplicative_10, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 101 /* divide */}, - &ruleIRefExpr{index: 43 /* exprExp */}, + &actionExpr{ + run: (*parser).call_onexprMultiplicative_11, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 101 /* divide */}, + &ruleIRefExpr{index: 43 /* exprExp */}, + }, + }, }, - }, - }, - &actionExpr{ - run: (*parser).call_onexprMultiplicative_14, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 102 /* modulus */}, - &ruleIRefExpr{index: 43 /* exprExp */}, + &actionExpr{ + run: (*parser).call_onexprMultiplicative_15, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 102 /* modulus */}, + &ruleIRefExpr{index: 43 /* exprExp */}, + }, + }, }, }, }, @@ -1259,12 +1273,12 @@ var g = &grammar{ expr: &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 43 /* exprExp */}, - &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ expr: &actionExpr{ - run: (*parser).call_onexprNullCoalescing_5, + run: (*parser).call_onexprNullCoalescing_4, expr: &seqExpr{ exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, &ruleIRefExpr{index: 104 /* nullCoalescing */}, &ruleIRefExpr{index: 43 /* exprExp */}, }, @@ -1279,12 +1293,12 @@ var g = &grammar{ expr: &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 44 /* exprUnaryNeg */}, - &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ expr: &actionExpr{ - run: (*parser).call_onexprExp_5, + run: (*parser).call_onexprExp_4, expr: &seqExpr{ exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, &ruleIRefExpr{index: 103 /* exponentiation */}, &ruleIRefExpr{index: 44 /* exprUnaryNeg */}, }, @@ -2150,6 +2164,7 @@ var g = &grammar{ &litMatcher{val: "[", want: "\"[\""}, &ruleIRefExpr{index: 115 /* sp */}, &ruleIRefExpr{index: 26 /* exprRoot */}, + &ruleIRefExpr{index: 115 /* sp */}, &litMatcher{val: "]", want: "\"]\""}, &ruleIRefExpr{index: 115 /* sp */}, }, @@ -2251,14 +2266,13 @@ var g = &grammar{ &litMatcher{val: "(", want: "\"(\""}, &ruleIRefExpr{index: 115 /* sp */}, &litMatcher{val: ")", want: "\")\""}, - &ruleIRefExpr{index: 115 /* sp */}, }, }, }, &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onfunc_invoke_9, + run: (*parser).call_onfunc_invoke_8, expr: &seqExpr{ exprs: []any{ &litMatcher{val: "(", want: "\"(\""}, @@ -2267,10 +2281,11 @@ var g = &grammar{ }, }, &actionExpr{ - run: (*parser).call_onfunc_invoke_13, + run: (*parser).call_onfunc_invoke_12, expr: &seqExpr{ exprs: []any{ &ruleIRefExpr{index: 26 /* exprRoot */}, + &ruleIRefExpr{index: 115 /* sp */}, &zeroOrMoreExpr{ expr: &actionExpr{ run: (*parser).call_onfunc_invoke_17, @@ -2283,8 +2298,8 @@ var g = &grammar{ }, }, }, - &litMatcher{val: ")", want: "\")\""}, &ruleIRefExpr{index: 115 /* sp */}, + &litMatcher{val: ")", want: "\")\""}, }, }, }, @@ -2847,13 +2862,18 @@ var g = &grammar{ }, }, }, - &litMatcher{val: "}", want: "\"}\""}, + &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, + &litMatcher{val: "}", want: "\"}\""}, + }, + }, }, }, &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onfstring_34, + run: (*parser).call_onfstring_36, expr: &seqExpr{ exprs: []any{ &litMatcher{val: "{%", want: "\"{%\""}, @@ -2862,7 +2882,12 @@ var g = &grammar{ }, }, }, - &litMatcher{val: "%}", want: "\"%}\""}, + &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, + &litMatcher{val: "%}", want: "\"%}\""}, + }, + }, }, }, &ruleIRefExpr{index: 82 /* strPart */}, @@ -2878,11 +2903,11 @@ var g = &grammar{ &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onfstring_43, + run: (*parser).call_onfstring_47, expr: &litMatcher{val: "\x1e", want: "\"\\x1e\""}, }, &actionExpr{ - run: (*parser).call_onfstring_45, + run: (*parser).call_onfstring_49, expr: &seqExpr{ exprs: []any{ &zeroOrMoreExpr{ @@ -2891,7 +2916,7 @@ var g = &grammar{ &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onfstring_50, + run: (*parser).call_onfstring_54, expr: &seqExpr{ exprs: []any{ &litMatcher{val: "{", want: "\"{\""}, @@ -2900,13 +2925,18 @@ var g = &grammar{ }, }, }, - &litMatcher{val: "}", want: "\"}\""}, + &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, + &litMatcher{val: "}", want: "\"}\""}, + }, + }, }, }, &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onfstring_57, + run: (*parser).call_onfstring_63, expr: &seqExpr{ exprs: []any{ &litMatcher{val: "{%", want: "\"{%\""}, @@ -2915,7 +2945,12 @@ var g = &grammar{ }, }, }, - &litMatcher{val: "%}", want: "\"%}\""}, + &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, + &litMatcher{val: "%}", want: "\"%}\""}, + }, + }, }, }, &ruleIRefExpr{index: 83 /* strPart1 */}, @@ -2931,11 +2966,11 @@ var g = &grammar{ &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onfstring_66, + run: (*parser).call_onfstring_74, expr: &litMatcher{val: "\"", want: "\"\\\"\""}, }, &actionExpr{ - run: (*parser).call_onfstring_68, + run: (*parser).call_onfstring_76, expr: &seqExpr{ exprs: []any{ &zeroOrMoreExpr{ @@ -2950,11 +2985,11 @@ var g = &grammar{ &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onfstring_74, + run: (*parser).call_onfstring_82, expr: &litMatcher{val: "'", want: "\"'\""}, }, &actionExpr{ - run: (*parser).call_onfstring_76, + run: (*parser).call_onfstring_84, expr: &seqExpr{ exprs: []any{ &zeroOrMoreExpr{ @@ -3400,16 +3435,11 @@ var g = &grammar{ name: "st_expr", expr: &choiceExpr{ alternatives: []any{ - &ruleIRefExpr{index: 128 /* st_modify_multi_1 */}, - &ruleIRefExpr{index: 125 /* st_assign_multi */}, - &ruleIRefExpr{index: 130 /* st_modify_multi_2 */}, + &ruleIRefExpr{index: 127 /* st_modify_multi_1 */}, + &ruleIRefExpr{index: 124 /* st_assign_multi */}, }, }, }, - { - name: "e0", - expr: &ruleIRefExpr{index: 2 /* stmtRoot */}, - }, { name: "est", expr: &choiceExpr{ @@ -3419,7 +3449,7 @@ var g = &grammar{ &andExpr{ expr: &litMatcher{val: "(", want: "\"(\""}, }, - &ruleIRefExpr{index: 123 /* e0 */}, + &ruleIRefExpr{index: 26 /* exprRoot */}, }, }, &seqExpr{ @@ -3427,12 +3457,12 @@ var g = &grammar{ &actionExpr{ run: (*parser).call_onest_7, expr: &andExpr{ - expr: &ruleIRefExpr{index: 123 /* e0 */}, + expr: &ruleIRefExpr{index: 26 /* exprRoot */}, }, }, &actionExpr{ run: (*parser).call_onest_10, - expr: &ruleIRefExpr{index: 123 /* e0 */}, + expr: &ruleIRefExpr{index: 26 /* exprRoot */}, }, }, }, @@ -3444,7 +3474,7 @@ var g = &grammar{ expr: &oneOrMoreExpr{ expr: &seqExpr{ exprs: []any{ - &ruleIRefExpr{index: 127 /* st_assign */}, + &ruleIRefExpr{index: 126 /* st_assign */}, &ruleIRefExpr{index: 115 /* sp */}, &zeroOrOneExpr{ expr: &litMatcher{val: ",", want: "\",\""}, @@ -3479,7 +3509,23 @@ var g = &grammar{ run: (*parser).call_onst_assign_2, expr: &seqExpr{ exprs: []any{ - &ruleIRefExpr{index: 136 /* st_name2 */}, + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 134 /* st_name2 */}, + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ + &litMatcher{val: ":", want: "\":\""}, + &litMatcher{val: "=", want: "\"=\""}, + }, + }, + &ruleIRefExpr{index: 115 /* sp */}, + &ruleIRefExpr{index: 123 /* est */}, + }, + }, + }, + &ruleIRefExpr{index: 134 /* st_name2 */}, &ruleIRefExpr{index: 115 /* sp */}, &choiceExpr{ alternatives: []any{ @@ -3488,26 +3534,52 @@ var g = &grammar{ }, }, &ruleIRefExpr{index: 115 /* sp */}, - &ruleIRefExpr{index: 124 /* est */}, + &ruleIRefExpr{index: 123 /* est */}, }, }, }, &actionExpr{ - run: (*parser).call_onst_assign_11, + run: (*parser).call_onst_assign_20, expr: &seqExpr{ exprs: []any{ - &ruleIRefExpr{index: 134 /* st_name1 */}, - &ruleIRefExpr{index: 124 /* est */}, + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 132 /* st_name1 */}, + &ruleIRefExpr{index: 123 /* est */}, + }, + }, + }, + &ruleIRefExpr{index: 132 /* st_name1 */}, + &ruleIRefExpr{index: 123 /* est */}, }, }, }, &actionExpr{ - run: (*parser).call_onst_assign_15, + run: (*parser).call_onst_assign_28, expr: &seqExpr{ exprs: []any{ - &ruleIRefExpr{index: 137 /* st_name2r */}, + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 135 /* st_name2r */}, + &ruleIRefExpr{index: 115 /* sp */}, + &ruleIRefExpr{index: 125 /* st_star */}, + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ + &litMatcher{val: ":", want: "\":\""}, + &litMatcher{val: "=", want: "\"=\""}, + }, + }, + &ruleIRefExpr{index: 115 /* sp */}, + &ruleIRefExpr{index: 123 /* est */}, + }, + }, + }, + &ruleIRefExpr{index: 135 /* st_name2r */}, &ruleIRefExpr{index: 115 /* sp */}, - &ruleIRefExpr{index: 126 /* st_star */}, + &ruleIRefExpr{index: 125 /* st_star */}, &ruleIRefExpr{index: 115 /* sp */}, &choiceExpr{ alternatives: []any{ @@ -3516,15 +3588,33 @@ var g = &grammar{ }, }, &ruleIRefExpr{index: 115 /* sp */}, - &ruleIRefExpr{index: 124 /* est */}, + &ruleIRefExpr{index: 123 /* est */}, }, }, }, &actionExpr{ - run: (*parser).call_onst_assign_26, + run: (*parser).call_onst_assign_50, expr: &seqExpr{ exprs: []any{ - &ruleIRefExpr{index: 137 /* st_name2r */}, + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 135 /* st_name2r */}, + &ruleIRefExpr{index: 115 /* sp */}, + &litMatcher{val: "*", want: "\"*\""}, + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ + &litMatcher{val: ":", want: "\":\""}, + &litMatcher{val: "=", want: "\"=\""}, + }, + }, + &ruleIRefExpr{index: 115 /* sp */}, + &ruleIRefExpr{index: 123 /* est */}, + }, + }, + }, + &ruleIRefExpr{index: 135 /* st_name2r */}, &ruleIRefExpr{index: 115 /* sp */}, &litMatcher{val: "*", want: "\"*\""}, &ruleIRefExpr{index: 115 /* sp */}, @@ -3535,15 +3625,31 @@ var g = &grammar{ }, }, &ruleIRefExpr{index: 115 /* sp */}, - &ruleIRefExpr{index: 124 /* est */}, + &ruleIRefExpr{index: 123 /* est */}, }, }, }, &actionExpr{ - run: (*parser).call_onst_assign_37, + run: (*parser).call_onst_assign_72, expr: &seqExpr{ exprs: []any{ - &ruleIRefExpr{index: 137 /* st_name2r */}, + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 135 /* st_name2r */}, + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ + &litMatcher{val: ":", want: "\":\""}, + &litMatcher{val: "=", want: "\"=\""}, + }, + }, + &ruleIRefExpr{index: 115 /* sp */}, + &ruleIRefExpr{index: 123 /* est */}, + }, + }, + }, + &ruleIRefExpr{index: 135 /* st_name2r */}, &ruleIRefExpr{index: 115 /* sp */}, &choiceExpr{ alternatives: []any{ @@ -3552,27 +3658,51 @@ var g = &grammar{ }, }, &ruleIRefExpr{index: 115 /* sp */}, - &ruleIRefExpr{index: 124 /* est */}, + &ruleIRefExpr{index: 123 /* est */}, }, }, }, &actionExpr{ - run: (*parser).call_onst_assign_46, + run: (*parser).call_onst_assign_90, expr: &seqExpr{ exprs: []any{ - &ruleIRefExpr{index: 135 /* st_name1r */}, - &ruleIRefExpr{index: 124 /* est */}, + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 133 /* st_name1r */}, + &ruleIRefExpr{index: 123 /* est */}, + }, + }, + }, + &ruleIRefExpr{index: 133 /* st_name1r */}, + &ruleIRefExpr{index: 123 /* est */}, }, }, }, &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onst_assign_51, + run: (*parser).call_onst_assign_99, expr: &seqExpr{ exprs: []any{ + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &litMatcher{val: "&", want: "\"&\""}, + &ruleIRefExpr{index: 134 /* st_name2 */}, + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ + &litMatcher{val: ":", want: "\":\""}, + &litMatcher{val: "=", want: "\"=\""}, + }, + }, + &ruleIRefExpr{index: 123 /* est */}, + }, + }, + }, &litMatcher{val: "&", want: "\"&\""}, - &ruleIRefExpr{index: 136 /* st_name2 */}, + &ruleIRefExpr{index: 134 /* st_name2 */}, &ruleIRefExpr{index: 115 /* sp */}, &choiceExpr{ alternatives: []any{ @@ -3585,10 +3715,10 @@ var g = &grammar{ }, }, &actionExpr{ - run: (*parser).call_onst_assign_60, + run: (*parser).call_onst_assign_117, expr: &labeledExpr{ label: "text", - expr: &ruleIRefExpr{index: 124 /* est */}, + expr: &ruleIRefExpr{index: 123 /* est */}, textCapture: true, }, }, @@ -3597,11 +3727,27 @@ var g = &grammar{ &seqExpr{ exprs: []any{ &actionExpr{ - run: (*parser).call_onst_assign_64, + run: (*parser).call_onst_assign_121, expr: &seqExpr{ exprs: []any{ + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &litMatcher{val: "&", want: "\"&\""}, + &ruleIRefExpr{index: 135 /* st_name2r */}, + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ + &litMatcher{val: ":", want: "\":\""}, + &litMatcher{val: "=", want: "\"=\""}, + }, + }, + &ruleIRefExpr{index: 123 /* est */}, + }, + }, + }, &litMatcher{val: "&", want: "\"&\""}, - &ruleIRefExpr{index: 137 /* st_name2r */}, + &ruleIRefExpr{index: 135 /* st_name2r */}, &ruleIRefExpr{index: 115 /* sp */}, &choiceExpr{ alternatives: []any{ @@ -3614,10 +3760,10 @@ var g = &grammar{ }, }, &actionExpr{ - run: (*parser).call_onst_assign_73, + run: (*parser).call_onst_assign_139, expr: &labeledExpr{ label: "text", - expr: &ruleIRefExpr{index: 124 /* est */}, + expr: &ruleIRefExpr{index: 123 /* est */}, textCapture: true, }, }, @@ -3632,34 +3778,7 @@ var g = &grammar{ exprs: []any{ &seqExpr{ exprs: []any{ - &choiceExpr{ - alternatives: []any{ - &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 136 /* st_name2 */}, - &ruleIRefExpr{index: 129 /* st_modify_rest1 */}, - }, - }, - &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 137 /* st_name2r */}, - &ruleIRefExpr{index: 129 /* st_modify_rest1 */}, - }, - }, - &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 134 /* st_name1 */}, - &ruleIRefExpr{index: 133 /* st_modify_rest */}, - }, - }, - &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 135 /* st_name1r */}, - &ruleIRefExpr{index: 133 /* st_modify_rest */}, - }, - }, - }, - }, + &ruleIRefExpr{index: 128 /* st_modify_lead */}, &ruleIRefExpr{index: 115 /* sp */}, &zeroOrOneExpr{ expr: &litMatcher{val: ",", want: "\",\""}, @@ -3667,66 +3786,70 @@ var g = &grammar{ &ruleIRefExpr{index: 115 /* sp */}, }, }, - &ruleIRefExpr{index: 131 /* st_modify_multi_rest */}, + &ruleIRefExpr{index: 129 /* st_modify_multi_rest */}, }, }, }, { - name: "st_modify_rest1", - varExists: true, - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 115 /* sp */}, - &choiceExpr{ - alternatives: []any{ - &actionExpr{ - run: (*parser).call_onst_modify_rest1_4, + name: "st_modify_lead", + expr: &choiceExpr{ + alternatives: []any{ + &seqExpr{ + exprs: []any{ + &andExpr{ expr: &seqExpr{ exprs: []any{ - &litMatcher{val: "+=", want: "\"+=\""}, - &ruleIRefExpr{index: 115 /* sp */}, - &labeledExpr{ - label: "text", - expr: &ruleIRefExpr{index: 123 /* e0 */}, - textCapture: true, - }, + &ruleIRefExpr{index: 134 /* st_name2 */}, + &ruleIRefExpr{index: 130 /* st_modify_rest1 */}, }, }, }, - &actionExpr{ - run: (*parser).call_onst_modify_rest1_10, + &ruleIRefExpr{index: 134 /* st_name2 */}, + &ruleIRefExpr{index: 130 /* st_modify_rest1 */}, + }, + }, + &seqExpr{ + exprs: []any{ + &andExpr{ expr: &seqExpr{ exprs: []any{ - &litMatcher{val: "-=", want: "\"-=\""}, - &ruleIRefExpr{index: 115 /* sp */}, - &labeledExpr{ - label: "text", - expr: &ruleIRefExpr{index: 123 /* e0 */}, - textCapture: true, - }, + &ruleIRefExpr{index: 135 /* st_name2r */}, + &ruleIRefExpr{index: 130 /* st_modify_rest1 */}, }, }, }, + &ruleIRefExpr{index: 135 /* st_name2r */}, + &ruleIRefExpr{index: 130 /* st_modify_rest1 */}, }, }, - }, - }, - }, - { - name: "st_modify_multi_2", - expr: &seqExpr{ - exprs: []any{ &seqExpr{ exprs: []any{ - &ruleIRefExpr{index: 132 /* st_modify2 */}, - &ruleIRefExpr{index: 115 /* sp */}, - &zeroOrOneExpr{ - expr: &litMatcher{val: ",", want: "\",\""}, + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 132 /* st_name1 */}, + &ruleIRefExpr{index: 131 /* st_modify_rest */}, + }, + }, }, - &ruleIRefExpr{index: 115 /* sp */}, + &ruleIRefExpr{index: 132 /* st_name1 */}, + &ruleIRefExpr{index: 131 /* st_modify_rest */}, + }, + }, + &seqExpr{ + exprs: []any{ + &andExpr{ + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 133 /* st_name1r */}, + &ruleIRefExpr{index: 131 /* st_modify_rest */}, + }, + }, + }, + &ruleIRefExpr{index: 133 /* st_name1r */}, + &ruleIRefExpr{index: 131 /* st_modify_rest */}, }, }, - &ruleIRefExpr{index: 131 /* st_modify_multi_rest */}, }, }, }, @@ -3735,7 +3858,7 @@ var g = &grammar{ expr: &zeroOrMoreExpr{ expr: &seqExpr{ exprs: []any{ - &ruleIRefExpr{index: 132 /* st_modify2 */}, + &ruleIRefExpr{index: 128 /* st_modify_lead */}, &ruleIRefExpr{index: 115 /* sp */}, &zeroOrOneExpr{ expr: &litMatcher{val: ",", want: "\",\""}, @@ -3746,26 +3869,7 @@ var g = &grammar{ }, }, { - name: "st_modify2", - expr: &choiceExpr{ - alternatives: []any{ - &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 136 /* st_name2 */}, - &ruleIRefExpr{index: 133 /* st_modify_rest */}, - }, - }, - &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 137 /* st_name2r */}, - &ruleIRefExpr{index: 133 /* st_modify_rest */}, - }, - }, - }, - }, - }, - { - name: "st_modify_rest", + name: "st_modify_rest1", varExists: true, expr: &seqExpr{ exprs: []any{ @@ -3773,40 +3877,65 @@ var g = &grammar{ &choiceExpr{ alternatives: []any{ &actionExpr{ - run: (*parser).call_onst_modify_rest_4, + run: (*parser).call_onst_modify_rest1_4, expr: &seqExpr{ exprs: []any{ - &litMatcher{val: "+", want: "\"+\""}, - &zeroOrOneExpr{ - expr: &litMatcher{val: "=", want: "\"=\""}, + &litMatcher{val: "+=", want: "\"+=\""}, + &ruleIRefExpr{index: 115 /* sp */}, + &labeledExpr{ + label: "text", + expr: &ruleIRefExpr{index: 26 /* exprRoot */}, + textCapture: true, }, + }, + }, + }, + &actionExpr{ + run: (*parser).call_onst_modify_rest1_10, + expr: &seqExpr{ + exprs: []any{ + &litMatcher{val: "-=", want: "\"-=\""}, &ruleIRefExpr{index: 115 /* sp */}, &labeledExpr{ label: "text", - expr: &ruleIRefExpr{index: 123 /* e0 */}, + expr: &ruleIRefExpr{index: 26 /* exprRoot */}, textCapture: true, }, }, }, }, + }, + }, + }, + }, + }, + { + name: "st_modify_rest", + varExists: true, + expr: &seqExpr{ + exprs: []any{ + &ruleIRefExpr{index: 115 /* sp */}, + &choiceExpr{ + alternatives: []any{ &actionExpr{ - run: (*parser).call_onst_modify_rest_12, + run: (*parser).call_onst_modify_rest_4, expr: &seqExpr{ exprs: []any{ - &andExpr{ - expr: &litMatcher{val: "-", want: "\"-\""}, + &litMatcher{val: "+", want: "\"+\""}, + &zeroOrOneExpr{ + expr: &litMatcher{val: "=", want: "\"=\""}, }, &ruleIRefExpr{index: 115 /* sp */}, &labeledExpr{ label: "text", - expr: &ruleIRefExpr{index: 123 /* e0 */}, + expr: &ruleIRefExpr{index: 26 /* exprRoot */}, textCapture: true, }, }, }, }, &actionExpr{ - run: (*parser).call_onst_modify_rest_19, + run: (*parser).call_onst_modify_rest_12, expr: &seqExpr{ exprs: []any{ &litMatcher{val: "-", want: "\"-\""}, @@ -3816,7 +3945,7 @@ var g = &grammar{ &ruleIRefExpr{index: 115 /* sp */}, &labeledExpr{ label: "text", - expr: &ruleIRefExpr{index: 123 /* e0 */}, + expr: &ruleIRefExpr{index: 26 /* exprRoot */}, textCapture: true, }, }, @@ -3837,11 +3966,11 @@ var g = &grammar{ expr: &seqExpr{ exprs: []any{ &oneOrMoreExpr{ - expr: &ruleIRefExpr{index: 138 /* id_ch0 */}, + expr: &ruleIRefExpr{index: 136 /* id_ch */}, }, &litMatcher{val: ":", want: "\":\""}, &oneOrMoreExpr{ - expr: &ruleIRefExpr{index: 138 /* id_ch0 */}, + expr: &ruleIRefExpr{index: 136 /* id_ch */}, }, }, }, @@ -3852,44 +3981,51 @@ var g = &grammar{ { name: "st_name1r", varExists: true, - expr: &actionExpr{ - run: (*parser).call_onst_name1r_1, - expr: &labeledExpr{ - label: "text", - expr: &oneOrMoreExpr{ - expr: &ruleIRefExpr{index: 138 /* id_ch0 */}, - }, - textCapture: true, - }, - }, - }, - { - name: "st_name2", - varExists: true, - expr: &actionExpr{ - run: (*parser).call_onst_name2_1, - expr: &labeledExpr{ - label: "text", - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 138 /* id_ch0 */}, - &zeroOrMoreExpr{ - expr: &ruleIRefExpr{index: 139 /* id_ch */}, + expr: &choiceExpr{ + alternatives: []any{ + &actionExpr{ + run: (*parser).call_onst_name1r_2, + expr: &labeledExpr{ + label: "text", + expr: &oneOrMoreExpr{ + expr: &ruleIRefExpr{index: 136 /* id_ch */}, }, - &seqExpr{ - exprs: []any{ - &litMatcher{val: ":", want: "\":\""}, - &oneOrMoreExpr{ - expr: &ruleIRefExpr{index: 139 /* id_ch */}, + textCapture: true, + }, + }, + &actionExpr{ + run: (*parser).call_onst_name1r_6, + expr: &seqExpr{ + exprs: []any{ + &litMatcher{val: "'", want: "\"'\""}, + &labeledExpr{ + label: "text", + expr: &oneOrMoreExpr{ + expr: &choiceExpr{ + alternatives: []any{ + &ruleIRefExpr{index: 136 /* id_ch */}, + &charClassMatcher{ + val: "[0-9]", + ranges: []rune{'0', '9'}, + }, + &litMatcher{val: " ", want: "\" \""}, + &litMatcher{val: ":", want: "\":\""}, + }, + }, }, + textCapture: true, }, + &litMatcher{val: "'", want: "\"'\""}, }, }, }, - textCapture: true, }, }, }, + { + name: "st_name2", + expr: &ruleIRefExpr{index: 132 /* st_name1 */}, + }, { name: "st_name2r", varExists: true, @@ -3899,19 +4035,14 @@ var g = &grammar{ run: (*parser).call_onst_name2r_2, expr: &labeledExpr{ label: "text", - expr: &seqExpr{ - exprs: []any{ - &ruleIRefExpr{index: 138 /* id_ch0 */}, - &zeroOrMoreExpr{ - expr: &ruleIRefExpr{index: 139 /* id_ch */}, - }, - }, + expr: &oneOrMoreExpr{ + expr: &ruleIRefExpr{index: 136 /* id_ch */}, }, textCapture: true, }, }, &actionExpr{ - run: (*parser).call_onst_name2r_8, + run: (*parser).call_onst_name2r_6, expr: &seqExpr{ exprs: []any{ &litMatcher{val: "'", want: "\"'\""}, @@ -3920,7 +4051,7 @@ var g = &grammar{ expr: &oneOrMoreExpr{ expr: &choiceExpr{ alternatives: []any{ - &ruleIRefExpr{index: 138 /* id_ch0 */}, + &ruleIRefExpr{index: 136 /* id_ch */}, &charClassMatcher{ val: "[0-9]", ranges: []rune{'0', '9'}, @@ -3939,10 +4070,6 @@ var g = &grammar{ }, }, }, - { - name: "id_ch0", - expr: &ruleIRefExpr{index: 92 /* xidStart */}, - }, { name: "id_ch", expr: &ruleIRefExpr{index: 92 /* xidStart */}, @@ -4034,7 +4161,7 @@ func (p *parser) call_onstmtWhile_4() any { })(&p.cur) } -func (p *parser) call_onstmtWhile_8() any { +func (p *parser) call_onstmtWhile_9() any { return (func(c *current) any { c.data.AddOp(typeJmp) c.data.OffsetPush() @@ -4056,7 +4183,7 @@ func (p *parser) call_onstmtIf_2() any { })(&p.cur) } -func (p *parser) call_onstmtIf_7() any { +func (p *parser) call_onstmtIf_8() any { return (func(c *current) any { c.data.AddOp(typeJmp) c.data.OffsetPopAndSet() @@ -4065,7 +4192,7 @@ func (p *parser) call_onstmtIf_7() any { })(&p.cur) } -func (p *parser) call_onstmtIf_9() any { +func (p *parser) call_onstmtIf_10() any { return (func(c *current) any { c.data.OffsetPopAndSet() return nil @@ -4361,7 +4488,7 @@ func (p *parser) call_onexprTernaryType2_4() any { })(&p.cur) } -func (p *parser) call_onexprLogicOr_6() any { +func (p *parser) call_onexprLogicOr_5() any { return (func(c *current) any { c.data.AddOp(typeJeDup) c.data.OffsetPush() @@ -4369,7 +4496,7 @@ func (p *parser) call_onexprLogicOr_6() any { })(&p.cur) } -func (p *parser) call_onexprLogicOr_8() any { +func (p *parser) call_onexprLogicOr_9() any { return (func(c *current) any { c.data.AddOp(typeJeDup) c.data.OffsetPush() @@ -4377,7 +4504,7 @@ func (p *parser) call_onexprLogicOr_8() any { })(&p.cur) } -func (p *parser) call_onexprLogicOr_10() any { +func (p *parser) call_onexprLogicOr_11() any { return (func(c *current) any { c.data.AddOp(typePushLast) c.data.OffsetPopAndSet() @@ -4386,7 +4513,7 @@ func (p *parser) call_onexprLogicOr_10() any { })(&p.cur) } -func (p *parser) call_onexprLogicAnd_5() any { +func (p *parser) call_onexprLogicAnd_4() any { return (func(c *current) any { c.data.AddOp(typeLogicAnd) return nil @@ -4399,105 +4526,105 @@ func (p *parser) call_onexprBitwiseOr_3() bool { })(&p.cur) } -func (p *parser) call_onexprBitwiseOr_9() any { +func (p *parser) call_onexprBitwiseOr_8() any { return (func(c *current) any { c.data.AddOp(typeBitwiseOr) return nil })(&p.cur) } -func (p *parser) call_onexprBitwiseAnd_5() any { +func (p *parser) call_onexprBitwiseAnd_4() any { return (func(c *current) any { c.data.AddOp(typeBitwiseAnd) return nil })(&p.cur) } -func (p *parser) call_onexprCompare_6() any { +func (p *parser) call_onexprCompare_7() any { return (func(c *current) any { c.data.AddOp(typeCompLT) return nil })(&p.cur) } -func (p *parser) call_onexprCompare_10() any { +func (p *parser) call_onexprCompare_11() any { return (func(c *current) any { c.data.AddOp(typeCompLE) return nil })(&p.cur) } -func (p *parser) call_onexprCompare_14() any { +func (p *parser) call_onexprCompare_15() any { return (func(c *current) any { c.data.AddOp(typeCompEQ) return nil })(&p.cur) } -func (p *parser) call_onexprCompare_18() any { +func (p *parser) call_onexprCompare_19() any { return (func(c *current) any { c.data.AddOp(typeCompNE) return nil })(&p.cur) } -func (p *parser) call_onexprCompare_22() any { +func (p *parser) call_onexprCompare_23() any { return (func(c *current) any { c.data.AddOp(typeCompGE) return nil })(&p.cur) } -func (p *parser) call_onexprCompare_26() any { +func (p *parser) call_onexprCompare_27() any { return (func(c *current) any { c.data.AddOp(typeCompGT) return nil })(&p.cur) } -func (p *parser) call_onexprAdditive_6() any { +func (p *parser) call_onexprAdditive_7() any { return (func(c *current) any { c.data.AddOp(typeAdd) return nil })(&p.cur) } -func (p *parser) call_onexprAdditive_10() any { +func (p *parser) call_onexprAdditive_11() any { return (func(c *current) any { c.data.AddOp(typeSubtract) return nil })(&p.cur) } -func (p *parser) call_onexprMultiplicative_6() any { +func (p *parser) call_onexprMultiplicative_7() any { return (func(c *current) any { c.data.AddOp(typeMultiply) return nil })(&p.cur) } -func (p *parser) call_onexprMultiplicative_10() any { +func (p *parser) call_onexprMultiplicative_11() any { return (func(c *current) any { c.data.AddOp(typeDivide) return nil })(&p.cur) } -func (p *parser) call_onexprMultiplicative_14() any { +func (p *parser) call_onexprMultiplicative_15() any { return (func(c *current) any { c.data.AddOp(typeModulus) return nil })(&p.cur) } -func (p *parser) call_onexprNullCoalescing_5() any { +func (p *parser) call_onexprNullCoalescing_4() any { return (func(c *current) any { c.data.AddOp(typeNullCoalescing) return nil })(&p.cur) } -func (p *parser) call_onexprExp_5() any { +func (p *parser) call_onexprExp_4() any { return (func(c *current) any { c.data.AddOp(typeExponentiation) return nil @@ -4906,7 +5033,7 @@ func (p *parser) call_onfunc_invoke_2() any { })(&p.cur) } -func (p *parser) call_onfunc_invoke_9() any { +func (p *parser) call_onfunc_invoke_8() any { return (func(c *current) any { c.data.CounterPush() c.data.CounterAdd(1) @@ -4921,7 +5048,7 @@ func (p *parser) call_onfunc_invoke_17() any { })(&p.cur) } -func (p *parser) call_onfunc_invoke_13() any { +func (p *parser) call_onfunc_invoke_12() any { return (func(c *current) any { c.data.AddInvoke(c.data.CounterPop()) return nil @@ -5136,7 +5263,7 @@ func (p *parser) call_onfstring_27() any { })(&p.cur) } -func (p *parser) call_onfstring_34() any { +func (p *parser) call_onfstring_36() any { return (func(c *current) any { c.data.CounterAdd(1) return nil @@ -5150,56 +5277,56 @@ func (p *parser) call_onfstring_22() any { })(&p.cur) } -func (p *parser) call_onfstring_43() any { +func (p *parser) call_onfstring_47() any { return (func(c *current) any { c.data.CounterPush() return nil })(&p.cur) } -func (p *parser) call_onfstring_50() any { +func (p *parser) call_onfstring_54() any { return (func(c *current) any { c.data.CounterAdd(1) return nil })(&p.cur) } -func (p *parser) call_onfstring_57() any { +func (p *parser) call_onfstring_63() any { return (func(c *current) any { c.data.CounterAdd(1) return nil })(&p.cur) } -func (p *parser) call_onfstring_45() any { +func (p *parser) call_onfstring_49() any { return (func(c *current) any { c.data.AddFormatString(c.data.CounterPop()) return nil })(&p.cur) } -func (p *parser) call_onfstring_66() any { +func (p *parser) call_onfstring_74() any { return (func(c *current) any { c.data.CounterPush() return nil })(&p.cur) } -func (p *parser) call_onfstring_68() any { +func (p *parser) call_onfstring_76() any { return (func(c *current) any { c.data.CounterPop() return nil })(&p.cur) } -func (p *parser) call_onfstring_74() any { +func (p *parser) call_onfstring_82() any { return (func(c *current) any { c.data.CounterPush() return nil })(&p.cur) } -func (p *parser) call_onfstring_76() any { +func (p *parser) call_onfstring_84() any { return (func(c *current) any { c.data.CounterPop() return nil @@ -5225,6 +5352,7 @@ func (p *parser) call_onest_7() any { c.data.FlagsPush() c.data.Config.DisableStmts = true c.data.Config.DisableNDice = true + c.data.Config.DisableBitwiseOp = true return nil })(&p.cur) } @@ -5243,69 +5371,67 @@ func (p *parser) call_onst_assign_2() any { })(&p.cur) } -func (p *parser) call_onst_assign_11() any { +func (p *parser) call_onst_assign_20() any { return (func(c *current) any { c.data.AddStName() return nil })(&p.cur) } -func (p *parser) call_onst_assign_15() any { +func (p *parser) call_onst_assign_28() any { return (func(c *current) any { c.data.AddOp(typeStX1) return nil })(&p.cur) } -func (p *parser) call_onst_assign_26() any { +func (p *parser) call_onst_assign_50() any { return (func(c *current) any { c.data.AddOp(typeStX0) return nil })(&p.cur) } -func (p *parser) call_onst_assign_37() any { +func (p *parser) call_onst_assign_72() any { return (func(c *current) any { c.data.AddStName() return nil })(&p.cur) } -func (p *parser) call_onst_assign_46() any { +func (p *parser) call_onst_assign_90() any { return (func(c *current) any { c.data.AddStName() return nil })(&p.cur) } -func (p *parser) call_onst_assign_51() any { +func (p *parser) call_onst_assign_99() any { return (func(c *current) any { c.data.CodePush() return nil })(&p.cur) } -func (p *parser) call_onst_assign_60() any { +func (p *parser) call_onst_assign_117() any { stack := p.vstack[len(p.vstack)-1] return (func(c *current, text any) any { - c.data.CodePop() c.data.AddStoreComputedOnStack(text.(string)) c.data.AddStName() return nil })(&p.cur, stack["text"]) } -func (p *parser) call_onst_assign_64() any { +func (p *parser) call_onst_assign_121() any { return (func(c *current) any { c.data.CodePush() return nil })(&p.cur) } -func (p *parser) call_onst_assign_73() any { +func (p *parser) call_onst_assign_139() any { stack := p.vstack[len(p.vstack)-1] return (func(c *current, text any) any { - c.data.CodePop() c.data.AddStoreComputedOnStack(text.(string)) c.data.AddStName() return nil @@ -5344,14 +5470,6 @@ func (p *parser) call_onst_modify_rest_12() any { })(&p.cur, stack["text"]) } -func (p *parser) call_onst_modify_rest_19() any { - stack := p.vstack[len(p.vstack)-1] - return (func(c *current, text any) any { - c.data.AddStModify("-", text.(string)) - return nil - })(&p.cur, stack["text"]) -} - func (p *parser) call_onst_name1_1() any { stack := p.vstack[len(p.vstack)-1] return (func(c *current, text any) any { @@ -5360,7 +5478,7 @@ func (p *parser) call_onst_name1_1() any { })(&p.cur, stack["text"]) } -func (p *parser) call_onst_name1r_1() any { +func (p *parser) call_onst_name1r_2() any { stack := p.vstack[len(p.vstack)-1] return (func(c *current, text any) any { c.data.PushStr(text.(string)) @@ -5368,7 +5486,7 @@ func (p *parser) call_onst_name1r_1() any { })(&p.cur, stack["text"]) } -func (p *parser) call_onst_name2_1() any { +func (p *parser) call_onst_name1r_6() any { stack := p.vstack[len(p.vstack)-1] return (func(c *current, text any) any { c.data.PushStr(text.(string)) @@ -5384,7 +5502,7 @@ func (p *parser) call_onst_name2r_2() any { })(&p.cur, stack["text"]) } -func (p *parser) call_onst_name2r_8() any { +func (p *parser) call_onst_name2r_6() any { stack := p.vstack[len(p.vstack)-1] return (func(c *current, text any) any { c.data.PushStr(text.(string)) diff --git a/rollvm.go b/rollvm.go index 8fb2a974..1b37337a 100644 --- a/rollvm.go +++ b/rollvm.go @@ -825,7 +825,7 @@ func (ctx *Context) evaluate() { stName, stVal := stackPop2() if e.Config.CallbackSt != nil { name, _ := stName.ReadString() - e.Config.CallbackSt("set", name, stVal, nil, "", "") + e.Config.CallbackSt("set", name, stVal.Clone(), nil, "", "") } case typeStModify: stName, stVal := stackPop2() @@ -833,13 +833,13 @@ func (ctx *Context) evaluate() { if e.Config.CallbackSt != nil { name, _ := stName.ReadString() - e.Config.CallbackSt("mod", name, stVal, nil, stInfo.Op, stInfo.Text) + e.Config.CallbackSt("mod", name, stVal.Clone(), nil, stInfo.Op, stInfo.Text) } case typeStX0: stName, stVal := stackPop2() if e.Config.CallbackSt != nil { name, _ := stName.ReadString() - e.Config.CallbackSt("set.x0", name, stVal, nil, "", "") + e.Config.CallbackSt("set.x0", name, stVal.Clone(), nil, "", "") } case typeStX1: stVal := stackPop() @@ -847,7 +847,7 @@ func (ctx *Context) evaluate() { stName := stackPop() if e.Config.CallbackSt != nil { name, _ := stName.ReadString() - e.Config.CallbackSt("set.x1", name, stVal, stExtra, "", "") + e.Config.CallbackSt("set.x1", name, stVal.Clone(), stExtra.Clone(), "", "") } } } diff --git a/rollvm_st_test.go b/rollvm_st_test.go index e4710fc0..3ed1fe8f 100644 --- a/rollvm_st_test.go +++ b/rollvm_st_test.go @@ -5,7 +5,24 @@ import ( "testing" ) -func TestStBasic(t *testing.T) { +type checkItem struct { + Name string + Value *VMValue + Extra *VMValue + Type string + Op string +} + +func (item *checkItem) check(t *testing.T, _type string, name string, val *VMValue, extra *VMValue, op string, detail string) { + assert.Equal(t, name, item.Name) + assert.True(t, valueEqual(val, item.Value)) + if item.Extra != nil { + assert.True(t, valueEqual(extra, item.Extra)) + } + assert.Equal(t, _type, item.Type) +} + +func TestStSetBasic(t *testing.T) { vm := NewVM() vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { @@ -19,7 +36,78 @@ func TestStBasic(t *testing.T) { assert.NoError(t, err) } -func TestStBasicMod(t *testing.T) { +func TestStSet(t *testing.T) { + vm := NewVM() + items := []checkItem{ + checkItem{Name: "力量", Value: ni(60), Type: "set"}, + checkItem{Name: "敏捷", Value: ni(70), Type: "set"}, + } + + index := 0 + vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { + items[index].check(t, _type, name, val, extra, op, detail) + index += 1 + } + + err := vm.Run(`^st力量60敏捷70`) + assert.NoError(t, err) +} + +func TestStSet2(t *testing.T) { + vm := NewVM() + items := []checkItem{ + checkItem{Name: "力量", Value: ni(60), Type: "set"}, + checkItem{Name: "敏捷", Value: ni(70), Type: "set"}, + } + + index := 0 + vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { + items[index].check(t, _type, name, val, extra, op, detail) + index += 1 + } + + err := vm.Run(`^st力量60 敏捷70`) + assert.NoError(t, err) +} + +func TestStSet3(t *testing.T) { + vm := NewVM() + items := []checkItem{ + checkItem{Name: "智力", Value: ni(80), Type: "set"}, + checkItem{Name: "知识", Value: ni(90), Type: "set"}, + } + + index := 0 + vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { + items[index].check(t, _type, name, val, extra, op, detail) + index += 1 + } + + err := vm.Run(`^st智力:80 知识=90`) + assert.NoError(t, err) +} + +func TestStSetCompute(t *testing.T) { + vm := NewVM() + items := []checkItem{ + checkItem{Name: "射击", Value: NewComputedVal("1d6"), Type: "set"}, + checkItem{Name: "射击", Value: NewComputedVal("(1d6)"), Type: "set"}, + } + + index := 0 + vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { + // fmt.Println("!!!", _type, name, val, extra, op, detail, val.ToRepr()) // 注: 最后一个值在IDEA中的输出可能不正常,中间加了空格,实际没有 + items[index].check(t, _type, name, val, extra, op, detail) + index += 1 + } + + // err := vm.Run(`^st&射击=1d6 `) + err := vm.Run(`^st&射击=1d6 &射击=(1d6)`) + assert.NoError(t, err) + assert.Equal(t, index, 2) +} + +func TestStModBasic(t *testing.T) { vm := NewVM() vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { @@ -33,7 +121,7 @@ func TestStBasicMod(t *testing.T) { assert.NoError(t, err) } -func TestStBasicStX0(t *testing.T) { +func TestStSetX0Basic(t *testing.T) { vm := NewVM() vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { @@ -47,7 +135,7 @@ func TestStBasicStX0(t *testing.T) { assert.NoError(t, err) } -func TestStBasicStX1(t *testing.T) { +func TestStSetX1Basic(t *testing.T) { vm := NewVM() vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { @@ -61,3 +149,60 @@ func TestStBasicStX1(t *testing.T) { err := vm.Run(`^stA*2.1: 3`) assert.NoError(t, err) } + +func TestStMod(t *testing.T) { + vm := NewVM() + + items := []checkItem{ + checkItem{Name: "力量", Value: ni(3), Type: "mod"}, + checkItem{Name: "敏捷", Value: ni(3), Type: "mod"}, + } + + index := 0 + vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { + // fmt.Println("!!", _type, name, val, extra, op, detail) + items[index].check(t, _type, name, val, extra, op, detail) + index += 1 + } + + err := vm.Run(`^st力量+3d1 敏捷+=3 `) + assert.NoError(t, err) +} + +func TestStMod1(t *testing.T) { + vm := NewVM() + items := []checkItem{ + checkItem{Name: "力量", Value: ni(1), Type: "mod"}, + checkItem{Name: "力量", Value: ni(4), Type: "mod"}, + checkItem{Name: "力量", Value: ni(6), Type: "mod"}, + checkItem{Name: "力量", Value: ni(6), Type: "mod", Op: "-"}, + } + + index := 0 + vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { + // fmt.Println("!!", _type, name, val, extra, op, detail) + items[index].check(t, _type, name, val, extra, op, detail) + index += 1 + } + + err := vm.Run(`^st力量+1力量+4d1力量+4d1+2力量-4d1+2`) + assert.NoError(t, err) +} + +func TestStMod2(t *testing.T) { + vm := NewVM() + + items := []checkItem{ + checkItem{Name: "力量123", Value: ni(3), Type: "mod"}, + } + + index := 0 + vm.Config.CallbackSt = func(_type string, name string, val *VMValue, extra *VMValue, op string, detail string) { + // fmt.Println("!!", _type, name, val, extra, op, detail) + items[index].check(t, _type, name, val, extra, op, detail) + index += 1 + } + + err := vm.Run(`^st'力量123'+=3`) + assert.NoError(t, err) +} diff --git a/rollvm_test.go b/rollvm_test.go index 8b14cb15..bbc13dcc 100644 --- a/rollvm_test.go +++ b/rollvm_test.go @@ -219,6 +219,14 @@ func TestValueStore(t *testing.T) { assert.True(t, vmValueEqual(vm, "d", ni(2))) } +func TestIfBasic(t *testing.T) { + vm := NewVM() + err := vm.Run("if 1 { a = 2 } ") + if assert.NoError(t, err) { + assert.True(t, vmValueEqual(vm, "a", ni(2))) + } +} + func TestIf(t *testing.T) { vm := NewVM() err := vm.Run("if 0 { a = 2 } else if 2 { b = 1 } c= 1; ;;;;; d= 2;b") diff --git a/types.go b/types.go index c6bed5ec..c37a8c41 100644 --- a/types.go +++ b/types.go @@ -533,7 +533,7 @@ func (v *VMValue) toReprRaw(ri *recursionInfo) string { } func (v *VMValue) ToRepr() string { - ri := &recursionInfo{exists: map[interface{}]bool{}} + ri := &recursionInfo{exists: map[any]bool{}} return v.toReprRaw(ri) } @@ -1553,6 +1553,10 @@ func ValueEqual(a *VMValue, b *VMValue, autoConvert bool) bool { return true }) return isSame + case VMTypeComputedValue: + c1, _ := a.ReadComputed() + c2, _ := b.ReadComputed() + return c1.Expr == c2.Expr case VMTypeNativeFunction: fd1, _ := a.ReadNativeFunctionData() fd2, _ := b.ReadNativeFunctionData() diff --git a/valuemap.go b/valuemap.go index d6628aa5..05f77976 100644 --- a/valuemap.go +++ b/valuemap.go @@ -7,6 +7,8 @@ package dicescript import ( + "bytes" + "encoding/json" "sync" "sync/atomic" "unsafe" @@ -392,3 +394,36 @@ func (e *entryValueMap) tryExpungeLocked() (isExpunged bool) { } return p == expungedValueMap } + +func (m *ValueMap) ToJSON() ([]byte, error) { + lst := [][]byte{} + var err error + save := map[*VMValue]bool{} + m.Range(func(key string, value *VMValue) bool { + var jsonKey []byte + var jsonData []byte + jsonData, err = value.ToJSONRaw(save) + if err != nil { + return false + } + jsonKey, err = json.Marshal(key) + if err != nil { + return false + } + + b := append(jsonKey, []byte(":")...) + b = append(b, jsonData...) + + lst = append(lst, b) + return true + }) + if err != nil { + return nil, err + } + + lst2 := [][]byte{[]byte(`{`)} + lst2 = append(lst2, bytes.Join(lst, []byte(","))) + lst2 = append(lst2, []byte("}")) + + return bytes.Join(lst2, []byte("")), nil +}