diff --git a/pkg/hintrunner/zero/hintcode.go b/pkg/hintrunner/zero/hintcode.go index 71a6fca2..7bb2d717 100644 --- a/pkg/hintrunner/zero/hintcode.go +++ b/pkg/hintrunner/zero/hintcode.go @@ -84,7 +84,8 @@ const ( // ------ Dictionaries hints related code ------ // ------ Other hints related code ------ - allocSegmentCode string = "memory[ap] = segments.add()" - vmEnterScopeCode string = "vm_enter_scope()" - vmExitScopeCode string = "vm_exit_scope()" + allocSegmentCode string = "memory[ap] = segments.add()" + memcpyEnterScopeCode string = "vm_enter_scope({'n': ids.len})" + vmEnterScopeCode string = "vm_enter_scope()" + vmExitScopeCode string = "vm_exit_scope()" ) diff --git a/pkg/hintrunner/zero/zerohint.go b/pkg/hintrunner/zero/zerohint.go index 35ebdd7d..878e3994 100644 --- a/pkg/hintrunner/zero/zerohint.go +++ b/pkg/hintrunner/zero/zerohint.go @@ -147,6 +147,8 @@ func GetHintFromCode(program *zero.ZeroProgram, rawHint zero.Hint, hintPC uint64 return createAllocSegmentHinter(resolver) case vmEnterScopeCode: return createVMEnterScopeHinter(resolver) + case memcpyEnterScopeCode: + return createMemcpyEnterScopeHinter(resolver) case vmExitScopeCode: return createVMExitScopeHinter(resolver) case testAssignCode: diff --git a/pkg/hintrunner/zero/zerohint_memcpy.go b/pkg/hintrunner/zero/zerohint_memcpy.go index 31c5fc87..bef67555 100644 --- a/pkg/hintrunner/zero/zerohint_memcpy.go +++ b/pkg/hintrunner/zero/zerohint_memcpy.go @@ -20,6 +20,29 @@ func createVMEnterScopeHinter(resolver hintReferenceResolver) (hinter.Hinter, er }, nil } +func newMemcpyEnterScopeHint(len hinter.ResOperander) hinter.Hinter { + return &GenericZeroHinter{ + Name: "MemcpyEnterScope", + Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { + //> vm_enter_scope({'n': ids.len}) + len, err := hinter.ResolveAsFelt(vm, len) + if err != nil { + return err + } + ctx.ScopeManager.EnterScope(map[string]any{"n": len}) + return nil + }, + } +} + +func createMemcpyEnterScopeHinter(resolver hintReferenceResolver) (hinter.Hinter, error) { + len, err := resolver.GetResOperander("len") + if err != nil { + return nil, err + } + return newMemcpyEnterScopeHint(len), nil +} + func createVMExitScopeHinter(resolver hintReferenceResolver) (hinter.Hinter, error) { return &GenericZeroHinter{ Name: "VMExitScope", diff --git a/pkg/hintrunner/zero/zerohint_memcpy_test.go b/pkg/hintrunner/zero/zerohint_memcpy_test.go new file mode 100644 index 00000000..0c2da90a --- /dev/null +++ b/pkg/hintrunner/zero/zerohint_memcpy_test.go @@ -0,0 +1,27 @@ +package zero + +import ( + "testing" + + "github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/hinter" +) + +func TestZeroHintMemcpy(t *testing.T) { + + runHinterTests(t, map[string][]hintTestCase{ + "MemcpyEnterScope": { + { + operanders: []*hintOperander{ + {Name: "len", Kind: apRelative, Value: feltUint64(1)}, + }, + ctxInit: func(ctx *hinter.HintRunnerContext) { + hinter.InitializeScopeManager(ctx, map[string]any{}) + }, + makeHinter: func(ctx *hintTestContext) hinter.Hinter { + return newMemcpyEnterScopeHint(ctx.operanders["len"]) + }, + check: varValueInScopeEquals("n", feltUint64(1)), + }, + }, + }) +}