/ src / run.js
run.js
  1  // SPDX-License-Identifier: AGPL-3.0-or-later
  2  // SPDX-FileCopyrightText: 2025 hyperpolymath
  3  //
  4  // AffineScript Playground - Deno Entry Point
  5  // Demonstrates affine type semantics for WebAssembly
  6  
  7  /**
  8   * AffineScript Playground
  9   *
 10   * This playground demonstrates affine type semantics - types that can be used
 11   * at most once. This is useful for:
 12   * - Resource management (file handles, network connections)
 13   * - Memory safety without garbage collection
 14   * - WebAssembly linear memory safety
 15   */
 16  
 17  // Import from compiled ReScript
 18  import { demonstrate } from "./Affine.res.js";
 19  
 20  // Affine type wrapper - simulates use-at-most-once semantics
 21  class AffineResource {
 22    #consumed = false;
 23    #resourceValue;
 24  
 25    constructor(value) {
 26      this.#resourceValue = value;
 27    }
 28  
 29    /**
 30     * Consume the resource. Can only be called once.
 31     * Affine semantics: use at most once (0 or 1 times)
 32     */
 33    consume() {
 34      if (this.#consumed) {
 35        throw new Error("Affine type violation: resource already consumed");
 36      }
 37      this.#consumed = true;
 38      return this.#resourceValue;
 39    }
 40  
 41    /**
 42     * Check if resource has been consumed
 43     */
 44    isConsumed() {
 45      return this.#consumed;
 46    }
 47  
 48    /**
 49     * Affine types can be dropped without use (unlike linear types)
 50     */
 51    drop() {
 52      if (!this.#consumed) {
 53        console.log("Resource dropped without use (affine allows this)");
 54        this.#consumed = true;
 55      }
 56    }
 57  }
 58  
 59  // Example: WASM memory handle with affine semantics
 60  function allocateWasmMemory(size) {
 61    const handle = {
 62      ptr: Math.floor(Math.random() * 0xffff), // Simulated pointer
 63      size,
 64    };
 65    console.log(`Allocated WASM memory at 0x${handle.ptr.toString(16)}, size: ${size}`);
 66    return new AffineResource(handle);
 67  }
 68  
 69  function useWasmMemory(resource) {
 70    const handle = resource.consume();
 71    console.log(`Using WASM memory at 0x${handle.ptr.toString(16)}`);
 72    // Memory is now consumed - cannot be used again
 73  }
 74  
 75  // Main demonstration
 76  function demonstrateAffineTypes() {
 77    console.log("=== AffineScript Playground ===\n");
 78    console.log("Demonstrating affine type semantics:\n");
 79  
 80    // Example 1: Proper affine usage
 81    console.log("1. Proper usage (use once):");
 82    const mem1 = allocateWasmMemory(1024);
 83    useWasmMemory(mem1);
 84    console.log(`   Resource consumed: ${mem1.isConsumed()}\n`);
 85  
 86    // Example 2: Affine allows dropping without use
 87    console.log("2. Drop without use (affine allows this):");
 88    const mem2 = allocateWasmMemory(512);
 89    mem2.drop();
 90    console.log(`   Resource consumed: ${mem2.isConsumed()}\n`);
 91  
 92    // Example 3: Attempting double use (will throw)
 93    console.log("3. Double use attempt (will throw):");
 94    const mem3 = allocateWasmMemory(256);
 95    try {
 96      mem3.consume();
 97      mem3.consume(); // This will throw
 98    } catch (error) {
 99      console.log(`   Error: ${error.message}\n`);
100    }
101  
102    console.log("=== Demo Complete ===");
103  }
104  
105  // Run if executed directly
106  if (import.meta.main) {
107    demonstrateAffineTypes();
108  }
109  
110  export { AffineResource, allocateWasmMemory, useWasmMemory, demonstrateAffineTypes };