/*---------------------------------------------------------------------------
  Copyright 2012-2025, Microsoft Research, Daan Leijen.

  This is free software; you can redistribute it and/or modify it under the
  terms of the Apache License, Version 2.0. A copy of the License can be
  found in the LICENSE file at the root of this distribution.
---------------------------------------------------------------------------*/

// Internal functions to support lazy constructors
//
module std/core/lazystd/core/lazy

import std/core/typesstd/core/types

// note: all of the following definitions will be made hidden (prefix with `@`)
// in the future and are only exposed for now for experimentation

// internal: marker for lazy values that will be memoized (used to for correct reuse and reference counting)
pub fip extern memoize-targetstd/core/lazy/memoize-target: forall<a> (target : a, size : int, scan-size : int) -> ()(^targettarget: $43 : aa: V, sizesize: int : intstd/core/types/int: V, scan-sizescan-size: int : intstd/core/types/int: V) : (std/core/types/unit: V)std/core/types/unit: V
  inline "/**/"

// internal: explicitly force update-in-place for lazy values
pub fip extern memoizestd/core/lazy/memoize: forall<a> (target : a, x : a) -> a(targettarget: $64 : aa: V, xx: $64 : aa: V) : astd/core/types/total: E
  inline "#1"

// internal: atomically set a lazy value to locked (or return `false` if already memoized)
pub inline fip extern atomic-enterstd/core/lazy/atomic-enter: forall<a> (target : a, lazy-tag : int32) -> bool(^target : aa: V, lazy-tag: int32std/core/types/int32: V ) : boolstd/core/types/bool: V
  c "kk_lazy_atomic_enter"

// internal: release an atomically memoized lazy value
pub inline fip extern atomic-leavestd/core/lazy/atomic-leave: forall<a> (target : a) -> ()(target : aa: V) : (std/core/types/unit: V)std/core/types/unit: V
  c "kk_lazy_atomic_leave"


// internal: test if a lazy value is in whnf
pub inline fip extern datatype-is-whnfstd/core/lazy/datatype-is-whnf: forall<a> (x : a, lazy-tag : int32) -> bool(^x:aa: V, lazy-tag:int32std/core/types/int32: V) : boolstd/core/types/bool: V
  c "kk_datatype_is_whnf"

// internal: test if a heap allocated lazy value is in whnf
pub inline fip extern datatype-ptr-is-whnfstd/core/lazy/datatype-ptr-is-whnf: forall<a> (x : a, lazy-tag : int32) -> bool(^x:aa: V, lazy-tag:int32std/core/types/int32: V) : boolstd/core/types/bool: V
  c "kk_datatype_ptr_is_whnf"


// internal: test if a heap allocated data type is unique
pub inline fip extern datatype-ptr-is-uniquestd/core/lazy/datatype-ptr-is-unique: forall<a> (x : a) -> bool(^x:aa: V) : boolstd/core/types/bool: V
  c "kk_datatype_ptr_is_unique"

// internal: test if a heap allocated data type is thread-shared
pub inline fip extern datatype-ptr-is-thread-sharedstd/core/lazy/datatype-ptr-is-thread-shared: forall<a> (x : a) -> bool(^x : aa: V) : boolstd/core/types/bool: V
  c "kk_datatype_ptr_is_thread_shared"


// internal: compress indirection chains
pub inline fip extern indirect-compressstd/core/lazy/indirect-compress: forall<a> (value : a, lazy-tag : int32) -> a(value : aa: V, lazy-tag:int32std/core/types/int32: V) : astd/core/types/total: E
  c "kk_indirect_compress"

val internalstd/core/lazy/internal: int = 42literal: int
dec = 42
hex8 = 0x2A
bit8 = 0b00101010