From 44cc030fb24d69cd2a3e6eb72b7856ae6ee97808 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Thu, 2 Jul 2026 15:23:49 +0200 Subject: [PATCH] Added an error message for loop control without loops --- src/core/compileLoopControl.go | 5 +++++ src/core/errors.go | 1 + src/core/errors_test.go | 1 + src/core/loopStack.go | 6 +++++- src/core/testdata/LoopControlWithoutLoop.q | 3 +++ 5 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/core/testdata/LoopControlWithoutLoop.q diff --git a/src/core/compileLoopControl.go b/src/core/compileLoopControl.go index fca34e9..af750c8 100644 --- a/src/core/compileLoopControl.go +++ b/src/core/compileLoopControl.go @@ -19,6 +19,11 @@ func (f *Function) compileLoopControl(control *ast.LoopControl) error { } loop := f.loopStack.Current() + + if loop == nil { + return errors.New(LoopControlWithoutLoop, f.File, control.Expression.Source()) + } + name := call.Children[0].Token.StringFrom(f.File.Bytes) switch name { diff --git a/src/core/errors.go b/src/core/errors.go index 7a60e91..5882e54 100644 --- a/src/core/errors.go +++ b/src/core/errors.go @@ -22,6 +22,7 @@ var ( InvalidNumber = errors.String("Invalid number") InvalidRune = errors.String("Invalid rune") InvalidStructOperation = errors.String("Invalid operation on structs") + LoopControlWithoutLoop = errors.String("Loop control without a loop") MissingCommaBetweenFields = errors.String("Missing ',' between struct fields") MissingFieldName = errors.String("Missing field name") MissingObject = errors.String("Missing object or identifier") diff --git a/src/core/errors_test.go b/src/core/errors_test.go index 8fd0bc5..f01b1df 100644 --- a/src/core/errors_test.go +++ b/src/core/errors_test.go @@ -59,6 +59,7 @@ var errs = []struct { {"InvalidLoopHeader.q", core.InvalidLoopHeader}, {"InvalidStructOperation.q", core.InvalidStructOperation}, {"InvalidStructOperation2.q", core.InvalidStructOperation}, + {"LoopControlWithoutLoop.q", core.LoopControlWithoutLoop}, {"MissingFieldName.q", core.MissingFieldName}, {"MissingFieldName2.q", core.MissingFieldName}, {"MissingObject.q", core.MissingObject}, diff --git a/src/core/loopStack.go b/src/core/loopStack.go index e013dd8..10c9228 100644 --- a/src/core/loopStack.go +++ b/src/core/loopStack.go @@ -5,8 +5,12 @@ type loopStack struct { loops []*Loop } -// Current returns the innermost loop. +// Current returns the innermost loop or nil if there is none. func (s *loopStack) Current() *Loop { + if len(s.loops) == 0 { + return nil + } + return s.loops[len(s.loops)-1] } diff --git a/src/core/testdata/LoopControlWithoutLoop.q b/src/core/testdata/LoopControlWithoutLoop.q new file mode 100644 index 0000000..52e1ae5 --- /dev/null +++ b/src/core/testdata/LoopControlWithoutLoop.q @@ -0,0 +1,3 @@ +main() { + loop.stop() +} \ No newline at end of file -- 2.51.2