From 0e5e379b722e1f19c5da64db76eb3c4c6f3b1124 Mon Sep 17 00:00:00 2001 From: fy Date: Sun, 23 Jun 2024 14:54:36 +0800 Subject: [PATCH] =?UTF-8?q?imp:=20=E6=94=B9=E8=BF=9Bst=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ README.md | 4 ++-- roll.peg | 6 +++--- roll.peg.go | 29 +++++++++++++++++++++++++---- rollvm.go | 4 ++++ rollvm_st_test.go | 41 ++++++++++++++++++++++++++++++++++++++++- 6 files changed, 78 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 131a2fa1..207d9e45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## 更新记录 +#### 2024.6.23 +* 重写计算过程机制 +* 改进st兼容问题 + #### 2024.6.18 * round ceil floor 允许输入int类型 * 加入新函数load用于动态载入变量 diff --git a/README.md b/README.md index 56fdebc3..19824e72 100644 --- a/README.md +++ b/README.md @@ -83,11 +83,11 @@ DiceScript将更好的实现骰点功能,语法规范化的同时,具有更 ## TODO -* d2d(4d4d5)d6 计算过程问题 +* ~~d2d(4d4d5)d6 计算过程问题~~ ## 开发 -如果修改了文法: +如果修改了文法,使用这个工具重新生成: ``` go install github.com/fy0/pigeon@latest pigeon -nolint -optimize-parser -optimize-ref-expr-by-index -o .\roll.peg.go .\roll.peg diff --git a/roll.peg b/roll.peg index 445bfbaa..10e9da6f 100644 --- a/roll.peg +++ b/roll.peg @@ -491,13 +491,13 @@ st_modify_multi_rest <- (st_modify_lead sp ','? sp)* st_modify_rest1 <- sp ( "+=" 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_modify_rest <- sp ( '+' '='? sp text:< exprRoot > {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))} / + &( '-' ) sp text:< exprRoot > {c.data.AddStModify("-", text.(string))} // 这一个式子是为了兼容st a-1-1视为a-2 ) st_name1 <- text:<( id_ch+ ":" id_ch+ )> { c.data.PushStr(text.(string)) } // 结尾不带数字 diff --git a/roll.peg.go b/roll.peg.go index 9cb57410..01c5ae06 100644 --- a/roll.peg.go +++ b/roll.peg.go @@ -4015,9 +4015,22 @@ var g = &grammar{ run: (*parser).call_onst_modify_rest_12, expr: &seqExpr{ exprs: []any{ - &litMatcher{val: "-", want: "\"-\""}, - &zeroOrOneExpr{ - expr: &litMatcher{val: "=", want: "\"=\""}, + &litMatcher{val: "-=", want: "\"-=\""}, + &ruleIRefExpr{index: 122 /* sp */}, + &labeledExpr{ + label: "text", + expr: &ruleIRefExpr{index: 26 /* exprRoot */}, + textCapture: true, + }, + }, + }, + }, + &actionExpr{ + run: (*parser).call_onst_modify_rest_18, + expr: &seqExpr{ + exprs: []any{ + &andExpr{ + expr: &litMatcher{val: "-", want: "\"-\""}, }, &ruleIRefExpr{index: 122 /* sp */}, &labeledExpr{ @@ -5658,7 +5671,7 @@ func (p *parser) call_onst_modify_rest1_4() any { func (p *parser) call_onst_modify_rest1_10() any { stack := p.vstack[len(p.vstack)-1] return (func(c *current, text any) any { - c.data.AddStModify("-", text.(string)) + c.data.AddStModify("-=", text.(string)) return nil })(&p.cur, stack["text"]) } @@ -5672,6 +5685,14 @@ func (p *parser) call_onst_modify_rest_4() any { } func (p *parser) call_onst_modify_rest_12() 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_modify_rest_18() any { stack := p.vstack[len(p.vstack)-1] return (func(c *current, text any) any { c.data.AddStModify("-", text.(string)) diff --git a/rollvm.go b/rollvm.go index b13747bd..dba7da65 100644 --- a/rollvm.go +++ b/rollvm.go @@ -950,6 +950,10 @@ func (ctx *Context) evaluate() { if e.Config.CallbackSt != nil { name, _ := stName.ReadString() + if stInfo.Op == "-" { + // 负号取正,以免-和-=出现符号一正一反的情况 + stVal = stVal.OpNegation() + } e.Config.CallbackSt("mod", name, stVal.Clone(), nil, stInfo.Op, stInfo.Text) } case typeStX0: diff --git a/rollvm_st_test.go b/rollvm_st_test.go index 3ed1fe8f..7e9dad74 100644 --- a/rollvm_st_test.go +++ b/rollvm_st_test.go @@ -19,6 +19,9 @@ func (item *checkItem) check(t *testing.T, _type string, name string, val *VMVal if item.Extra != nil { assert.True(t, valueEqual(extra, item.Extra)) } + if item.Op != "" { + assert.Equal(t, op, item.Op) + } assert.Equal(t, _type, item.Type) } @@ -175,7 +178,7 @@ func TestStMod1(t *testing.T) { 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: "-"}, + checkItem{Name: "力量", Value: ni(2), Type: "mod", Op: "-"}, } index := 0 @@ -206,3 +209,39 @@ func TestStMod2(t *testing.T) { err := vm.Run(`^st'力量123'+=3`) assert.NoError(t, err) } + +func TestStModMinus(t *testing.T) { + vm := NewVM() + + items := []checkItem{ + checkItem{Name: "力量", Value: ni(4), 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力量-3d1-1 `) + assert.NoError(t, err) +} + +func TestStModMinus2(t *testing.T) { + vm := NewVM() + + items := []checkItem{ + checkItem{Name: "力量", Value: ni(2), 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力量-=3d1-1 `) + assert.NoError(t, err) +}