diff --git a/src/core/Function.go b/src/core/Function.go index 37024df..1241c9f 100644 --- a/src/core/Function.go +++ b/src/core/Function.go @@ -23,6 +23,7 @@ type Function struct { name string pkg string body token.Source + constantStack []*Constant valueToStruct map[ssa.Value]*ssa.Struct loopStack ssa.IR diff --git a/src/core/errors_test.go b/src/core/errors_test.go index 26d7809..c635c81 100644 --- a/src/core/errors_test.go +++ b/src/core/errors_test.go @@ -23,6 +23,8 @@ var errs = []struct { {"AlwaysFalse2.q", core.AlwaysFalse}, {"AlwaysFalse3.q", core.AlwaysFalse}, {"AlwaysFalse4.q", core.AlwaysFalse}, + // {"CycleDetected.q", &core.CycleDetected{A: "A", B: "B"}}, // TODO: deterministic output + {"CycleDetected2.q", &core.CycleDetected{A: "y", B: "x"}}, {"DefinitionCountMismatch.q", &core.DefinitionCountMismatch{Function: "main.swap", Count: 1, ExpectedCount: 2}}, {"DefinitionCountMismatch2.q", &core.DefinitionCountMismatch{Function: "main.swap", Count: 3, ExpectedCount: 2}}, {"DefinitionCountMismatch3.q", &core.DefinitionCountMismatch{Function: "main.nothing", Count: 1, ExpectedCount: 0}}, diff --git a/src/core/evaluatePackageMember.go b/src/core/evaluatePackageMember.go index a870a53..1f8ca6c 100644 --- a/src/core/evaluatePackageMember.go +++ b/src/core/evaluatePackageMember.go @@ -1,6 +1,8 @@ package core import ( + "slices" + "git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/expression" "git.urbach.dev/cli/q/src/ssa" @@ -12,10 +14,16 @@ func (f *Function) evaluatePackageMember(pkg *Package, rightText string, expr *e constant, exists := pkg.Constants[rightText] if exists { + if slices.Contains(f.constantStack, constant) { + return nil, errors.New(&CycleDetected{A: f.constantStack[len(f.constantStack)-1].Name, B: constant.Name}, f.File, expr.Source()) + } + + f.constantStack = append(f.constantStack, constant) tmp := f.File f.File = constant.File v, err := f.evaluateRight(constant.Value) f.File = tmp + f.constantStack = f.constantStack[:len(f.constantStack)-1] return v, err } diff --git a/src/core/testdata/CycleDetected2.q b/src/core/testdata/CycleDetected2.q new file mode 100644 index 0000000..63a51b2 --- /dev/null +++ b/src/core/testdata/CycleDetected2.q @@ -0,0 +1,9 @@ +const { + x = z + y = x + z = y +} + +main() { + a := x +} \ No newline at end of file