diff --git a/example_basiccalculator2_test.go b/example_basiccalculator2_test.go index de807eb..c5356d7 100644 --- a/example_basiccalculator2_test.go +++ b/example_basiccalculator2_test.go @@ -98,11 +98,11 @@ func (c *calculator) expr(p *parsekit.ParseAPI) { var pc, a = parsekit.C, parsekit.A if p.Handle(c.term) { for p.On(pc.Any(a.Add, a.Subtract)).Skip() { - c.interpreter.pushOperator(p.LastMatch) + op := p.LastMatch if !p.Handle(c.term) { return } - c.interpreter.eval() + c.interpreter.eval(op) } } @@ -116,11 +116,11 @@ func (c *calculator) term(p *parsekit.ParseAPI) { var pc, a = parsekit.C, parsekit.A if p.Handle(c.factor) { for p.On(pc.Any(a.Multiply, a.Divide)).Skip() { - c.interpreter.pushOperator(p.LastMatch) + op := p.LastMatch if !p.Handle(c.factor) { return } - c.interpreter.eval() + c.interpreter.eval(op) } } @@ -164,9 +164,8 @@ func (c *calculator) factor(p *parsekit.ParseAPI) { // --------------------------------------------------------------------------- type stackFrame struct { - a float64 - b float64 - op func(a, b float64) float64 + a float64 + b float64 } type interpreter struct { @@ -175,51 +174,38 @@ type interpreter struct { result float64 } -func (i *interpreter) push() *stackFrame { +func (i *interpreter) push() { f := &stackFrame{} - i.stack = append(i.stack, f) - i.top = f - i.pushOperator("VAL") - return f + i.top, i.stack = f, append(i.stack, f) } -func (i *interpreter) pop() float64 { - value := i.eval() +func (i *interpreter) pop() { + popped := i.top i.stack = i.stack[0 : len(i.stack)-1] if len(i.stack) > 0 { i.top = i.stack[len(i.stack)-1] - i.pushValue(value) + i.pushValue(popped.b) } else { - i.result = i.top.b - i.top = nil + i.result = popped.b } - return value } func (i *interpreter) pushValue(value float64) { i.top.a, i.top.b = i.top.b, value } -func (i *interpreter) pushOperator(op string) { +func (i *interpreter) eval(op string) float64 { + value := i.top.a switch op { - case "VAL": - i.top.op = func(a, b float64) float64 { return b } case "+": - i.top.op = func(a, b float64) float64 { return a + b } + value += i.top.b case "-": - i.top.op = func(a, b float64) float64 { return a - b } + value -= i.top.b case "*": - i.top.op = func(a, b float64) float64 { return a * b } + value *= i.top.b case "/": - i.top.op = func(a, b float64) float64 { return a / b } - default: - panic(fmt.Sprintf("Unhandled op name: %s", op)) + value /= i.top.b } -} - -func (i *interpreter) eval() float64 { - value := i.top.op(i.top.a, i.top.b) - i.pushValue(value) - i.pushOperator("VAL") + i.top.b = value return value } diff --git a/parsehandler.go b/parsehandler.go index 0020844..001d297 100644 --- a/parsehandler.go +++ b/parsehandler.go @@ -68,7 +68,7 @@ func (p *ParseAPI) checkForLoops() { id := fmt.Sprintf("%s:%d", file, line) if _, ok := p.loopCheck[id]; ok { caller := runtime.FuncForPC(pc) - panic(fmt.Sprintf("Loop detected in parser in %s at %s, line %d", caller.Name(), file, line)) + panic(fmt.Sprintf("Loop detected in parser in %s at %s", caller.Name(), id)) } p.loopCheck[id] = true } diff --git a/parsehandler_test.go b/parsehandler_test.go index cf654aa..487a39e 100644 --- a/parsehandler_test.go +++ b/parsehandler_test.go @@ -1,7 +1,6 @@ package parsekit_test import ( - "fmt" "testing" "git.makaay.nl/mauricem/go-parsekit" @@ -105,7 +104,7 @@ func TestGivenLoopingParserDefinition_ParserPanics(t *testing.T) { func() { parser.Execute("Het houdt niet op, niet vanzelf") }, "Loop detected in parser in git.makaay.nl/mauricem/go-parsekit_test." + "(*parserWithLoop).second at /home/ubuntu/Projects/Parsekit/go-parsekit" + - "/parsehandler_test.go, line 87"}) + "/parsehandler_test.go:87"}) } // This test incorporates an actual loop bug that I dropped on myself and @@ -124,7 +123,6 @@ func TestGivenLoopingParserDefinition_ParserPanics(t *testing.T) { func TestGivenLoopingParserDefinition2_ParserPanics(t *testing.T) { parser := parsekit.NewParser(func(p *parsekit.ParseAPI) { for p.On(c.Max(5, a.AnyRune)).Accept() { - fmt.Printf("Cycle: %s\n", p.BufLiteral()) p.BufClear() } p.Stop() @@ -133,5 +131,5 @@ func TestGivenLoopingParserDefinition2_ParserPanics(t *testing.T) { func() { parser.Execute("This will end soon") }, "Loop detected in parser in git.makaay.nl/mauricem/go-parsekit_test." + "TestGivenLoopingParserDefinition2_ParserPanics.func1 at " + - "/home/ubuntu/Projects/Parsekit/go-parsekit/parsehandler_test.go, line 126"}) + "/home/ubuntu/Projects/Parsekit/go-parsekit/parsehandler_test.go:125"}) }