Skip to content

Script API

Benjamin Rosseaux edited this page Dec 2, 2025 · 1 revision

POCA Script API Documentation

Table of Contents

Array

Overview

The POCA Array API provides functionality similar to JavaScript arrays. Arrays in POCA are dynamic, typeless collections that support a variety of operations including element insertion, removal, slicing, sorting, joining, and filling. The API offers an Array namespace for creating arrays as well as a rich set of methods on arrays for manipulating collections of values.


Global Array Object

The global Array object serves as both a factory and a namespace for array operations. You can create arrays using any of the following variants:

Array.create(), new Array(), or the [] Literal Syntax

Usage:

let arr = Array.create();

or equivalently,

let arr = new Array();

or using the literal syntax:

let arr = [];

You can also provide an initial elements:

let arr = Array.create("a", "b", "c");

or via literal notation (when supported):

let arr = ["a", "b", "c"];
  • Description: Array.create(), new Array(), or the [] literal syntax creates a new array by invoking the underlying array creation routine. The resulting ghost object represents a dynamic array, which is registered for subsequent array operations.

  • Parameters:

    • If provided, the first parameter specifies the desired size of the array.

    • Additional parameters (if any) are used to initialize the array elements.

  • Return Value: A new array.

  • Example:

    // Create an empty array.
    let arr1 = Array.create();
    let arr2 = new Array();
    let arr3 = []; // Using literal syntax
    
    // Create an array with size 3 and initial values.
    let arr4 = Array.create(3, "a", "b", "c");
    let arr5 = ["a", "b", "c"]; // Using literal syntax with initial values

Methods on Arrays

Once created, arrays provide the following methods:

Array.empty

Usage:

let isEmpty = arr.empty();
  • Description: Returns a numeric boolean value indicating whether the array is empty (1 if empty, 0 otherwise).

  • Parameters: None.

  • Return Value: A numeric boolean value.

  • Example:

    if (arr.empty()) {
      puts("The array is empty.");
    }

Array.length

Usage:

let length = arr.length;
  • Description: A pseudo-property that returns the number of elements in the array. For the functional API, this is equivalent to arr.size().

  • Parameters: None.

  • Return Value: A numeric value representing the array length.

  • Example:

    let n = arr.length;
    puts("Array length: " + n);

Array.size

Usage:

let size = arr.size();
  • Description: Returns the number of elements in the array.

  • Parameters: None.

  • Return Value: A numeric value representing the array size.

  • Example:

    let n = arr.size();
    puts("Array size: " + n);

Array.resize

Usage:

arr.resize(newSize);
  • Description: Resizes the array to the specified size. If the new size is smaller, elements are truncated; if larger, new slots are added (typically initialized to null).

  • Parameters:

    • newSize (number): The desired new size of the array.

  • Return Value: The array itself.

  • Example:

    arr.resize(10);

Array.push

Usage:

arr.push(element1, element2, ...);
  • Description: Appends one or more elements to the end of the array.

  • Parameters: One or more elements to be added.

  • Return Value: The array itself.

  • Example:

    arr.push("new item");

Array.pop

Usage:

let item = arr.pop();
  • Description: Removes and returns the last element from the array.

  • Parameters: None.

  • Return Value: The removed element.

  • Example:

    let last = arr.pop();

Array.slice

Usage:

let subArray = arr.slice(start, length);
  • Description: Returns a new array containing a portion of the original array, starting at the specified index and extending for the specified length. If the length is omitted or exceeds the remaining elements, the slice extends to the end of the array.

  • Parameters:

    • start (number): The starting index.

    • length (number): The number of elements to include (optional).

  • Return Value: A new array containing the specified elements.

  • Example:

    let part = arr.slice(2, 3);

Array.splice

Usage:

arr.splice(start, deleteCount, item1, item2, ...);
  • Description: Modifies the array by removing or replacing existing elements and/or adding new elements in place. The start parameter specifies the index at which to start modifying the array, and deleteCount specifies how many elements to remove. If deleteCount is omitted, all elements from start to the end of the array are removed. You can also add new elements by providing additional arguments after deleteCount.

  • Parameters:

    • start (number): The index at which to start modifying the array.

    • deleteCount (number, optional): The number of elements to remove.

    • item1, item2, ... (any, optional): The elements to add.

  • Return Value: The removed elements (if any).

  • Example:

    arr.splice(2, 1, "new item");

Array.toSpliced

Usage:

let newArr = arr.toSpliced(start, deleteCount, item1, item2, ...);
  • Description: Returns a new array with the specified elements removed and/or replaced, without modifying the original array. The start parameter specifies the index at which to start modifying the array, and deleteCount specifies how many elements to remove. If deleteCount is omitted, all elements from start to the end of the array are removed. You can also add new elements by providing additional arguments after deleteCount.

  • Parameters:

    • start (number): The index at which to start modifying the array.

    • deleteCount (number, optional): The number of elements to remove.

    • item1, item2, ... (any, optional): The elements to add.

  • Return Value: A new array with the specified elements removed and/or added.

  • Example:

    let newArr = arr.toSpliced(2, 1, "new item");

Array.sort

Usage:

arr.sort(compareFunctionOrArrayIndex);
  • Description: Sorts the array elements in place using the default comparison.

  • Parameters:

    • compareFunctionOrArrayIndex (function or number): A function to compare two elements, or an array index to sort by.

  • Return Value: The sorted array itself.

  • Example:

    arr.sort();

Array.toSorted

Usage:

let sortedArray = arr.toSorted(compareFunctionOrArrayIndex);
  • Description: Returns a new array with the elements sorted, without modifying the original array.

  • Parameters:

    • compareFunctionOrArrayIndex (function or number): A function to compare two elements, or an array index to sort by.

  • Return Value: A new array with the elements sorted.

  • Example:

    let sortedArr = arr.toSorted();
    puts("Sorted array: ", String.dump(sortedArr));

Array.join

Usage:

let str = arr.join(separator);
  • Description: Joins all elements of the array into a single string, separated by the specified separator. If no separator is provided, a comma is used by default.

  • Parameters:

    • separator (string): The string to insert between each element (optional).

  • Return Value: A string resulting from concatenating the array elements.

  • Example:

    let result = arr.join("-");

Array.fill

Usage:

arr.fill(value, start, end);
  • Description: Replaces a range of elements in the array with the specified value. The filling starts at the index specified by start and ends just before the index specified by end. If start is omitted, it defaults to 0; if end is omitted, it defaults to the array size.

  • Parameters:

    • value (any): The value to fill with.

    • start (number, optional): The starting index.

    • end (number, optional): The ending index.

  • Return Value: The array itself.

  • Example:

    arr.fill("x", 2, 5);

Array.toFilled

Usage:

arr.toFilled(value, start, end);
  • Description: Replaces a range of elements in the array with the specified value. The filling starts at the index specified by start and ends just before the index specified by end. If start is omitted, it defaults to 0; if end is omitted, it defaults to the array size.

  • Parameters:

    • value (any): The value to fill with.

    • start (number, optional): The starting index.

    • end (number, optional): The ending index.

  • Return Value: A new array with the specified range filled.

  • Example:

    let newArr = arr.toFilled("x", 2, 5);

Array.delete

Usage:

arr.delete(index...);
  • Description: Deletes the element at the specified index/indices from the array. The array is resized accordingly.

  • Parameters:

    • index (number): The index/indices of the element to delete.

  • Return Value: The array itself.

  • Example:

    arr.delete(2);

Array.remove

Usage:

arr.remove(element...);
  • Description: Removes all occurrences of the specified element(s) from the array.

  • Parameters:

    • element (any): The element(s) to remove.

  • Return Value: The array itself.

  • Example:

    arr.remove("x");

Array.indexOf

Usage:

let index = arr.indexOf(element);
  • Description: Returns the index of the first occurrence of the specified element in the array. If the element is not found, it returns -1.

  • Parameters:

    • element (any): The element to search for.

  • Return Value: The index of the element, or -1 if not found.

  • Example:

    let idx = arr.indexOf("x");
    if (idx !== -1) {
      puts("Element found at index: " + idx);
    } else {
      puts("Element not found.");
    }

Array.lastIndexOf

Usage:

let index = arr.lastIndexOf(element);
  • Description: Returns the index of the last occurrence of the specified element in the array. If the element is not found, it returns -1.

  • Parameters:

    • element (any): The element to search for.

  • Return Value: The index of the element, or -1 if not found.

  • Example:

    let idx = arr.lastIndexOf("x");
    if (idx !== -1) {
      puts("Element found at index: " + idx);
    } else {
      puts("Element not found.");
    }

Array.reverse

Usage:

arr.reverse();
  • Description: Reverses the order of the elements in the array.

  • Parameters: None.

  • Return Value: The reversed array itself.

  • Example:

    arr.reverse();

Array.toReversed

Usage:

let reversedArray = arr.toReversed();
  • Description: Returns a new array with the elements in reverse order, without modifying the original array.

  • Parameters: None.

  • Return Value: A new array with the elements in reverse order.

  • Example:

    let reversed = arr.toReversed();
    puts("Reversed array: ", String.dump(reversed));

Array.includes

Usage:

let exists = arr.includes(element);
  • Description: Checks if the specified element exists in the array.

  • Parameters:

    • element (any): The element to check for.

  • Return Value: A numeric boolean (1 for true, 0 for false).

  • Example:

    if (arr.includes("x")) {
      puts("Element exists in the array.");
    } else {
      puts("Element does not exist.");
    }

Array.shift

Usage:

let firstElement = arr.shift();
  • Description: Removes and returns the first element from the array.

  • Parameters: None.

  • Return Value: The removed element.

  • Example:

    let first = arr.shift();
    puts("First element removed: ", first);

Array.unshift

Usage:

arr.unshift(element1, element2, ...);
  • Description: Adds one or more elements to the beginning of the array.

  • Parameters: One or more elements to be added.

  • Return Value: The array itself.

  • Example:

    arr.unshift("new item");

Array.map

Usage:

let newArr = arr.map(callback);
  • Description: Creates a new array populated with the results of calling a provided function on every element in the calling array.

  • Parameters:

    • callback (function): A function that is called for every element of the array. It accepts three arguments:

      • currentValue: The current element being processed.

      • index: The index of the current element.

      • array: The array that map was called upon.

  • Return Value: A new array with each element being the result of the callback function.

  • Example:

    function myFunction(num) {
      return num * 10;
    }
    
    let numbers = [65, 44, 12, 4];
    let newArr = numbers.map(myFunction);
    // newArr is [650, 440, 120, 40]
    
    // Using inline function
    let doubled = numbers.map(function(x) { return x * 2; });
    // doubled is [130, 88, 24, 8]

Array.reduce

Usage:

let result = arr.reduce(callback);
let result = arr.reduce(callback, initialValue);
  • Description: Executes a reducer function on each element of the array, resulting in a single output value. The reducer function is executed from left to right.

  • Parameters:

    • callback (function): A function to execute on each element in the array. It accepts four arguments:

      • accumulator: The accumulated value previously returned in the last invocation of the callback, or initialValue, if supplied.

      • currentValue: The current element being processed.

      • index: The index of the current element.

      • array: The array that reduce was called upon.

    • initialValue (optional): A value to use as the first argument to the first call of the callback. If no initial value is supplied, the first element in the array will be used as the initial accumulator value and skipped as currentValue.

  • Return Value: The single value that results from the reduction.

  • Example:

    function sum(accumulator, currentValue) {
      return accumulator + currentValue;
    }
    
    let numbers = [65, 44, 12, 4];
    let total = numbers.reduce(sum);
    // total is 125
    
    // With initial value
    let totalWithInit = numbers.reduce(sum, 100);
    // totalWithInit is 225
    
    // Finding maximum value
    let max = numbers.reduce(function(acc, val) {
      if (val > acc) {
        return val;
      }
      return acc;
    });
    // max is 65

Array.reduceRight

Usage:

let result = arr.reduceRight(callback);
let result = arr.reduceRight(callback, initialValue);
  • Description: Applies a function against an accumulator and each value of the array (from right-to-left) to reduce it to a single value.

  • Parameters:

    • callback (function): A function to execute on each element in the array, taking four arguments:

      • accumulator: The accumulated value previously returned in the last invocation of the callback, or initialValue, if supplied.

      • currentValue: The current element being processed.

      • index: The index of the current element.

      • array: The array that reduceRight was called upon.

    • initialValue (optional): Value to use as accumulator to the first call of the callback. If no initial value is supplied, the last element in the array will be used and skipped.

  • Return Value: The value that results from the reduction.

  • Example:

    let nums = [1, 2, 3, 4];
    
    // Subtract from right to left
    let difference = nums.reduceRight(function(acc, val) {
      return acc - val;
    });
    // difference is -2 (4 - 3 - 2 - 1)
    
    // Build array in reverse
    let reversed = nums.reduceRight(function(acc, val) {
      acc.push(val);
      return acc;
    }, []);
    // reversed is [4, 3, 2, 1]

Summary

  • Global Object: The Array object acts as a factory for creating array ghost objects. Array.create(), new Array(), or the [] literal syntax creates a new array by invoking the underlying array creation routine. The resulting ghost object represents a dynamic array, which is registered for subsequent array operations.

  • Array Methods: Once created, array provide the following methods to manipulate arrays:

    • empty: Returns a numeric boolean indicating whether the array is empty.

    • length: Returns the number of elements in the array.

    • size: Returns the number of elements in the array.

    • resize: Changes the size of the array.

    • push: Appends one or more elements to the end of the array.

    • pop: Removes and returns the last element of the array.

    • slice: Extracts a portion of the array into a new array.

    • splice: Changes the contents of an array by removing or replacing existing elements and/or adding new elements.

    • toSpliced: Returns a new array with some elements removed and/or replaced at a given index.

    • sort: Sorts the array elements.

    • toSorted: Returns a new sorted array without modifying the original.

    • join: Concatenates array elements into a string, separated by a specified separator.

    • fill: Replaces a range of elements in the array with a specified value.

    • toFilled: Returns a new array with a range of elements filled with a specified value.

    • delete: Removes an element at a specified index.

    • remove: Removes the first occurrence of a specified value.

    • indexOf: Returns the first index at which a given element can be found.

    • lastIndexOf: Returns the last index at which a given element can be found.

    • reverse: Reverses the order of the elements in the array.

    • toReversed: Returns a new array with the elements in reversed order.

    • includes: Determines whether an array contains a specified element.

    • shift: Removes and returns the first element from the array.

    • unshift: Adds one or more elements to the beginning of the array.

    • map: Creates a new array with the results of calling a provided function on every element.

    • reduce: Executes a reducer function on each element, resulting in a single output value (left to right).

    • reduceRight: Executes a reducer function on each element, resulting in a single output value (right to left).

  • Usage: Arrays in POCA function similarly to JavaScript arrays, offering dynamic resizing and a rich set of operations for manipulating collections of values. This comprehensive API lets you incorporate robust array handling into your POCA projects, providing flexible and powerful data manipulation capabilities.

Boolean

Overview

The POCA Boolean API provides a mechanism for converting values into a boolean representation. In POCA, booleans are represented as number literals—0 for false and 1 for true. The global Boolean object acts as a factory for creating these boolean values.


Global Boolean Object

The global Boolean object serves as a factory for boolean values.

Boolean.create

Usage:

let b = Boolean.create(someValue);
  • Description: Boolean.create() converts the provided value into a boolean number. If an argument is provided, it returns 1 (true) if the value is truthy, or 0 (false) otherwise. If no argument is provided, it returns 0 (false).

  • Parameters:

    • value (any, optional): The value to convert to a boolean.

  • Return Value: A number literal representing the boolean value (0 or 1).

  • Example:

    let b1 = Boolean.create(0);   // Returns 0 (false)
    let b2 = Boolean.create(42);  // Returns 1 (true)
    let b3 = Boolean.create();    // Returns 0 (false)

Summary

  • Global Object: The Boolean object acts as a factory for creating boolean values. Boolean.create() converts a provided value into a number literal (0 or 1) representing false or true.

  • Boolean API Function:

    • create: Converts a value to a boolean; if no value is provided, it returns 0 (false).

  • Usage: This API enables you to convert any value to its boolean representation in POCA, using the familiar paradigm where 0 represents false and 1 represents true.

Console

Overview

The POCA Console API provides basic input/output functions for interacting with the console in POCA scripts. With this API, you can log messages to the console and read user input from it. The API uses user-provided I/O functions (if available) for writing and flushing output, falling back to system I/O routines otherwise.


Global Console Object

The global Console object serves as a namespace for console operations. It includes functions to log output and to read a line of input from the console.


Console.initialize

Usage:

Console.initialize();
  • Description: Initializes the console for interactive input/output. This disables echoing, sets the console mode to raw, and prepares the console for realtime non-blocking input.

  • Parameters: None.

  • Return Value: A numeric boolean (1 for success, 0 for failure).

  • Example:

    // Initialize the console for input/output.
    if (Console.initialize()) {
      Console.log("Console initialized successfully.");
    } else {
      Console.log("Failed to initialize console.");
    }

Console.finalize

Usage:

Console.finalize();
  • Description: Finalizes the console, restoring the original console mode and flushing any remaining output. This is typically called at the end of a script to clean up the console state.

  • Parameters: None.

  • Return Value: A numeric boolean (1 for success, 0 for failure).

  • Example:

    // Finalize the console before exiting.
    Console.finalize();
    Console.log("Console finalized successfully.");

Console.log

Usage:

Console.log(value1, value2, ...);
  • Description: The Console.log function outputs one or more values to the console. For each argument, it converts the value to a string:

    • If the value is null, it outputs "null".

    • If the value is a string, it converts the internal UTF‑8 representation to UTF‑16 before writing, when it is necessary for the underlying I/O function, otherwise it writes the UTF‑8 string directly.

    • If the value is a number, it converts the number to its string representation.

      After processing all arguments, Console.log writes a newline and flushes the output (using user-defined I/O functions if available, or the system I/O routines otherwise).

  • Parameters:

    • One or more values (of type null, string, or number) to be logged.

  • Return Value: A null value (represented internally as a number literal with the special null value).

  • Example:

    // Log different types of values.
    Console.log("Hello, World!", 123.45, null);

Console.readLine

Usage:

let input = Console.readLine(prompt);
  • Description: The Console.readLine function reads a full line of text from the console. An optional prompt can be provided, which is passed to the underlying input function.

  • Parameters:

    • prompt (string, optional): A string displayed to the user as a prompt before reading input.

  • Return Value: A string containing the line read from the console.

  • Example:

    // Read user input with a prompt.
    let userInput = Console.readLine("Enter your name: ");
    Console.log("Hello, " + userInput + "!");

Console.readKey

Usage:

let key = Console.readKey();
  • Description: The Console.readKey function reads a single key press from the console. This is typically used for interactive applications where immediate feedback is required. It’s non-blocking and does not wait for the user to press Enter. The function returns a number code representing the key pressed. If no key is pressed, it returns 0.

  • Parameters: None.

  • Return Value: A number code representing the key pressed.

  • Example:

    // Read a single key press.
    while (true) {
      let key = Console.readKey();
      if (key === 113) { // Q key
        Console.log("Q key pressed. Exiting...");
        break;
      } else if (key != 0) {
        Console.log("Key pressed: " + key);
      } else {
        sleep(100); // Sleep for a short duration to avoid busy waiting
      }
    }

Summary

  • Global Object: The Console object provides a namespace for basic console operations. It offers functions to log messages and read input from the console.

  • Console API Functions:

    • initialize: Initializes the console for interactive input/output.

    • finalize: Finalizes the console, restoring the original mode.

    • log: Outputs one or more values to the console. Values are converted to strings (with special handling for null, strings, and numbers), followed by a newline and a flush of the output.

    • readKey: Reads a single key press from the console, returning a number code representing the key. If no key is pressed, it returns 0.

    • readLine: Reads a line of text from the console, optionally displaying a prompt.

  • Usage: This comprehensive API enables you to output messages and interact with the user via the console, using either user-defined or system I/O routines in a dynamic, typeless environment.

Coroutine

Overview

The POCA Coroutine API enables cooperative multitasking in your POCA scripts. Coroutines in POCA are dynamic, typeless ghost objects that encapsulate a separate execution context. You can create a coroutine to run a function concurrently (in a cooperative manner) and later resume its execution, yield control, or retrieve passed values. The API provides a set of functions to create, resume, yield, and retrieve values from a coroutine.


Global Coroutine Object

The global Coroutine object serves as a namespace and factory for coroutine operations. It provides functions to create a new coroutine, yield execution from within a coroutine, and retrieve the latest value passed to it. In addition, coroutine ghost objects have a dedicated method (resume) registered in the global coroutine hash that lets you resume a suspended coroutine.


Creating a Coroutine

Coroutine.create

Usage:

let co = Coroutine.create(function(a, b) {
  // Coroutine body: perform operations using a and b.
  puts("Inside coroutine, received: " + a + ", " + b);

  // Yield a value back to the caller.
  Coroutine.yield("Yielding from coroutine");

  // When resumed, get the new input:
  let resumedValue = Coroutine.get();
  puts("Resumed with: " + resumedValue);

  return "Coroutine complete";
}, arg1, arg2);

or

let co = new Coroutine(function(a, b) {
  // Coroutine body: perform operations using a and b.
  puts("Inside coroutine, received: " + a + ", " + b);

  // Yield a value back to the caller.
  Coroutine.yield("Yielding from coroutine");

  // When resumed, get the new input:
  let resumedValue = Coroutine.get();
  puts("Resumed with: " + resumedValue);

  return "Coroutine complete";
}, arg1, arg2);
  • Description: Coroutine.create or new Coroutine creates a coroutine ghost object with the provided function. The first argument must be a function, and any additional arguments will be passed to that function when the coroutine is first executed. Internally, a new execution context is created for the coroutine, and the coroutine ghost object is registered in the global coroutine hash.

  • Parameters:

    • func (function): The function to be executed as a coroutine.

    • ...args (any): Additional arguments that are passed to the coroutine function.

  • Return Value: A coroutine ghost object that encapsulates the created coroutine.

  • Example:

    // Create a coroutine that accepts two arguments.
    let co = Coroutine.create(function(a, b) {
      puts("Started with: " + a + ", " + b);
      // Suspend execution, yielding a value.
      Coroutine.yield("Paused");
      // Retrieve the value passed on resume.
      let input = Coroutine.get();
      puts("Resumed with: " + input);
      return "Done";
    }, "first", "second");

or

// Create a coroutine that accepts two arguments.
let co = new Coroutine(function(a, b) {
  puts("Started with: " + a + ", " + b);
  // Suspend execution, yielding a value.
  Coroutine.yield("Paused");
  // Retrieve the value passed on resume.
  let input = Coroutine.get();
  puts("Resumed with: " + input);
  return "Done";
}, "first", "second");
  • Note: The coroutine function can be defined inline or as a named function.


Checking if inside a Coroutine at any time

Coroutine.inside

Usage:

let result = Coroutine.inside();
  • Description: Return true if currently executing inside a coroutine, or false otherwise.

  • Parameters: None.

  • Return Value: A numeric boolean (1 for true, 0 for false).

  • Example:

    let inside = Coroutine.inside();
    puts("Inside coroutine: ", inside);

Resuming a Coroutine

coroutine.resume

Usage:

let result = coroutine.resume(value);
  • Description: Resumes the execution of a previously created coroutine. Optionally, you can pass a value to the coroutine that will be accessible after it yields. If the coroutine function throws an exception, it is re-raised when you resume it.

  • Parameters:

    • value (any): A value passed to the coroutine to resume its execution. If omitted, a null value is used.

  • Return Value: The value yielded by the coroutine immediately before suspension, or the final return value if the coroutine completes.

  • Example:

    // Resume the coroutine, passing "continue" as the resume value.
    let output = coroutine.resume("continue");
    puts("Coroutine yielded: " + output);

Yielding from a Coroutine

Coroutine.yield

Usage:

Coroutine.yield(value);
  • Description: From within a coroutine function, use Coroutine.yield to suspend its execution and optionally return a value to the caller. Execution will pause at this point until the coroutine is resumed.

  • Parameters:

    • value (any): A value to be yielded back to the caller. If omitted, a null value is used.

  • Return Value: No value is returned by Coroutine.yield directly; instead, the coroutine’s state is saved and later resumed.

  • Example:

    // Inside the coroutine function:
    Coroutine.yield("Yielding control");
    // Execution pauses here until resumed.

Retrieving a Resume Value

Coroutine.get

Usage:

let value = Coroutine.get();
  • Description: When a coroutine is resumed, the value passed to resume is stored. You can retrieve this value inside the coroutine by calling Coroutine.get.

  • Parameters: None.

  • Return Value: The value that was passed to the coroutine during the last resume call, or a null value if none was provided.

  • Example:

    // Inside the coroutine function after yielding:
    let resumeValue = Coroutine.get();
    puts("Received on resume: " + resumeValue);

Coroutine Additional Instance Methods

A coroutine is a ghost object that have the following API methods:

Coroutine.resumed

Usage:

let isResumed = coroutine.resumed();
  • Description: Checks if the coroutine has been resumed. This indicates that the coroutine is already at least once resumed and is currently executing or suspended.

  • Parameters: None.

  • Return Value: A numeric boolean (1 for true, 0 for false).

  • Example:

    let isResumed = coroutine.resumed();
    if (isResumed) {
      puts("Coroutine has been resumed.");
    } else {
      puts("Coroutine has not been resumed yet.");
    }

Coroutine.data

Usage:

let data = coroutine.data();
  • Description: Returns the data hash associated with the coroutine. This is the value passed to the coroutine when it was created. If no data is associated with the coroutine, it returns a empty hash. In the coroutine function, you can access this data using this.

  • Parameters: None.

  • Return Value: A hash containing the data associated with the coroutine.

  • Example:

    let data = coroutine.data();
    puts("Coroutine data: ", String.dump(data));

Coroutine.state

Usage:

let state = coroutine.state();
  • Description: Returns the current state of the coroutine. The state can be one of the following:

    • none: The coroutine has not been started yet.

    • outside: The coroutine is currently outside of its execution context.

    • inside: The coroutine is currently inside its execution context.

    • insideterminated: The coroutine is inside its execution context and is terminated.

    • terminated: The coroutine has been terminated.

  • Parameters: None.

  • Return Value: A string representing the current state of the coroutine.

  • Example:

    let state = coroutine.state();
    puts("Coroutine state: ", state);

Coroutine.inside

Usage:

let isInside = coroutine.inside();
  • Description: Checks if the coroutine is currently inside its execution context. This is useful for determining if the coroutine is actively executing or has been suspended.

  • Parameters: None.

  • Return Value: A numeric boolean (1 for true, 0 for false).

  • Example:

    let isInside = coroutine.inside();
    if (isInside) {
      puts("Coroutine is currently executing.");
    } else {
      puts("Coroutine is not executing.");
    }

Coroutine.outside

Usage:

let isOutside = coroutine.outside();
  • Description: Checks if the coroutine is currently outside its execution context. This is useful for determining if the coroutine is suspended or has completed its execution.

  • Parameters: None.

  • Return Value: A numeric boolean (1 for true, 0 for false).

  • Example:

    let isOutside = coroutine.outside();
    if (isOutside) {
      puts("Coroutine is currently suspended.");
    } else {
      puts("Coroutine is executing.");
    }

Coroutine.terminated

Usage:

let isTerminated = coroutine.terminated();
  • Description: Checks if the coroutine has been terminated. This indicates that the coroutine has completed its execution and is no longer active.

  • Parameters: None.

  • Return Value: A numeric boolean (1 for true, 0 for false).

  • Example:

    let isTerminated = coroutine.terminated();
    if (isTerminated) {
      puts("Coroutine has been terminated.");
    } else {
      puts("Coroutine is still active.");
    }

Coroutine.alive

Usage:

let isAlive = coroutine.alive();
  • Description: Checks if the coroutine is alive. This indicates that the coroutine is still active and has not been terminated.

  • Parameters: None.

  • Return Value: A numeric boolean (1 for true, 0 for false).

  • Example:

    let isAlive = coroutine.alive();
    if (isAlive) {
      puts("Coroutine is alive.");
    } else {
      puts("Coroutine has been terminated.");
    }

Coroutine Lifecycle and Resource Management

When a coroutine finishes execution or is destroyed: - Its internal execution context and allocated resources are properly cleaned up. - If an exception occurs during execution, it is captured and re-raised when the coroutine is resumed. - The garbage collector is informed of all associated values (arguments, context, and function) via the ghost object’s mark procedure.

The API ensures that any associated coroutine data is finalized and memory is released when the coroutine ghost is destroyed.


Example Usage

// Create a coroutine that processes some data.
let co = Coroutine.create(function(x, y) {
  puts("Coroutine started with: " + x + " and " + y);

  // Suspend execution and yield a status.
  Coroutine.yield("Waiting for resume...");

  // Retrieve the resume value.
  let resumeData = Coroutine.get();
  puts("Resumed with: " + resumeData);

  // Continue processing and complete.
  return "Processing complete";
}, "data1", "data2");

// Resume the coroutine, passing a value.
let initialYield = co.resume("resume_value_1");
puts("Yielded value: " + initialYield);

// Resume again to complete the coroutine.
let finalResult = co.resume("resume_value_2");
puts("Final result: " + finalResult);

Summary

  • Global Object: The Coroutine object provides the following functions:

    • create: Creates a coroutine ghost object for a provided function.

    • yield: Suspends the execution of a running coroutine, optionally yielding a value.

    • get: Retrieves the value passed to the coroutine when it is resumed.

  • Coroutine Ghost Object Methods: Once created, a coroutine ghost object supports the resume method (registered in the global Coroutine hash), which resumes its execution and returns the value yielded by the coroutine.

  • Lifecycle: The API manages the coroutine’s context, arguments, and exception handling, ensuring proper resource cleanup when the coroutine is destroyed.

This comprehensive API enables you to implement cooperative multitasking in POCA, making it possible to write asynchronous or concurrent code in a dynamic, typeless environment.

DateTime

Overview

The POCA DateTime API provides functions for working with date and time values in POCA scripts. Date and time values are represented in the TDateTime format—a 64-bit double floating point number—similar to FreePascal and Delphi, where the fractional part represents the time of day. With this API, you can retrieve the current date and time in both local and UTC formats, and convert date/time values to milliseconds.


Global DateTime Object

The global DateTime object serves as a namespace for date and time operations. It provides the following functions:

DateTime.now

Usage:

let currentTime = DateTime.now();
  • Description: Returns the current local date and time as a TDateTime value (a 64-bit double). The TDateTime format represents the number of days (including fractions for time) since a base date.

  • Parameters: None.

  • Return Value: A numeric value in TDateTime format representing the current local date and time.

  • Example:

    let now = DateTime.now();
    puts("Current local time: " + now);

DateTime.nowUTC

Usage:

let currentUTCTime = DateTime.nowUTC();
  • Description: Returns the current UTC date and time as a TDateTime value (a 64-bit double). The TDateTime format is used consistently for both local and UTC times.

  • Parameters: None.

  • Return Value: A numeric value in TDateTime format representing the current UTC date and time.

  • Example:

    let utcNow = DateTime.nowUTC();
    puts("Current UTC time: " + utcNow);

DateTime.milliseconds

Usage:

let ms = DateTime.milliseconds(timeValue);
  • Description: Converts a date time value (representing days) into milliseconds. Since one day equals 86,400,000 milliseconds, the function multiplies the input value by 86,400,000.

  • Parameters:

    • timeValue (number): A date time value (in days) to be converted to milliseconds.

  • Return Value: A numeric value representing the equivalent time in milliseconds.

  • Example:

    // Convert current time (in days) to milliseconds.
    let ms = DateTime.milliseconds(DateTime.now());
    puts("Milliseconds since base date: " + ms);

DateTime.utcOffset

Usage:

let offset = DateTime.utcOffset(dateTimeValue);
  • Description: Returns the UTC offset in hours for the current local time zone. This is useful for converting between local and UTC times.

  • Parameters:

    • dateTimeValue (number, optional): A TDateTime value (in days) for which to calculate the UTC offset. If omitted, the current date/time is used.

  • Return Value: A numeric value representing the UTC offset.

  • Example:

    // Get the UTC offset for the current local time.
    let offset = DateTime.utcOffset(DateTime.now());
    puts("UTC offset: " + offset);

DateTime.toLocal

Usage:

let localTime = DateTime.toLocal(dateTimeValue);
  • Description: Converts a date time value (in days) to the local time format. This is useful for displaying date/time values in the local time zone.

  • Parameters:

    • dateTimeValue (number): A date time value (in days) to be converted to local time.

  • Return Value: A numeric value representing the local time in date time format.

  • Example:

    // Convert a UTC date/time value to local time.
    let utcTime = DateTime.nowUTC();
    let localTime = DateTime.toLocal(utcTime);
    puts("Local time: " + localTime);

DateTime.toUniversal

Usage:

let utcTime = DateTime.toUniversal(dateTimeValue);
  • Description: Converts a date time value (in days) to the UTC time format. This is useful for displaying date/time values in UTC.

  • Parameters:

    • dateTimeValue (number): A date time value (in days) to be converted to UTC time.

  • Return Value: A numeric value representing the UTC time in date time format.

  • Example:

    // Convert a local date/time value to UTC.
    let localTime = DateTime.now();
    let utcTime = DateTime.toUniversal(localTime);
    puts("UTC time: " + utcTime);

DateTime.fromUnixTime

Usage:

let dateTimeValue = DateTime.fromUnixTime(unixTime);
  • Description: Converts a Unix timestamp (seconds since the epoch) to a date time value (in days). The Unix timestamp is typically represented as a 32-bit integer, and this function converts it to a date time value.

  • Parameters:

    • unixTime (number): A Unix timestamp (seconds since the epoch)

  • Return Value: A numeric value representing the date time in date time format.

  • Example:

    // Convert a Unix timestamp to a date/time value.
    let unixTime = 1633072800; // Example Unix timestamp
    let dateTimeValue = DateTime.fromUnixTime(unixTime);
    puts("Date/time value: ", dateTimeValue);

DateTime.toUnixTime

Usage:

let unixTime = DateTime.toUnixTime(dateTimeValue);
  • Description: Converts a date time value (in days) to a Unix timestamp (seconds since the epoch). This is useful for interoperating with systems that use Unix timestamps.

  • Parameters:

    • dateTimeValue (number): A date time value (in days) to be converted to a Unix timestamp.

  • Return Value: A numeric value representing the Unix timestamp.

  • Example:

    // Convert a date/time value to a Unix timestamp.
    let dateTimeValue = DateTime.now();
    let unixTime = DateTime.toUnixTime(dateTimeValue);
    puts("Unix timestamp: ", unixTime);

DateTime.toString

Usage:

let dateTimeString = DateTime.toString(dateTimeValue, format);
  • Description: Converts a date time value (in days) to a string representation. The format string specifies how the date and time should be displayed. The format string can include various placeholders for year, month, day, hour, minute, second, etc.

  • Parameters:

    • dateTimeValue (number): A date time value (in days) to be converted to a string.

    • format (string, optional): A format string that specifies how the date and time should be displayed. Placeholders in the format string are replaced with the corresponding date/time components. If omitted, a default format is used.

  • Return Value: A string representing the date and time in the specified format.

  • Example:

    // Convert a date/time value to a string with the default format.
    let dateTimeValue = DateTime.now();
    let formattedString = DateTime.toString(dateTimeValue);
    puts("Formatted date/time: ", formattedString);

DateTime.parse

Usage:

let dateTimeValue = DateTime.parse(dateTimeString);
  • Description: Parses a date time string and converts it to a date time value (in days). The input string should be in a recognized date time format. The function attempts to parse the string and return a date time value. If the string cannot be parsed, an error is raised.

  • Parameters:

    • dateTimeString (string): A string representing a date and time to be parsed.

  • Return Value: A numeric value representing the parsed date and time in date time format.

  • Example:

    // Parse a date/time string and convert it to a date time value.
    let dateTimeString = "2023-10-01 12:34:56";
    let dateTimeValue = DateTime.parse(dateTimeString);
    puts("Parsed date/time value: ", dateTimeValue);

Summary

  • Global Object: The DateTime object provides functions to work with date and time values in POCA scripts. These functions return values in the TDateTime format—a 64-bit double where the fractional part represents the time of day.

  • DateTime Functions:

    • now: Returns the current local date and time.

    • nowUTC: Returns the current UTC date and time.

    • milliseconds: Converts a TDateTime value (in days) to milliseconds.

    • utcOffset: Returns the UTC offset in hours for the current local time zone.

    • toLocal: Converts a TDateTime value (in days) to local time.

    • toUniversal: Converts a TDateTime value (in days) to UTC time.

    • toString: Converts a TDateTime value (in days) to a string representation, using a specified format string.

    • parse: Parses a date time string and converts it to a TDateTime

  • Usage: This comprehensive API allows you to integrate date and time operations into your POCA projects, providing a consistent and familiar approach to handling TDateTime values as used in FreePascal and Delphi.

  • Note: The TDateTime format is compatible with FreePascal and Delphi, allowing for easy integration with existing codebases and libraries.

GarbageCollector

Overview

In POCA, garbage collection is a incremental generational system that manages memory and lifecycle for dynamically allocated objects (e.g., arrays, strings, hash tables, code objects, etc.). The GarbageCollector object provides direct access to certain GC parameters (like tuning factors for how aggressively GC runs) and lets you manually trigger collection events if desired. This API is exposed under the global GarbageCollector namespace.


GarbageCollector Object

The global GarbageCollector object is a namespace for garbage-collection operations and configuration. It holds functions to get or set GC tuning parameters, run GC cycles or full collections, and query memory usage information.


Getting Parameters

These functions read the current settings from the garbage collector:

GarbageCollector.getDynamicThreshold

Usage:

let threshold = GarbageCollector.getDynamicThreshold();
  • Description: Returns if the garbage collector is in "dynamic" threshold mode (1 for true, 0 for false). In dynamic threshold mode (true), the GC adapts its threshold based on the current memory usage and allocation patterns. In budget decrement mode (false), the threshold is fixed and changed only at every collection cycle. This is a global setting that affects all collections. For more information, see the GarbageCollector.setDynamicThreshold function.

  • Parameters: None.

  • Return Value: A numeric boolean (1 or 0).


GarbageCollector.getIncrementalCollectionThresholdFactor

Usage:

let factor = GarbageCollector.getIncrementalCollectionThresholdFactor();
  • Description: Returns the "incremental collection threshold factor" that is used to determine when an incremental garbage collection cycle should be initiated. This factor is multiplied by the current number of used objects (calculated as Allocated minus FreeCount) to compute a threshold. When the number of used objects exceeds this product, an incremental GC cycle is triggered. In essence, the lower the factor, the more aggressive the incremental collection becomes, whereas a higher factor delays GC triggering, potentially allowing more objects to accumulate before collection commences.

  • Return Value: A numeric value (integer).


GarbageCollector.getFullCollectionThresholdFactor

Usage:

let factor = GarbageCollector.getFullCollectionThresholdFactor();
  • Description: Returns the "full collection threshold factor" that is used to determine when a full garbage collection cycle should be initiated. This factor is multiplied by the current number of used objects (calculated as Allocated minus FreeCount) to compute a threshold value. When the number of used objects exceeds this product, a full GC cycle is triggered. In essence, a lower factor causes the GC to run more aggressively, performing full collections more frequently, while a higher factor delays full collection, permitting more objects to accumulate before initiating the process.

  • Return Value: A numeric value (integer) representing the full collection threshold factor.


GarbageCollector.getMarkFactor

Usage:

let factor = GarbageCollector.getMarkFactor();
  • Description: Returns the "mark factor" that determines how many objects are marked in each partial mark step. This factor is multiplied by the number of objects in the memory pool to compute the number of used objects to be marked in each step. A higher factor results in more aggressive marking, while a lower factor results in less aggressive marking.

  • Return Value: A numeric value (integer).


GarbageCollector.getGhostFactor

Usage:

let factor = GarbageCollector.getGhostFactor();
  • Description: Returns the “ghost factor” that determines how many ghost objects are processed in each partial mark step. This factor is multiplied by the number of ghost objects in the memory pool to compute the number of ghost objects to be processed in each step. A higher factor results in more aggressive ghost processing, while a lower factor results in less aggressive ghost processing.

  • Return Value: A numeric value (integer).


GarbageCollector.getSweepFactor

Usage:

let factor = GarbageCollector.getSweepFactor();
  • Description: Returns the “sweep factor” that determines how many objects are swept in each partial sweep step. This factor is multiplied by the number of used objects in the memory pool to compute the number of objects to be swept in each step. A higher factor results in more aggressive sweeping, while a lower factor results in less aggressive sweeping.

  • Return Value: A numeric value (integer).


GarbageCollector.getPersistentInterval

Usage:

let interval = GarbageCollector.getPersistentInterval();
  • Description: Returns the number of cycles after which persistent objects (long-lived objects) are rescanned.

  • Return Value: A numeric value (integer).


GarbageCollector.getPersistentThreshold

Usage:

let threshold = GarbageCollector.getPersistentThreshold();
  • Description: Returns the threshold at which an object transitions from ephemeral to persistent generation, i.e. how many times an object can survive GC before it is considered “persistent.”

  • Return Value: A numeric value (integer).


GarbageCollector.getExhaustionCollect

Usage:

let exhaustion = GarbageCollector.getExhaustionCollect();
  • Description: Returns whether a collection is triggered when a memory pool is exhausted (1 for true, 0 for false). This is a global setting that affects all collections.

  • Parameters: None.

  • Return Value: A numeric boolean (1 or 0).


GarbageCollector.getExhaustionIncrementalFullCycleThreshold

Usage:

let threshold = GarbageCollector.getExhaustionIncrementalFullCycleThreshold();
  • Description: Returns the threshold of incremental cycles after which a full collection is triggered when a memory pool is exhausted. This is a global setting that affects all collections.

  • Return Value: A numeric value (integer).


GarbageCollector.getActive

Usage:

let active = GarbageCollector.getActive();
  • Description: Returns whether the garbage collector is active (1 for true, 0 for false). This is a global setting that affects all collections.

  • Return Value: A numeric boolean (1 or 0).

  • Example:

    // Check if the garbage collector is active.
    let isActive = GarbageCollector.getActive();
    if (isActive) {
      puts("Garbage collector is active.");
    } else {
      puts("Garbage collector is inactive.");
    }

GarbageCollector.getIncremental

Usage:

let incremental = GarbageCollector.getIncremental();
  • Description: Returns whether incremental garbage collection is enabled (1 for true, 0 for false). This is a global setting that affects all collections.

  • Return Value: A numeric boolean (1 or 0).

  • Example:

    // Check if incremental garbage collection is enabled.
    let isIncremental = GarbageCollector.getIncremental();
    if (isIncremental) {
      puts("Incremental garbage collection is enabled.");
    } else {
      puts("Incremental garbage collection is disabled.");
    }

GarbageCollector.getGenerational

Usage:

let generational = GarbageCollector.getGenerational();
  • Description: Returns whether generational garbage collection is enabled (1 for true, 0 for false). This is a global setting that affects all collections.

  • Return Value: A numeric boolean (1 or 0).

  • Example:

    // Check if generational garbage collection is enabled.
    let isGenerational = GarbageCollector.getGenerational();
    if (isGenerational) {
      puts("Generational garbage collection is enabled.");
    } else {
      puts("Generational garbage collection is disabled.");
    }

GarbageCollector.getLocalContextPoolSize

Usage:

let size = GarbageCollector.getLocalContextPoolSize();
  • Description: Returns the size of the local context pool, which is used for caching and reuse of temporary contexts.

  • Return Value: A numeric value (integer).


GarbageCollector.getContextCacheSize

Usage:

let size = GarbageCollector.getContextCacheSize();
  • Description: Returns the size of the context cache that can be reused to avoid allocations of large stack frames.

  • Return Value: A numeric value (integer).


GarbageCollector.getMinimumBlockSize

Usage:

let size = GarbageCollector.getMinimumBlockSize();
  • Description: Returns the minimum block size (in number of objects) used for new allocation blocks in the memory pool.

  • Return Value: A numeric value (integer).


Setting Parameters

These functions set the current tuning parameters in the garbage collector. Each function returns the old value as a number.

GarbageCollector.setDynamicThreshold

Usage:

let old = GarbageCollector.setDynamicThreshold(newDynamicThreshold);
  • Description: Sets the garbage collector to "dynamic" threshold mode. In dynamic threshold mode (true), the GC adapts its threshold based on the current memory usage and allocation patterns. In budget decrement mode (false), the threshold is fixed and changed only at every collection cycle. This is a global setting that affects all collections. The dynamic threshold mode is more responsive to allocation spikes, while the budget decrement mode is more predictable in terms of collection intervals.

  • Parameters:

    • newDynamicThreshold (boolean): The new dynamic threshold mode.

      • When enabled (true), the garbage collector uses an incrementing threshold-based approach. The allocation counter is incremented with each memory allocation until it reaches a dynamically calculated threshold. This threshold is determined based on current memory usage and a predefined scaling factor (e.g., IncrementalCollectionThresholdFactor). When the counter exceeds or matches the threshold, garbage collection is triggered, and the counter is reset to zero. Because the threshold is evaluated at each allocation increment, its value can “float” as memory usage changes. This makes the GC trigger condition responsive to current usage patterns — if more objects are used, the threshold increases and vice versa. This approach adapts to real-time memory pressure, prioritizing responsiveness to sudden allocation spikes. It is ideal for applications with fluctuating memory demands, such as games or real-time systems.

      • When disabled (false), the garbage collector uses a decrementing budget-based approach. The allocation counter is initialized to a dynamic budget (calculated post-GC), and decremented with each allocation. When the counter reaches zero, garbage collection is triggered, and a new budget is calculated based on the current memory state. This approach yields a more predictable interval from GC trigger to trigger, regardless of any fluctuations in object usage during the counting period. The key difference in terms of predictable behavior is that once set, the threshold does not change during the cycle; it is “static” rather than recalculating on every allocation. This mode ensures predictable garbage collection intervals, as allocations consume a fixed (but dynamically adjusted) budget. It is suited for workloads with stable memory patterns, such as batch processing or steady-state applications.

    • Key Features:

      • Dynamic Threshold Mode (Enabled): Adapts to memory usage patterns, triggering GC based on real-time allocation spikes.

        • Adaptive: Threshold recalculates in real time before GC.

        • Use Case: Fluctuating memory usage (e.g., unpredictable allocations).

      • Budget Decrement Mode (Disabled): Uses a fixed threshold, triggering GC based on a consistent budget.

        • Predictable: Budget recalculates after GC, based on post-GC memory.

        • Use Case: Stable memory patterns (e.g., steady-state workloads).

    • Important Note: Using dynamic threshold mode may lead to more frequent GC cycles under heavy and bursty allocations, which can be beneficial for real-time responsiveness, while budget decrement mode provides a more consistent GC interval that may improve predictability in applications with stable loads.

  • Return Value: The old dynamic threshold mode.

  • Example:

    // Set the garbage collector to dynamic threshold mode.
    let oldDynamicThreshold = GarbageCollector.setDynamicThreshold(1);
    puts("Old dynamic threshold mode: ", oldDynamicThreshold);
    // Set the garbage collector to budget decrement mode.
    oldDynamicThreshold = GarbageCollector.setDynamicThreshold(0);
    puts("Old dynamic threshold mode: ", oldDynamicThreshold);
  • Note: The default value is 1 (enabled). Setting it to 0 (disabled) will switch the garbage collector to budget decrement mode. This setting is global and affects all collections.


GarbageCollector.setIncrementalCollectionThresholdFactor

Usage:

let old = GarbageCollector.setIncrementalCollectionThresholdFactor(0.25);
  • Description: Sets the "incremental collection threshold factor." This factor is multiplied by the current number of used objects (calculated as Allocated minus FreeCount) to compute a threshold. When the number of used objects exceeds this product, an incremental GC cycle is triggered. In essence, the lower the factor, the more aggressive the incremental collection becomes, whereas a higher factor delays GC triggering, potentially allowing more objects to accumulate before collection commences.

  • Parameters:

    • newIncrementalCollectionThresholdFactor (number): The new incremental collection threshold factor.

  • Return Value: The old incremental collection threshold factor.

  • Example:

    // Set the incremental collection threshold factor to 0.25.
    let oldFactor = GarbageCollector.setIncrementalCollectionThresholdFactor(0.25);
    puts("Old incremental collection threshold factor: ", oldFactor);
    // Set the incremental collection threshold factor to 0.5.
    oldFactor = GarbageCollector.setIncrementalCollectionThresholdFactor(0.5);
    puts("Old incremental collection threshold factor: ", oldFactor);
  • Note: The default value is 0.25, which means that the GC will trigger an incremental collection when the number of used objects exceeds 25.0% of the total allocated objects. A value of 0.5 would trigger the collection when the number of used objects exceeds 50% of the total allocated objects.


GarbageCollector.setFullCollectionThresholdFactor

Usage:

let old = GarbageCollector.setFullCollectionThresholdFactor(0.9375);
  • Description: Sets the "full collection threshold factor." This factor is multiplied by the current number of used objects (calculated as Allocated minus FreeCount) to compute a threshold value. When the number of used objects exceeds this product, a full GC cycle is triggered. In essence, a lower factor causes the GC to run more aggressively, performing full collections more frequently, while a higher factor delays full collection, permitting more objects to accumulate before initiating the process.

  • Parameters:

    • newFullCollectionThresholdFactor (number): The new full collection threshold factor.

  • Return Value: The old full collection threshold factor.

  • Example:

    // Set the full collection threshold factor to 0.9375.
    let oldFactor = GarbageCollector.setFullCollectionThresholdFactor(0.9375);
    puts("Old full collection threshold factor: ", oldFactor);
    // Set the full collection threshold factor to 0.5.
    oldFactor = GarbageCollector.setFullCollectionThresholdFactor(0.5);
    puts("Old full collection threshold factor: ", oldFactor);
  • Note: The default value is 0.9375, which means that the GC will trigger a full collection when the number of used objects exceeds 93.75% of the total allocated objects. A value of 0.5 would trigger the collection when the number of used objects exceeds 50% of the total allocated objects.


GarbageCollector.setMarkFactor

Usage:

let old = GarbageCollector.setMarkFactor(0.25)
  • Description: Sets the “mark factor”. This factor is multiplied by the current number of used objects (calculated as Allocated minus FreeCount) to compute a count of objects to be marked in a partial collection cycle.

  • Parameters:

    • newStepFactor (number): The new step factor.

  • Return Value: The old step factor.

  • Note: The default value is 0.25, which means that the GC will process 25.0% of the used objects in a partial collection cycle.


GarbageCollector.setGhostFactor

Usage:

let old = GarbageCollector.setGhostFactor(0.25);
  • Description: Sets the “ghost factor”. This factor is multiplied by the current number of used objects (calculated as Allocated minus FreeCount) to compute a count of objects to be marked in a partial collection cycle. This is the factor for partial marking/sweeping of ghost objects. The ghost factor is used to determine how aggressively ghost objects (special objects like IO streams, threads, coroutines, etc.) are processed. objects.

  • Parameters:

    • newGhostFactor (number)

  • Return Value: The old ghost factor.

  • Note: The default value is 0.25, which means that the GC will process 25.0% of the used objects in a partial collection cycle.


GarbageCollector.setSweepFactor

Usage:

let old = GarbageCollector.setSweepFactor(0.25);
  • Description: Sets the “sweep factor”. This factor is multiplied by the current number of used objects (calculated as Allocated minus FreeCount) to compute a count of objects to be swept in a partial collection cycle. This is the factor for partial sweeping of objects, which are no longer reachable. The sweep factor is used to determine how aggressively objects are swept (freed) per partial collection cycle.

  • Parameters:

    • newSweepFactor (number)

  • Return Value: The old sweep factor.

  • Note: The default value is 0.25, which means that the GC will process 25.0% of the used objects in a partial collection cycle.


GarbageCollector.setPersistentInterval

Usage:

let old = GarbageCollector.setPersistentInterval(10);
  • Description: Sets how often (in cycles) persistent objects are rescanned.

  • Parameters:

    • newPersistentInterval (number)

  • Return Value: The old interval value.


GarbageCollector.setPersistentThreshold

Usage:

let old = GarbageCollector.setPersistentThreshold(3);
  • Description: Sets how many GC cycles an object must survive before it’s considered persistent (long-lived).

  • Parameters:

    • newPersistentThreshold (number)

  • Return Value: The old threshold value.


GarbageCollector.setExhaustionCollect

Usage:

let old = GarbageCollector.setExhaustionCollect(1);
  • Description: Enables or disables “exhaustion collection” (0 or 1), which triggers a collection when a memory pool is exhausted. This is a global setting that affects all collections.

  • Parameters:

    • exhaustionCollect (number): 0 or 1 (false or true)

  • Return Value: The old setting (0 or 1).


GarbageCollector.setExhaustionIncrementalFullCycleThreshold

Usage:

let old = GarbageCollector.setExhaustionIncrementalFullCycleThreshold(512);
  • Description: Sets the threshold of incremental cycles after which a full collection is triggered when a memory pool is exhausted. This is a global setting that affects all collections.

  • Parameters:

    • newExhaustionIncrementalFullCycleThreshold (number): The new exhaustion incremental full cycle threshold, where 0 means no full collection is triggered after exhaustion, and -1 means full collection is triggered immediately in every case, otherwise it is the number of incremental cycles after which a full collection is triggered.

  • Return Value: The old threshold value.


GarbageCollector.setActive

Usage:

let old = GarbageCollector.setActive(active);
  • Description: Enables or disables the garbage collector (1 for true, 0 for false). This is a global setting that affects all collections.

  • Parameters:

    • active (number): 0 or 1 (false or true)

  • Return Value: The old setting (0 or 1).

  • Example:

    // Enable the garbage collector.
    let oldSetting = GarbageCollector.setActive(1);
    puts("Old garbage collector setting: ", oldSetting);
    // Disable the garbage collector.
    oldSetting = GarbageCollector.setActive(0);
    puts("Old garbage collector setting: ", oldSetting);

GarbageCollector.setIncremental

Usage:

let old = GarbageCollector.setIncremental(active);
  • Description: Enables or disables the incremental garbage collection mode. This is a global setting that affects all collections. When incremental mode is enabled, the garbage collector processes objects in smaller steps, allowing for more responsive memory management.

  • Parameters:

    • active (number): 0 or 1 (false or true)

  • Return Value: The old setting (0 or 1).

  • Example:

    // Enable incremental garbage collection.
    let oldSetting = GarbageCollector.setIncremental(1);
    puts("Old incremental setting: ", oldSetting);
    // Disable incremental garbage collection.
    oldSetting = GarbageCollector.setIncremental(0);
    puts("Old incremental setting: ", oldSetting);

GarbageCollector.setGenerational

Usage:

let old = GarbageCollector.setGenerational(active);
  • Description: Enables or disables the generational garbage collection mode. This is a global setting that affects all collections. When generational mode is enabled, the garbage collector treats objects differently based on their age, allowing for more efficient memory management.

  • Parameters:

    • active (number): 0 or 1 (false or true)

  • Return Value: The old setting (0 or 1).

  • Example:

    // Enable generational garbage collection.
    let oldSetting = GarbageCollector.setGenerational(1);
    puts("Old generational setting: ", oldSetting);
    // Disable generational garbage collection.
    oldSetting = GarbageCollector.setGenerational(0);
    puts("Old generational setting: ", oldSetting);

GarbageCollector.setLocalContextPoolSize

Usage:

let old = GarbageCollector.setLocalContextPoolSize(32);
  • Description: Adjusts the size of the local context pool used for reusing smaller contexts.

  • Parameters:

    • newSize (number)

  • Return Value: The old size.


GarbageCollector.setContextCacheSize

Usage:

let old = GarbageCollector.setContextCacheSize(64);
  • Description: Sets how many contexts can be cached.

  • Parameters:

    • newSize (number)

  • Return Value: The old size.


GarbageCollector.setMinimumBlockSize

Usage:

let old = GarbageCollector.setMinimumBlockSize(16);
  • Description: Changes the minimum block size for allocation in each memory pool.

  • Parameters:

    • newBlockSize (number)

  • Return Value: The old block size.


Triggering Collection

These functions let you manually request garbage collection or single cycles. They are useful if you want more control over memory usage.

GarbageCollector.collect

Usage:

GarbageCollector.collect();
  • Description: Requests a full garbage collection and immediately processes it. This runs through ephemeral and persistent objects, calling finalizers where needed.

  • Return Value: A numeric value (1). This is a dummy success code.


GarbageCollector.cycle

Usage:

GarbageCollector.cycle();
  • Description: Requests an incremental or partial collection cycle, marking and freeing some subset of objects. This is typically less disruptive but may leave some objects for the next cycle.

  • Return Value: A numeric value (1), a dummy success code.


Memory Usage Queries

These functions report the amount of memory (or number of objects) currently allocated, used, or free in the GC system.

GarbageCollector.allocated

Usage:

let amount = GarbageCollector.allocated();
  • Description: Returns the total count of allocated objects within the system.

  • Return Value: A numeric value representing the number of allocated objects.


GarbageCollector.used

Usage:

let amount = GarbageCollector.used();
  • Description: Returns how many allocated objects are actually in use (allocated minus freed).

  • Return Value: A numeric value (in objects).


GarbageCollector.free

Usage:

let amount = GarbageCollector.free();
  • Description: Returns how many objects are in the free list (ready for reuse).

  • Return Value: A numeric value (in objects).


Summary

  • Global Object: The GarbageCollector object allows you to configure and interact with POCA’s garbage collection system, controlling how aggressively and frequently collection occurs, and whether ephemeral plus persistent objects are handled.

  • Parameter Getter/Setter Functions:

    • GarbageCollector.getDynamicThreshold, GarbageCollector.setDynamicThreshold

    • GarbageCollector.getIncrementalCollectionThresholdFactor, GarbageCollector.setIncrementalCollectionThresholdFactor

    • GarbageCollector.getFullIntervalFactor, GarbageCollector.setFullIntervalFactor

    • GarbageCollector.getMarkFactor, GarbageCollector.setMarkFactor

    • GarbageCollector.getGhostFactor, GarbageCollector.setGhostFactor

    • GarbageCollector.getSweepFactor, GarbageCollector.setSweepFactor

    • GarbageCollector.getPersistentInterval, GarbageCollector.setPersistentInterval

    • GarbageCollector.getPersistentThreshold, GarbageCollector.setPersistentThreshold

    • GarbageCollector.getExhaustionCollect, GarbageCollector.setExhaustionCollect

    • GarbageCollector.getActive, GarbageCollector.setActive

    • GarbageCollector.getIncremental, GarbageCollector.setIncremental

    • GarbageCollector.getGenerational, GarbageCollector.setGenerational

    • GarbageCollector.getLocalContextPoolSize, GarbageCollector.setLocalContextPoolSize

    • GarbageCollector.getContextCacheSize, GarbageCollector.setContextCacheSize

    • GarbageCollector.getMinimumBlockSize, GarbageCollector.setMinimumBlockSize

  • GC Operations:

    • GarbageCollector.collect(): Forces a full collection (ephemeral
      persistent generations).

    • GarbageCollector.cycle(): Runs an incremental or partial cycle.

  • Memory Usage:

    • GarbageCollector.allocated(): Number of allocated objects.

    • GarbageCollector.used(): Number of currently used objects.

    • GarbageCollector.free(): Number of free objects in the pool.

  • Usage: By tuning these parameters, you can control how often GC runs and how thoroughly it sweeps. You can also request manual partial or full collections, or simply query how much memory is used. This flexibility allows you to adapt POCA’s garbage collection strategy to different performance requirements in a dynamic, typeless environment.

  • Note: The garbage collector is designed to be efficient and incremental, allowing for low-latency applications. The API provides a comprehensive set of functions to manage memory usage and performance tuning, making it suitable for a wide range of use cases.

Global Functions

Overview

The POCA global functions provide a set of utility functions that facilitate common operations in POCA scripts. These functions are available globally and can be used without needing to create an instance of any object. They include functions for type checking, string manipulation, array handling, and more. The functions are designed to be simple and intuitive, allowing you to perform operations on various data types easily.


Global Functions

size

Usage:

let n = size(value);
  • Description: Determines the size/length of the provided value, which can be a string, array, or hash:

    • String: Returns the string’s length. If UTF-8, returns its code point count.

    • Array: Returns the array’s number of elements.

    • Hash: Returns the hash’s entry count.

    • Other types: Returns 0.

  • Parameters:

    • value (string | array | hash)

  • Return Value: A numeric value.

  • Example:

    size("Hello");      // 5
    size(["a","b","c"]); // 3
    size({x:1,y:2});     // 2
    size(42);            // 0

ownKeys

Usage:

let keysArray = ownKeys(myHash);
  • Description: Returns an array of the own keys in a hash (i.e., keys directly in that hash, not in a prototype chain). The returned array is sorted.

  • Parameters:

    • hash (hash): The hash from which to get keys.

  • Return Value: An array of strings representing the hash’s own keys.

  • Example:

    let h = {a: 1, b: 2};
    let arr = ownKeys(h); // ["a", "b"]

keys

Usage:

let keysArray = keys(myHash);
  • Description: Similar to ownKeys, but for standard key enumeration (which may differ if the hash uses prototypes or special handling). The returned array is sorted.

  • Parameters:

    • hash (hash): The hash from which to get keys.

  • Return Value: An array of strings representing the enumerated keys.

  • Example:

    let h = {a: 1, b: 2};
    let arr = keys(h); // ["a", "b"]

print

Usage:

print(value1, value2, ...);
  • Description: Prints each argument’s string representation (without a newline). Accepts null, strings, or numbers. If a custom UserIOWrite function is registered, it uses that; otherwise, it uses System.Write.

  • Parameters:

    • valueX: The values to be printed (null, string, or number).

  • Return Value: No meaningful return; the function returns null.

  • Example:

    print("Hello, ", 123);
    // Output on the same line: Hello, 123

puts

Usage:

puts(value1, value2, ...);
  • Description: Similar to print, but appends a newline at the end. Accepts null, strings, or numbers. After printing all arguments, writes a newline ("\n").

  • Parameters:

    • valueX: The values to be printed (null, string, or number).

  • Return Value: No meaningful return; the function returns null.

  • Example:

    puts("Hello, World!");
    // Output: Hello, World!
    // (plus a newline)

readLine

Usage:

let input = readLine(prompt);
  • Description: Reads a line of input from the console. If a prompt string is given, prints that before waiting for input. Uses ReadLine(Context,promptValue) under the hood.

  • Parameters:

    • prompt (string, optional): A string to prompt the user.

  • Return Value: A string with the line read from the user.

  • Example:

    let name = readLine("Enter name: ");
    puts("Hello, " + name);

chr

Usage:

let charStr = chr(codePoint);
  • Description: Converts a numeric code point to a single-character string in UTF-8 form.

  • Parameters:

    • codePoint (number): The Unicode code point.

  • Return Value: A string with that single character.

  • Example:

    chr(65); // "A"

ord

Usage:

let codePoint = ord(charStr);
  • Description: Converts a single-character string to its numeric code point in UTF-8 form.

  • Parameters:

    • charStr (string): The single-character string.

  • Return Value: A numeric code point.

  • Example:

    ord("A"); // 65

sleep

Usage:

sleep(milliseconds);
  • Description: Pauses execution for the specified number of milliseconds. This is a blocking call, meaning it halts the current execution until the time has elapsed.

  • Parameters:

    • milliseconds (number): The number of milliseconds to sleep.

  • Return Value: No meaningful return; the function returns null.

  • Example:

    puts("Sleeping for 2 seconds...");
    sleep(2000);
    puts("Awake!");
    // Output:
    // Sleeping for 2 seconds...
    // (waits 2 seconds)
    // Awake!

contains

Usage:

if (contains(myHash, "someKey")) {
  puts("Yes");
}
  • Description: Checks if a hash contains a specific key.

  • Parameters:

    1. hash (hash): A hash object.

    2. key (any): The key to look for.

  • Return Value: A numeric boolean (1 or 0).


import

See also ModuleManager.import.

Usage:

import * from "ModuleName";
import a, b from "ModuleName";
// or function call:
import("ModuleName", ["a","b"], allowReloadIfNewer);
  • Description: Loads the specified module (if not already cached), optionally reloading if newer. If a list of imports is provided, only those symbols are pulled into the current scope. If ["*"] or ["all"] is used, it imports all available exports.

  • Parameters:

    • moduleName (string): The name/path of the module.

    • imports (array, optional): Which symbols to import.

    • allowReloadIfNewer (boolean, optional): If true, checks if the file has changed.

  • Return Value: If called via syntax import ... from ...;, it doesn’t return a value. If called as import(moduleName, imports, reload), it returns the module’s scope or exported hash.


require

See also ModuleManager.require.

Usage:

let moduleObj = require("ModuleName", allowReloadIfNewer);
  • Description: Loads (and possibly reloads) the specified module, returning whatever the module returned. This can be an object, function, or anything else the module’s code ends with return.

  • Parameters:

    • moduleName (string): The name/path of the module.

    • allowReloadIfNewer (boolean, optional): If true, checks if the module file changed.

  • Return Value: The module’s exported object.


eval

Usage:

let result = eval(codeString, filename, callArguments, callThis, callNamespace);
  • Description: Compiles and executes a code string in a sub-context. Optionally provides:

    • filename: for debugging reference

    • callArguments: array of arguments

    • callThis: “this” binding

    • callNamespace: a namespace object (hash) for top-level scope

  • Parameters:

    1. codeString (string): The POCA code to compile and run.

    2. filename (string, optional): Used for debugging or error messages.

    3. callArguments (array, optional): If present, these are passed as function arguments.

    4. callThis (hash | ghost, optional): The this context for the eval code.

    5. callNamespace (hash, optional): The namespace in which the code runs.

  • Return Value: Whatever the eval’d code returns.


compile

Usage:

let codeObject = compile(source, filename, rawCode);
  • Description: Compiles source into a code object. If rawCode is false or omitted, compile then “binds” the code object to the current context, making it directly callable. If rawCode is true, you get just the raw code object.

  • Parameters:

    1. source (string): The POCA code to compile.

    2. filename (string, optional): For debugging or references.

    3. rawCode (boolean, optional): If true, returns just raw code object; otherwise returns a code object bound to the current context.

  • Return Value: A code object (raw or bound).


caller

Usage:

let info = caller(level);
  • Description: Returns an array of information about a stack frame. The default level is 1, which means the caller of the current function.

  • Parameters:

    • level (number): How many levels to go up the call stack. 0 means current frame, 1 is the caller, etc.

  • Return Value: An array containing [localsHash, func, obj, sourceFile, lineNumber] for that frame, or null if out of range.


closure

Usage:

let arr = closure(func, index);
  • Description: Returns the [namespace, obj] pair from a function closure in a chain. If a function has “next” references (like chained closures), index selects which link in the chain.

  • Parameters:

    1. func (function): The function to inspect.

    2. index (number): Which link in the chain (0 for the first, 1 for next, etc.).

  • Return Value: An array [namespace, obj] or null if out of range.


bind

Usage:

let newFunc = bind(originalFunc, namespaceHash, obj, next);
  • Description: Creates a new function object based on originalFunc but with a new namespace, optional “this” (obj), and optional next reference. This effectively re-binds a function’s environment.

  • Parameters:

    1. originalFunc (function): The function to clone.

    2. namespaceHash (hash): The new namespace.

    3. obj (function, optional): The new “this” object (or null).

    4. next (function, optional): The new next closure link.

  • Return Value: A newly created function.


call

Usage:

let result = call(func, argumentsArray, thisVal, namespace);
  • Description: Calls a function in a sub-context, optionally providing:

    • argumentsArray: an array of arguments

    • thisVal: a “this” context

    • namespace: an alternate top-level namespace

  • Parameters:

    1. func (function): The function to call.

    2. argumentsArray (array, optional)

    3. thisVal (hash | ghost, optional)

    4. namespace (hash, optional)

  • Return Value: Whatever the function call returns.


setHashEvents

Usage:

setHashEvents(myHash, eventsHash);
  • Description: Attaches a special events hash to a hash. This can override meta-operations (get, set, etc.). Returns the original hash.

  • Parameters:

    1. myHash (hash)

    2. eventsHash (hash)

  • Return Value: The original myHash.


getHashEvents

Usage:

let ev = getHashEvents(myHash);
  • Description: Retrieves the current events hash associated with a hash, if any.

  • Parameters:

    • myHash (hash)

  • Return Value: A hash representing the events, or null if no special events are assigned.


rawDelete

Usage:

let success = rawDelete(myHash, key);
  • Description: Deletes a key in a hash without invoking meta-events (setHashEvents). Returns 1 if a key was deleted, 0 otherwise.

  • Parameters:

    1. myHash (hash)

    2. key (any)

  • Return Value: A numeric boolean (1 or 0).


rawExist

Usage:

let yesNo = rawExist(myHash, key);
  • Description: Checks if a key exists in a hash without invoking meta-events. Returns 1 if present, 0 if not.

  • Parameters:

    1. myHash (hash)

    2. key (any)

  • Return Value: A numeric boolean (1 or 0).


rawGet

Usage:

let val = rawGet(myHash, key);
  • Description: Retrieves the value from a hash for a given key without triggering meta-events.

  • Parameters:

    1. myHash (hash)

    2. key (any)

  • Return Value: The value associated with key, or null if not found.


rawSet

Usage:

rawSet(myHash, key, value);
  • Description: Sets a key in a hash without meta-events.

  • Parameters:

    1. myHash (hash)

    2. key (any)

    3. value (any)

  • Return Value: Returns the myHash object.


rawSize

Usage:

let n = rawSize(myHash);
  • Description: Returns the number of entries in a hash without meta-events. Equivalent to the internal hash size.

  • Parameters:

    • myHash (hash)

  • Return Value: A numeric value representing the entry count.


rawKeys

Usage:

let kArray = rawKeys(myHash);
  • Description: Returns an array of key strings from the hash without meta-events. The array is sorted.

  • Parameters:

    • myHash (hash)

  • Return Value: A sorted array of keys.


map

Usage:

let result = map(collection, callback);
  • Description: Creates a new array or hash by applying a callback function to each element of the input collection.

    • For arrays: The callback receives (value, index, array) and the result is a new array.

    • For hashes: The callback receives (key, value, hash) and the result is a new hash with the same keys but transformed values.

  • Parameters:

    • collection (array | hash): The collection to map over.

    • callback (function): Function to call for each element.

  • Return Value: A new array or hash with transformed values.

  • Example:

    let numbers = [1, 2, 3, 4];
    let doubled = map(numbers, function(x) { return x * 2; });
    // doubled is [2, 4, 6, 8]
    
    let person = { name: "Alice", age: 30 };
    let exclaimed = map(person, function(key, value) {
      return value ~ "!";
    });
    // exclaimed is { name: "Alice!", age: "30!" }

reduce

Usage:

let result = reduce(collection, callback);
let result = reduce(collection, callback, initialValue);
  • Description: Reduces a collection to a single value by executing a reducer function on each element.

    • For arrays: Processes elements from left to right. The callback receives (accumulator, value, index, array).

    • For hashes: Processes key-value pairs. The callback receives (accumulator, key, value, hash). Note that hash iteration order is based on sorted keys.

  • Parameters:

    • collection (array | hash): The collection to reduce.

    • callback (function): Reducer function called for each element.

    • initialValue (optional): Starting value. If omitted, uses the first element/value as initial.

  • Return Value: The final accumulated value.

  • Example:

    // Array example
    let numbers = [1, 2, 3, 4];
    let sum = reduce(numbers, function(acc, val) {
      return acc + val;
    });
    // sum is 10
    
    // Hash example
    let scores = { math: 90, science: 85, english: 92 };
    let total = reduce(scores, function(acc, key, value) {
      return acc + value;
    }, 0);
    // total is 267

reduceRight

Usage:

let result = reduceRight(collection, callback);
let result = reduceRight(collection, callback, initialValue);
  • Description: Reduces a collection to a single value by executing a reducer function, but processes elements from right to left (for arrays) or in the same order as reduce (for hashes, since they have no inherent direction).

    • For arrays: Processes elements from right to left. The callback receives (accumulator, value, index, array).

    • For hashes: Behaves identically to reduce since hashes have no inherent order. The callback receives (accumulator, key, value, hash).

  • Parameters:

    • collection (array | hash): The collection to reduce.

    • callback (function): Reducer function called for each element.

    • initialValue (optional): Starting value. If omitted, uses the last element (arrays) or first key-value pair (hashes) as initial.

  • Return Value: The final accumulated value.

  • Example:

    // Array example - subtract from right to left
    let nums = [1, 2, 3, 4];
    let diff = reduceRight(nums, function(acc, val) {
      return acc - val;
    });
    // diff is -2 (4 - 3 - 2 - 1)
    
    // Build array in reverse
    let reversed = reduceRight(nums, function(acc, val) {
      acc.push(val);
      return acc;
    }, []);
    // reversed is [4, 3, 2, 1]

Summary

Global Functions in POCA

The global namespace contains a variety of utilities that let you:

  1. Interact with arrays, hashes, and strings using size, 'length', ownKeys, keys, etc.

  2. Perform console I/O with print, puts, and readLine.

  3. Manipulate strings with chr, ord for character operations.

  4. Pause execution with sleep for pausing execution.

  5. Manage or query modules with import, require (duplicates of ModuleManager’s functions).

  6. Evaluate code with eval and compile, manipulate function closures with caller, closure, bind, and call.

  7. Control or bypass hash meta-events with rawGet, rawSet, etc.

  8. Transform and reduce collections with map, reduce, and reduceRight for both arrays and hashes.

These functions enable rapid scripting and flexible data handling in POCA’s dynamic environment. When combined with the features of ModuleManager and other built-in namespaces (like IO, Array, etc.), they provide a rich and extensible standard library for your POCA code.

Note: The global functions are designed to be easy to use and understand, making them suitable for both beginners and experienced developers. They provide a consistent interface for common tasks, allowing you to focus on your application logic rather than low-level details.

Function

Overview

The POCA Function API provides methods that can be called on function values. Functions in POCA can be stored in variables, passed as arguments, and have methods called on them. The FunctionHash prototype provides these methods to all function values, enabling advanced function manipulation and invocation patterns.


API Functions

Function.call

Usage:

let result = myFunction.call(arguments, thisValue, namespace);
  • Description: Invokes a function with an explicit this context and namespace. This method provides fine-grained control over function execution by allowing you to specify the context (this binding) and the namespace in which the function executes. The call method is particularly useful for: applying a function to different objects, borrowing methods from one object to use on another, or controlling the execution environment of dynamically generated functions.

  • Parameters:

    • arguments – An array of arguments to pass to the function, or null if no arguments are needed. Each element in the array becomes a parameter to the function call.

    • thisValue (optional) – The value to use as this when executing the function. Must be a hash or ghost object. If not provided or null, the function executes without a specific this context.

    • namespace (optional) – A hash object to use as the namespace for the function execution. If not provided, a new empty hash is created as the namespace.

  • Return Value: The return value of the invoked function.

  • Example:

    // Basic usage - calling a function with arguments
    function greet(name, title) {
      print("Hello, " ~ title ~ " " ~ name ~ "!\n");
      return "Greeted " ~ name;
    }
    
    let result = greet.call(["Alice", "Dr."]);
    // Prints: Hello, Dr. Alice!
    // result is "Greeted Alice"
    
    // Using with a custom 'this' context
    function introduce() {
      print("I am " ~ this.name ~ " from " ~ this.city ~ "\n");
    }
    
    let person = { name: "Bob", city: "Berlin" };
    introduce.call([], person);
    // Prints: I am Bob from Berlin
    
    // Comparing with global call() function
    // These two calls are equivalent:
    let result1 = myFunc.call([arg1, arg2], thisObj);
    let result2 = call(myFunc, [arg1, arg2], thisObj);
  • Notes:

    • The call method is similar to the global call function, but with the function itself as the receiver (method syntax) rather than as the first parameter.

    • If the arguments parameter is not null or an array, a runtime error is raised.

    • The thisValue parameter is only used if it is a hash or ghost object; otherwise, the function executes without a specific this binding.

    • A new sub-context is created for the function execution to ensure proper scoping and error handling.


Function.closure

Usage:

let closureData = myFunction.closure(index);
  • Description: Retrieves the closure data (namespace and object context) for a function at a specified index in the closure chain. Functions in POCA can have nested closures, forming a chain where each function captures its execution environment. This method allows you to inspect these captured environments by traversing the closure chain.

  • Parameters:

    • index (optional) – A numeric value indicating which closure in the chain to retrieve. 0 (the default) refers to the current function’s closure, 1 refers to the next closure in the chain, and so on.

  • Return Value: An array containing two elements: [namespace, object], where namespace is the hash object representing the function’s namespace, and object is the context object. Returns null if the index is out of range or if no closure exists at that position.

  • Example:

    function outer() {
      var x = 10;
    
      function inner() {
        var y = 20;
    
        // Get the closure data for this function
        let closureData = inner.closure(0);
        print("Namespace: " ~ closureData[0] ~ "\n");
        print("Object: " ~ closureData[1] ~ "\n");
    
        // Get the closure data for the outer function
        let outerClosure = inner.closure(1);
        if (outerClosure != null) {
          print("Outer namespace: " ~ outerClosure[0] ~ "\n");
        }
      }
    
      return inner;
    }
    
    let fn = outer();
    fn();
    
    // Comparing with global closure() function
    // These two calls are equivalent:
    let data1 = myFunc.closure(0);
    let data2 = closure(myFunc, 0);
  • Notes:

    • The closure method is similar to the global closure function, but with the function itself as the receiver (method syntax) rather than as the first parameter.

    • Closures are fundamental to POCA’s scoping model and allow functions to capture and access variables from their defining scope even after that scope has finished executing.

    • This method is primarily useful for debugging, introspection, or advanced metaprogramming scenarios.


Function.bind

Usage:

let boundFunc = myFunction.bind(namespace, thisObj, nextFunc);
  • Description: Creates a new function with a specific namespace, this object, and optional next function in the closure chain. This is a powerful mechanism for creating functions with pre-configured execution environments, enabling partial application, method borrowing, and custom closure chains.

  • Parameters:

    • namespace (optional) – A hash object to use as the function’s namespace. This defines the scope in which the function will execute. If not provided or invalid, a new empty hash is created.

    • thisObj (optional) – The value to bind as this within the function. Must be null or a function value. If not provided, defaults to null.

    • nextFunc (optional) – Another function to link in the closure chain. Must be null or a function value. If not provided, defaults to null.

  • Return Value: A new function that shares the same code as the original but with the specified namespace, this object, and closure chain.

  • Example:

    function greet(name) {
      print("Hello, " ~ name ~ "!\n");
      print("Language: " ~ this.language ~ "\n");
    }
    
    // Create a namespace with some variables
    let context = { language: "English" };
    let customNamespace = { greeting: "Hi" };
    
    // Bind the function with a custom namespace and 'this' object
    let boundGreet = greet.bind(customNamespace, context);
    
    boundGreet.call(["Alice"]);
    // Prints: Hello, Alice!
    //         Language: English
    
    // Partial application example
    function add(a, b) {
      return a + b;
    }
    
    let addFive = add.bind({ five: 5 });
    // Use the bound function
    let result = addFive.call([3, 5]);
    print("Result: " ~ result ~ "\n"); // Result: 8
    
    // Comparing with global bind() function
    // These two calls are equivalent:
    let bound1 = myFunc.bind(ns, thisObj, next);
    let bound2 = bind(myFunc, ns, thisObj, next);
  • Notes:

    • The bind method is similar to the global bind function, but with the function itself as the receiver (method syntax) rather than as the first parameter.

    • The newly created function shares the same bytecode as the original but operates in a different execution environment.

    • This is useful for creating specialized versions of functions with pre-configured contexts, implementing partial application, or building complex closure chains for advanced control flow.

    • The thisObj and nextFunc parameters must be either null or function values; any other type will cause a runtime error.


Summary

Function Methods in POCA

The Function API provides methods for advanced function manipulation:

  1. call – Invoke a function with explicit control over the arguments array, this context, and execution namespace.

  2. closure – Retrieve the closure data (namespace and object) for a function at a specific index in the closure chain.

  3. bind – Create a new function with a specific namespace, this object, and closure chain configuration.

These methods enable functional programming patterns such as dynamic method borrowing, context manipulation, and flexible function application. When combined with POCA’s closure support and the global functions like bind, caller, and closure, the Function API provides a powerful foundation for advanced scripting patterns.

Note: All functions in POCA automatically have access to these methods through the FunctionHash prototype. There is no need to explicitly create or configure function objects – any function value can immediately use these methods.

Hash

Overview

The POCA Hash API provides a set of functions to manipulate hash objects (dictionaries) in POCA scripts. Hashes are key–value collections with their own built-in methods for querying, modifying, and managing properties. The API includes functions to check if a hash is empty, get its size, add entries from another hash, query for keys, and even bypass meta-event handling with “raw” operations.


API Functions

Hash.empty

Usage:

let isEmpty = myHash.empty();
  • Description: Checks if the hash contains no entries. Returns 1 (true) if the hash is empty, or 0 (false) otherwise.

  • Parameters: None.

  • Return Value: A numeric boolean (1 if empty, 0 otherwise).


Hash.size

Usage:

let n = myHash.size();
  • Description: Returns the number of entries in the hash.

  • Parameters: None.

  • Return Value: A numeric value representing the number of key–value pairs.


Hash.merge

Usage:

myHash.merge(anotherHash);
  • Description: Merges entries from one or more hash objects into the current hash. Only arguments that are hashes are processed; others are ignored.

  • Parameters: One or more hash objects to merge.

  • Return Value: The original hash (after merging).


Hash.contains

Usage:

let present = myHash.contains("keyName");
  • Description: Checks whether the hash contains a given key. Returns 1 (true) if the key is present, or 0 (false) otherwise.

  • Parameters:

    • key (any): The key to look for.

  • Return Value: A numeric boolean.


Hash.toArray

Usage:

let arr = myHash.toArray();
  • Description: Converts the hash into an array of key–value pairs.

  • Parameters: None.

  • Return Value: An array of key–value pairs.


Hash.keys

Usage:

let keysArray = myHash.keys();
  • Description: Returns a sorted array of all keys in the hash (including inherited ones, depending on the implementation).

  • Parameters: None.

  • Return Value: An array of keys.


Hash.ownKeys

Usage:

let ownKeysArray = myHash.ownKeys();
  • Description: Returns a sorted array of the hash’s own keys (excluding keys inherited from prototypes).

  • Parameters: None.

  • Return Value: An array of strings representing the hash’s own keys.


Hash.setHashEvents

Usage:

myHash.setHashEvents(eventsHash);
  • Description: Attaches a special events hash to the hash. These events can override standard meta-operations like property access or modification. Returns the original hash.

  • Parameters:

    • eventsHash (hash): A hash containing event handlers.

  • Return Value: The original myHash.


Hash.getHashEvents

Usage:

let events = myHash.getHashEvents();
  • Description: Retrieves the events hash associated with the hash, if any.

  • Parameters: None.

  • Return Value: A hash representing the events, or null if no special events are assigned.


Hash.rawDelete

Usage:

let success = myHash.rawDelete("keyName");
  • Description: Deletes a key in the hash without invoking meta-events. Returns 1 if a key was deleted, 0 otherwise.

  • Parameters:

    • key (any): The key to delete.

  • Return Value: A numeric boolean (1 or 0).


Hash.rawExist

Usage:

let exists = myHash.rawExist("keyName");
  • Description: Checks if a key exists in the hash without invoking meta-events. Returns 1 if present, 0 if not.

  • Parameters:

    • key (any): The key to check.

  • Return Value: A numeric boolean (1 or 0).


Hash.rawGet

Usage:

let value = myHash.rawGet("keyName");
  • Description: Retrieves the value from a hash for a given key without triggering meta-events.

  • Parameters:

    • key (any): The key to look up.

  • Return Value: The value associated with key, or null if not found.


Hash.rawSet

Usage:

myHash.rawSet("keyName", someValue);
  • Description: Sets a key in the hash without meta-events.

  • Parameters:

    1. key (any): The key to set.

    2. value (any): The value to assign.

  • Return Value: Returns the original myHash.


Hash.rawSize

Usage:

let n = myHash.rawSize();
  • Description: Returns the number of entries in the hash without meta-events. Equivalent to the internal hash size.

  • Parameters: None.

  • Return Value: A numeric value representing the entry count.


Hash.rawKeys

Usage:

let kArray = myHash.rawKeys();
  • Description: Returns an array of key strings from the hash without meta-events. The array is sorted.

  • Parameters: None.

  • Return Value: A sorted array of keys.


Summary

  • Global Object: The Hash object is a native collection type in POCA used for key–value storage. It provides a comprehensive suite of functions for querying and manipulating its entries.

  • Hash API Functions:

    • Hash.empty: Checks if the hash is empty.

    • Hash.size: Returns the number of entries.

    • Hash.merge: Merges other hash objects into the current hash.

    • Hash.contains: Checks for the presence of a key.

    • Hash.toArray: Converts the hash to an array of key–value pairs.

    • Hash.keys / Hash.ownKeys: Retrieve sorted arrays of keys.

    • Hash.setHashEvents / Hash.getHashEvents: Attach or retrieve custom event handlers for hash operations.

    • Hash.rawDelete, Hash.rawExist, Hash.rawGet, Hash.rawSet, Hash.rawSize, Hash.rawKeys: Perform low-level operations on the hash bypassing meta-events.

  • Usage: These global functions enable flexible and efficient manipulation of hash objects in POCA. They support both standard high-level operations and low-level “raw” operations that bypass additional event processing, providing developers with fine-grained control over data structures in a dynamic, typeless environment.

  • Note: The Hash API is designed to be intuitive and easy to use, allowing developers to work with hash objects without needing to understand the underlying implementation details. The functions are optimized for performance and can handle large datasets efficiently.

IO

Overview

The POCA IO API provides file input/output functionality for a dynamic, typeless language. Instead of dealing with static types, you interact with a global IO object. The IO.open method creates a ghost object that represents a file, and you call I/O methods directly on that ghost object. The API supports both text and binary modes while handling resource management internally.


Global Object: IO

The IO object is the entry point for file operations. It offers:

IO.open

Usage:

let file = IO.open(filename, mode);
  • Parameters:

    • filename (string): The file name or path.

    • mode (string, optional): Determines how the file is opened. Modes include:

      • Text Modes:

        • "r": Open for reading.

        • "rw": Open for reading and writing.

        • "w": Open for writing (creates the file if it does not exist, or truncates it if it does).

        • "c": Open for reading and writing, creating the file if it does not exist.

      • Binary Modes:

        • "rb": Open for reading in binary mode.

        • "rwb": Open for reading and writing in binary mode.

        • "wb": Open for writing in binary mode (creates/truncates as needed).

        • "cb": Open for reading and writing in binary mode, creating the file if necessary.

  • Return Value: A ghost object representing the file. This object exposes various methods for file I/O.

  • Example:

    // Open a text file for reading
    let file = IO.open("example.txt", "r");

IO.getDirectoryEntries

Usage:

let entries = IO.getDirectoryEntries(directoryPath);
  • Description: Returns an array of hashes/objects of file and directory entries in the specified directory. Each entry contains information about the file or directory, such as its name, size, and type.

  • Parameters:

    • directoryPath (string): The path to the directory to list.

  • Return Value: An array of hashes/objects, each representing a file or directory entry.

  • Example:

    // Get entries in the current directory
    let entries = IO.getDirectoryEntries("./*");
    foreach(let entry in entries) {
        puts("Name: ", entry.name);
        puts("Size: ", entry.size);
        puts("Type: ", entry.type);
    }
  • Note: The entries returned may include files, directories, and other types of objects, depending on the file system and the directory contents. The type field in the entry hash/object indicates whether the entry is a file, directory, or other type. The size field may not be applicable for directories. The name field contains the name of the entry.


File Ghost Object Methods

Once you have a file ghost object, the following methods are available:

IO.read

Usage:

let data = file.read(length);
  • Description: Reads data from the file.

    • Text Mode: Reads and returns a string.

    • Binary Mode: Reads a specified number of bytes (defaults to 1 if omitted).

  • Return Value: A string containing the data read. Returns a null value if the file is not open or an error occurs.

  • Example:

    // Read 10 characters/bytes
    let chunk = file.read(10);

IO.readln

Usage:

let line = file.readln();
  • Description: Reads a full line from the file (only applicable in text mode). In binary mode, it returns a null value or no action occurs.

  • Return Value: A string containing the line read from the file.

  • Example:

    let line = file.readln();

IO.write

Usage:

let count = file.write(data);
  • Description: Writes the provided string data to the file.

    • In text mode, the string is written directly.

    • In binary mode, the string (or its byte representation) is written using block write operations.

  • Return Value: The number of characters (or bytes) written.

  • Example:

    let bytesWritten = file.write("Hello, POCA!");

IO.writeln

Usage:

let count = file.writeln(data);
  • Description: Writes the string data followed by a newline sequence (platform-dependent, e.g., \n on Unix-like systems or \r\n on others).

  • Return Value: The total number of characters (or bytes) written, including the newline.

  • Example:

    let count = file.writeln("This is a new line.");

IO.eof

Usage:

let atEnd = file.eof();
  • Description: Checks whether the file pointer has reached the end-of-file.

  • Return Value: A truthy value (e.g., true or 1) if the end is reached, otherwise a falsy value (e.g., false or 0).

  • Example:

    if (file.eof()) {
        // End of file reached
    }

IO.close

Usage:

file.close();
  • Description: Closes the file associated with the ghost object. This method ensures that any open file handles are closed and that allocated resources are freed. It handles system handles (which should not be freed) appropriately.

  • Return Value: A numeric value indicating whether the file was open (for example, 1 if open, 0 otherwise).

  • Example:

    file.close();

Example Usage

Below is a complete example that demonstrates opening a file, processing its contents, and closing it using the POCA IO API. Remember, for output, use puts for printing with a newline and print for printing without one.

// Open a text file for reading
let file = IO.open("data.txt", "r");
if (file) {
    // Read and output each line until end-of-file
    while (!file.eof()) {
        let line = file.readln();
        puts(line);
    }
    file.close();
} else {
    puts("Failed to open file.");
}

// Open a binary file for writing
let binFile = IO.open("image.bin", "wb");
if (binFile) {
    let data = "binary data";
    let bytesWritten = binFile.write(data);
    puts("Wrote " + bytesWritten + " bytes to binary file.");
    binFile.close();
} else {
    puts("Failed to open binary file.");
}

Summary

  • Global Object: The API is accessed via the IO object.

  • File Ghost Object: Methods like read, readln, write, writeln, eof, and close are available directly on the object returned by IO.open.

  • Mode Options: Various text and binary modes allow you to control file access precisely.

This documentation should help you integrate file I/O in your POCA projects using a simple, dynamic approach.

JSON

Overview

The POCA JSON API provides functions for parsing JSON strings into POCA values and serializing POCA values into JSON strings. The API follows the familiar JavaScript JSON interface, offering JSON.parse() and JSON.stringify() functions. JSON values are converted to their corresponding POCA types: objects become hashes, arrays remain arrays, strings remain strings, numbers remain numbers, booleans are represented as numbers (0 or 1), and null remains null.


Global JSON Object

The global JSON object serves as a namespace for JSON operations. It provides functions to parse JSON strings and serialize POCA values.


JSON.parse

Usage:

let obj = JSON.parse(jsonString);
  • Description: Parses a JSON string and converts it to a POCA value. The function uses an iterative stack-based algorithm to handle deeply nested JSON structures without recursion limits. JSON types are mapped to POCA types as follows:

    • JSON objects → POCA hashes

    • JSON arrays → POCA arrays

    • JSON strings → POCA strings

    • JSON numbers → POCA numbers

    • JSON booleans → POCA numbers (0 for false, 1 for true)

    • JSON null → POCA null

  • Parameters:

    • jsonString (string): A valid JSON string to parse.

  • Return Value: A POCA value representing the parsed JSON. Returns null if the argument is missing or parsing fails.

  • Errors: Raises a runtime error if the JSON syntax is invalid, including the position of the error in the string.

  • Example:

    // Parse a simple JSON object
    let obj = JSON.parse('{"name": "John", "age": 30, "active": true}');
    puts("Name: " ~ obj.name);
    puts("Age: " ~ obj.age);
    puts("Active: " ~ obj.active); // Will be 1 (true)
    
    // Parse a JSON array
    let arr = JSON.parse('[1, 2, 3, 4, 5]');
    puts("First element: " ~ arr[0]);
    puts("Array length: " ~ arr.length);
    
    // Parse nested structures
    let data = JSON.parse('{"users": [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]}');
    puts("First user: " ~ data.users[0].name);
    
    // Handle null
    let value = JSON.parse('null');
    if (value === null) {
        puts("Value is null");
    }

JSON.stringify

Usage:

let jsonString = JSON.stringify(value);
  • Description: Converts a POCA value to a JSON string representation. The function uses an iterative stack-based algorithm to handle deeply nested structures efficiently. POCA types are mapped to JSON as follows:

    • POCA null → JSON null

    • POCA numbers → JSON numbers

    • POCA strings → JSON strings (properly escaped)

    • POCA hashes → JSON objects (with string keys)

    • POCA arrays → JSON arrays

    • Other types → JSON null

      Note: POCA does not have a separate boolean type; numbers are used. Values are serialized as JSON numbers.

  • Parameters:

    • value (any): The POCA value to serialize to JSON.

  • Return Value: A string containing the JSON representation of the value. Returns null if no argument is provided.

  • Errors: Raises a runtime error if serialization fails.

  • Example:

    // Stringify a hash (object)
    let obj = {name: "John", age: 30, active: 1};
    let json = JSON.stringify(obj);
    puts(json); // Outputs: {"name":"John","age":30,"active":1}
    
    // Stringify an array
    let arr = [1, 2, 3, 4, 5];
    json = JSON.stringify(arr);
    puts(json); // Outputs: [1,2,3,4,5]
    
    // Stringify nested structures
    let data = {
        users: [
            {id: 1, name: "Alice"},
            {id: 2, name: "Bob"}
        ],
        total: 2
    };
    json = JSON.stringify(data);
    puts(json); // Outputs: {"users":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}],"total":2}
    
    // Stringify primitive values
    puts(JSON.stringify(42));      // Outputs: 42
    puts(JSON.stringify("hello")); // Outputs: "hello"
    puts(JSON.stringify(null));    // Outputs: null

Implementation Notes

  • Stack-Based Algorithm: Both JSON.parse() and JSON.stringify() use iterative stack-based implementations rather than recursion. This allows them to handle arbitrarily deep nesting without hitting call stack limits, making them suitable for processing deeply nested JSON structures.

  • Memory Management: All created POCA values (strings, arrays, hashes) are automatically managed by POCA’s garbage collector. The JSON parsing and serialization processes properly integrate with the GC to ensure memory safety.

  • Type Conversions:

    • When parsing JSON booleans, they are converted to POCA numbers (0 or 1) since POCA uses numbers for boolean values.

    • When stringifying POCA values, all numbers are serialized as JSON numbers (not booleans), maintaining consistency with POCA’s type system.

    • Hash keys are always converted to strings when stringifying to JSON objects.

  • Error Handling: Parse errors include position information to help identify the location of syntax errors in the JSON string. Stringify errors are reported with descriptive messages.


Round-Trip Example

// Create a POCA data structure
let original = {
    name: "Alice",
    scores: [95, 87, 92],
    metadata: {
        timestamp: 1234567890,
        active: 1
    }
};

// Serialize to JSON
let jsonStr = JSON.stringify(original);
puts("JSON: " ~ jsonStr);

// Parse back to POCA
let restored = JSON.parse(jsonStr);

// Access the restored data
puts("Name: " ~ restored.name);
puts("First score: " ~ restored.scores[0]);
puts("Timestamp: " ~ restored.metadata.timestamp);
puts("Active: " ~ restored.metadata.active);

Summary

  • Global Object: The JSON object provides a namespace for JSON operations with two main functions:

    • parse: Converts JSON strings to POCA values

    • stringify: Converts POCA values to JSON strings

  • Type Mapping:

    • JSON objects ↔ POCA hashes

    • JSON arrays ↔ POCA arrays

    • JSON strings ↔ POCA strings

    • JSON numbers ↔ POCA numbers

    • JSON booleans → POCA numbers (parsing only)

    • JSON null ↔ POCA null

  • Performance: Both functions use iterative stack-based algorithms that can handle deeply nested structures efficiently without recursion limits.

  • Usage: This API enables seamless JSON integration in POCA scripts, supporting data interchange with external systems, configuration files, and web APIs using the familiar JavaScript JSON interface.

Lock

Overview

The POCA Lock API provides mutual exclusion mechanisms for synchronizing access to shared resources in concurrent POCA scripts. Locks in POCA are dynamic, typeless ghost objects created via a factory function. These ghost objects offer methods to acquire and release the lock, ensuring that only one execution context can access a critical section at a time.


Global Lock Object

The global Lock object serves as both a factory and a namespace for lock operations. You can create lock ghost objects using either of the following variants:

Lock.create(), or new Lock()

Usage:

let lock = Lock.create();

or equivalently,

let lock = new Lock();
  • Description: Lock.create() or new Lock() creates a new lock ghost object by invoking the underlying lock creation routine. The resulting ghost object represents a mutual exclusion lock, which is registered for subsequent lock operations.

  • Parameters: None.

  • Return Value: A lock ghost object that can be used to control access to shared resources.

  • Example:

    // Create a new lock using either syntax.
    let lock1 = Lock.create();
    let lock2 = new Lock();

Methods on Lock Ghost Objects

Once created, a lock ghost object provides the following methods:

Lock.enter

Usage:

lock.enter();
  • Description: Acquires the lock. The garbage collector is unlocked while the lock is being acquired to prevent deadlocks. This method returns a numeric value (1) to indicate that the lock has been successfully acquired.

  • Parameters: None.

  • Return Value: A numeric boolean value: 1 if the lock was acquired successfully, 0 otherwise.

  • Example:

    if (lock.enter()) {
      // Critical section: safely access shared resources.
    }

Lock.leave

Usage:

lock.leave();
  • Description: Releases the lock, allowing other execution contexts to acquire it.

  • Parameters: None.

  • Return Value: A null value.

  • Example:

    // Release the lock after finishing the critical section.
    lock.leave();

Summary

  • Global Object: The Lock object acts as a factory for creating lock ghost objects. Lock.create() or new Lock() creates a new lock ghost object by invoking the underlying lock creation routine. The resulting ghost object represents a mutual exclusion lock, which is registered for subsequent lock operations.

  • Lock Ghost Object Methods: Once created, lock ghost objects provide the following methods to control mutual exclusion:

    • enter: Acquires the lock.

    • leave: Releases the lock.

  • Usage: Locks enable you to synchronize access to shared resources in concurrent POCA scripts, ensuring that only one execution context can access a critical section at a time.

This comprehensive API lets you incorporate locking mechanisms into your POCA projects, providing essential synchronization for concurrent execution.

Math

Overview

The POCA Math API provides a set of mathematical constants and functions for numerical calculations in POCA scripts. These include basic arithmetic functions, trigonometric functions, hyperbolic functions, exponentiation, logarithms, and checks for numeric properties (e.g., whether a number is finite or NaN). The global Math object acts as a namespace for these constants and functions, making them readily accessible in your scripts. All trigonometric and hyperbolic functions in this API use radians.


Global Math Object

The global Math object houses numerical constants (such as Math.PI and Math.E) and a collection of native functions for mathematical operations.


Math Constants

Below is a list of each constant on Math, each in its own section:

Math.PI

  • Description: The mathematical constant π, approximately 3.141592653589793.

Math.E

  • Description: The base of natural logarithms, e, approximately 2.718281828459045.

Math.LN2

  • Description: The natural logarithm of 2, i.e., ln(2).

Math.LN10

  • Description: The natural logarithm of 10, i.e., ln(10).

Math.LOG10E

  • Description: The base-10 logarithm of e, i.e., log10(e).

Math.LOG2E

  • Description: The base-2 logarithm of e, i.e., log2(e).

Math.SQRT1_2

  • Description: The square root of 1/2.

Math.SQRT2

  • Description: The square root of 2.

Math.NaN

  • Description: Represents “Not-a-Number.”

Math.Infinity

  • Description: A positive infinite value.


Math Functions

Below is a complete list of Math functions. For each function, the usage, description, parameters, return value, and an example are included to ensure no details are lost.

Math.min

Usage:

let value = Math.min(a, b);
  • Description: Returns the smaller of the two numeric values a and b.

  • Parameters:

    • a (number): The first value.

    • b (number): The second value.

  • Return Value: The smaller of a and b.

  • Example:

    let x = Math.min(10, 3); // 3

Math.max

Usage:

let value = Math.max(a, b);
  • Description: Returns the larger of the two numeric values a and b.

  • Parameters:

    • a (number): The first value.

    • b (number): The second value.

  • Return Value: The larger of a and b.

  • Example:

    let x = Math.max(10, 3); // 10

Math.clamp

Usage:

let value = Math.clamp(num, minVal, maxVal);
  • Description: Clamps num so that it is not less than minVal and not greater than maxVal.

  • Parameters:

    • num (number): The value to clamp.

    • minVal (number): The lower bound.

    • maxVal (number): The upper bound.

  • Return Value: The clamped value.

  • Example:

    let c = Math.clamp(5, 0, 3); // 3

Math.abs

Usage:

let value = Math.abs(x);
  • Description: Returns the absolute value of x.

  • Parameters:

    • x (number): The input value.

  • Return Value: The absolute value of x.

  • Example:

    let v = Math.abs(-10); // 10

Math.sin

Usage:

let value = Math.sin(angle);
  • Description: Returns the sine of angle, where angle is in radians.

  • Parameters:

    • angle (number): The angle in radians.

  • Return Value: The sine of the given angle.

  • Example:

    let s = Math.sin(Math.PI / 2); // 1

Math.cos

Usage:

let value = Math.cos(angle);
  • Description: Returns the cosine of angle, where angle is in radians.

  • Parameters:

    • angle (number): The angle in radians.

  • Return Value: The cosine of the given angle.

  • Example:

    let c = Math.cos(Math.PI); // -1

Math.tan

Usage:

let value = Math.tan(angle);
  • Description: Returns the tangent of angle, where angle is in radians.

  • Parameters:

    • angle (number): The angle in radians.

  • Return Value: The tangent of the given angle.

  • Example:

    let t = Math.tan(Math.PI / 4); // 1

Math.exp

Usage:

let value = Math.exp(x);
  • Description: Returns e^x, where e is the base of natural logarithms.

  • Parameters:

    • x (number): The exponent.

  • Return Value: e^x.

  • Example:

    let e = Math.exp(1); // ~2.718281828

Math.ln

Usage:

let value = Math.ln(x);
  • Description: Returns the natural logarithm of x (i.e., ln(x)).

  • Parameters:

    • x (number): The input value.

  • Return Value: ln(x).

  • Example:

    let l = Math.ln(Math.E); // 1

Math.log

Usage:

let value = Math.log(x);
  • Description: An alias for Math.ln, returning the natural logarithm of x.

  • Parameters:

    • x (number): The input value.

  • Return Value: ln(x).

  • Example:

    let l2 = Math.log(Math.E); // 1

Math.sqr

Usage:

let value = Math.sqr(x);
  • Description: Returns the square of x (i.e., x*x).

  • Parameters:

    • x (number): The input value.

  • Return Value: x^2.

  • Example:

    let sq = Math.sqr(5); // 25

Math.sqrt

Usage:

let value = Math.sqrt(x);
  • Description: Returns the square root of x.

  • Parameters:

    • x (number): The input value.

  • Return Value: The square root of x.

  • Example:

    let root = Math.sqrt(25); // 5

Math.atan2

Usage:

let angle = Math.atan2(y, x);
  • Description: Returns the angle θ between the positive x-axis and the point (x, y), in radians.

  • Parameters:

    • y (number): The y-coordinate.

    • x (number): The x-coordinate.

  • Return Value: The angle in radians in the range -π to π.

  • Example:

    let a = Math.atan2(1, 1); // ~π/4

Math.acos

Usage:

let value = Math.acos(x);
  • Description: Returns the arccosine of x, in radians, in the range 0 to π.

  • Parameters:

    • x (number): The input value (should be between -1 and 1).

  • Return Value: The arccosine of x.

  • Example:

    let a = Math.acos(1); // 0

Math.asin

Usage:

let value = Math.asin(x);
  • Description: Returns the arcsine of x, in radians, in the range -π/2 to π/2.

  • Parameters:

    • x (number): The input value (between -1 and 1).

  • Return Value: The arcsine of x.

  • Example:

    let a = Math.asin(0); // 0

Math.atan

Usage:

let value = Math.atan(x);
  • Description: Returns the arctangent of x, in radians, in the range -π/2 to π/2.

  • Parameters:

    • x (number): The input value.

  • Return Value: The arctangent of x.

  • Example:

    let a = Math.atan(1); // ~π/4

Math.cotan

Usage:

let value = Math.cotan(x);
  • Description: Returns the cotangent of x (i.e., 1 / tan(x)).

  • Parameters:

    • x (number): The angle in radians.

  • Return Value: The cotangent of x.

  • Example:

    let ct = Math.cotan(Math.PI / 4); // 1

Math.secant

Usage:

let value = Math.secant(x);
  • Description: Returns the secant of x (i.e., 1 / cos(x)).

  • Parameters:

    • x (number): The angle in radians.

  • Return Value: The secant of x.

  • Example:

    let sc = Math.secant(0); // 1

Math.cosecant

Usage:

let value = Math.cosecant(x);
  • Description: Returns the cosecant of x (i.e., 1 / sin(x)).

  • Parameters:

    • x (number): The angle in radians.

  • Return Value: The cosecant of x.

  • Example:

    let co = Math.cosecant(Math.PI / 2); // 1

Math.hypot

Usage:

let value = Math.hypot(a, b);
  • Description: Returns the square root of (a^2 + b^2), typically used for computing the length of the hypotenuse in a right-angled triangle.

  • Parameters:

    • a (number): First coordinate.

    • b (number): Second coordinate.

  • Return Value: The hypotenuse length.

  • Example:

    let h = Math.hypot(3, 4); // 5

Math.ceil

Usage:

let value = Math.ceil(x);
  • Description: Returns x rounded upward to the nearest integer.

  • Parameters:

    • x (number): The number to round.

  • Return Value: The smallest integer greater than or equal to x.

  • Example:

    let c = Math.ceil(1.2); // 2

Math.floor

Usage:

let value = Math.floor(x);
  • Description: Returns x rounded downward to the nearest integer.

  • Parameters:

    • x (number): The number to round.

  • Return Value: The largest integer less than or equal to x.

  • Example:

    let f = Math.floor(1.8); // 1

Math.log10

Usage:

let value = Math.log10(x);
  • Description: Returns the base-10 logarithm of x.

  • Parameters:

    • x (number): The input value.

  • Return Value: The base-10 logarithm of x.

  • Example:

    let l10 = Math.log10(100); // 2

Math.log2

Usage:

let value = Math.log2(x);
  • Description: Returns the base-2 logarithm of x.

  • Parameters:

    • x (number): The input value.

  • Return Value: The base-2 logarithm of x.

  • Example:

    let l2 = Math.log2(8); // 3

Math.logn

Usage:

let value = Math.logn(base, x);
  • Description: Returns the base-base logarithm of x.

  • Parameters:

    • base (number): The logarithm base.

    • x (number): The input value.

  • Return Value: The base-base logarithm of x.

  • Example:

    let ln = Math.logn(5, 25); // 2

Math.pow

Usage:

let value = Math.pow(x, y);
  • Description: Raises x to the power y (i.e., x^y).

  • Parameters:

    • x (number): The base.

    • y (number): The exponent.

  • Return Value: x^y.

  • Example:

    let p = Math.pow(2, 5); // 32

Math.sinh

Usage:

let value = Math.sinh(x);
  • Description: Returns the hyperbolic sine of x.

  • Parameters:

    • x (number): The input value in radians.

  • Return Value: The hyperbolic sine of x.

  • Example:

    let sh = Math.sinh(0); // 0

Math.cosh

Usage:

let value = Math.cosh(x);
  • Description: Returns the hyperbolic cosine of x.

  • Parameters:

    • x (number): The input value in radians.

  • Return Value: The hyperbolic cosine of x.

  • Example:

    let ch = Math.cosh(0); // 1

Math.tanh

Usage:

let value = Math.tanh(x);
  • Description: Returns the hyperbolic tangent of x.

  • Parameters:

    • x (number): The input value in radians.

  • Return Value: The hyperbolic tangent of x.

  • Example:

    let th = Math.tanh(1); // ~0.76159

Math.asinh

Usage:

let value = Math.asinh(x);
  • Description: Returns the inverse hyperbolic sine of x.

  • Parameters:

    • x (number): The input value.

  • Return Value: The inverse hyperbolic sine of x.

  • Example:

    let ash = Math.asinh(0); // 0

Math.acosh

Usage:

let value = Math.acosh(x);
  • Description: Returns the inverse hyperbolic cosine of x (where x ≥ 1).

  • Parameters:

    • x (number): The input value (≥ 1).

  • Return Value: The inverse hyperbolic cosine of x.

  • Example:

    let ach = Math.acosh(1); // 0

Math.atanh

Usage:

let value = Math.atanh(x);
  • Description: Returns the inverse hyperbolic tangent of x (typically between -1 and 1).

  • Parameters:

    • x (number): The input value. Typically a value between -1 and 1.

  • Return Value: The inverse hyperbolic tangent of x.

  • Example:

    let ath = Math.atanh(0); // 0

Math.coth

Usage:

let value = Math.coth(x);
  • Description: Returns the hyperbolic cotangent of x (i.e., 1 / tanh(x)).

  • Parameters:

    • x (number): The input value in radians.

  • Return Value: The hyperbolic cotangent of x.

  • Example:

    let cth = Math.coth(1); // ~1.313035

Math.sech

Usage:

let value = Math.sech(x);
  • Description: Returns the hyperbolic secant of x (i.e., 1 / cosh(x)).

  • Parameters:

    • x (number): The input value in radians.

  • Return Value: The hyperbolic secant of x.

  • Example:

    let sch = Math.sech(0); // 1

Math.csch

Usage:

let value = Math.csch(x);
  • Description: Returns the hyperbolic cosecant of x (i.e., 1 / sinh(x)).

  • Parameters:

    • x (number): The input value in radians.

  • Return Value: The hyperbolic cosecant of x.

  • Example:

    let csh = Math.csch(1); // ~0.850918

Math.acot

Usage:

let value = Math.acot(x);
  • Description: Returns the inverse cotangent of x, typically computed as arctan(1/x).

  • Parameters:

    • x (number): The input value.

  • Return Value: The inverse cotangent of x.

  • Example:

    let ac = Math.acot(1); // ~π/4

Math.asec

Usage:

let value = Math.asec(x);
  • Description: Returns the inverse secant of x, typically computed as arccos(1/x).

  • Parameters:

    • x (number): The input value.

  • Return Value: The inverse secant of x.

  • Example:

    let as = Math.asec(1); // 0

Math.acsc

Usage:

let value = Math.acsc(x);
  • Description: Returns the inverse cosecant of x, typically computed as arcsin(1/x).

  • Parameters:

    • x (number): The input value.

  • Return Value: The inverse cosecant of x.

  • Example:

    let aC = Math.acsc(1); // π/2

Math.acoth

Usage:

let value = Math.acoth(x);
  • Description: Returns the inverse hyperbolic cotangent of x.

  • Parameters:

    • x (number): The input value.

  • Return Value: The inverse hyperbolic cotangent of x.

  • Example:

    let ac = Math.acoth(2);
    // Returns a valid double; no simple numeric example here.

Math.asech

Usage:

let value = Math.asech(x);
  • Description: Returns the inverse hyperbolic secant of x (0 < x ≤ 1).

  • Parameters:

    • x (number): The input value.

  • Return Value: The inverse hyperbolic secant of x.

  • Example:

    let as = Math.asech(1); // 0

Math.acsch

Usage:

let value = Math.acsch(x);
  • Description: Returns the inverse hyperbolic cosecant of x.

  • Parameters:

    • x (number): The input value.

  • Return Value: The inverse hyperbolic cosecant of x.

  • Example:

    let acs = Math.acsch(2);
    // No simple numeric result example here, but it returns a valid double.

Math.round

Usage:

let value = Math.round(x);
  • Description: Rounds x to the nearest integer. If the fractional portion is 0.5 or greater, rounds up; otherwise, rounds down.

  • Parameters:

    • x (number): The input value.

  • Return Value: The rounded integer.

  • Example:

    let r = Math.round(2.5); // 3

Math.trunc

Usage:

let value = Math.trunc(x);
  • Description: Truncates x to an integer by removing any fractional digits (toward zero).

  • Parameters:

    • x (number): The input value.

  • Return Value: The integer part of x.

  • Example:

    let t = Math.trunc(2.9); // 2

Math.int

Usage:

let value = Math.int(x);
  • Description: Similar to Math.trunc(x), returns the integer part of x, discarding any fractional component.

  • Parameters:

    • x (number): The input value.

  • Return Value: The integer part of x.

  • Example:

    let i = Math.int(-3.8); // -3

Math.random

Usage:

let value = Math.random();
  • Description: Returns a random floating-point number between 0 (inclusive) and 1 (exclusive).

  • Parameters: None.

  • Return Value: A random number in the range [0, 1).

  • Example:

    let rand = Math.random(); // e.g., 0.714

Math.isNaN

Usage:

let value = Math.isNaN(x);
  • Description: Checks whether x is Not-a-Number (NaN).

  • Parameters:

    • x (number): The value to test.

  • Return Value: A numeric boolean value: 1 if x is NaN, 0 otherwise.

  • Example:

    let check = Math.isNaN(0 / 0); // 1

Math.isInfinite

Usage:

let value = Math.isInfinite(x);
  • Description: Checks whether x is infinite (positive or negative infinity).

  • Parameters:

    • x (number): The value to test.

  • Return Value: A numeric boolean value: 1 if x is infinite, 0 otherwise.

  • Example:

    let inf = Math.isInfinite(Math.Infinity); // 1

Math.isFinite

Usage:

let value = Math.isFinite(x);
  • Description: Checks whether x is a finite number.

  • Parameters:

    • x (number): The value to test.

  • Return Value: A numeric boolean value: 1 if x is finite, 0 otherwise.

  • Example:

    let fin = Math.isFinite(10 / 2); // 1

Math.frac

Usage:

let value = Math.frac(x);
  • Description: Returns the fractional part of x (i.e., x - floor(x) if x is positive, or x - ceil(x) if x is negative).

  • Parameters:

    • x (number): The input value.

  • Return Value: The fractional part of x.

  • Example:

    let fractional = Math.frac(2.75); // 0.75

Math.fract

Usage:

let value = Math.fract(x);
  • Description: Returns the fractional part of x (i.e., x - floor(x) if x is positive, or x - ceil(x) if x is negative). This is an alias for Math.frac for compatibility with other languages, which use fract as the function name.

  • Parameters:

    • x (number): The input value.

  • Return Value: The fractional part of x.

  • Example:

    let fractional = Math.fract(2.75); // 0.75

Summary

  • Global Object: The Math object serves as a namespace for mathematical constants (like Math.PI, Math.E, Math.NaN, Math.Infinity) and a wide array of numeric functions.

  • Math API Functions: It includes functions for:

    • Basic numeric comparisons: Math.min, Math.max, Math.clamp.

    • Trigonometric/hyperbolic operations: Math.sin, Math.cosh, Math.atanh, etc.

    • Exponentiation, logarithms, and rounding: Math.pow, Math.log10, Math.floor, Math.round.

    • Random number generation: Math.random.

    • Infinity checks: Math.isInfinite, Math.isFinite, Math.isNaN, and more.

  • Usage: This comprehensive set of constants and functions allows you to perform advanced math operations in a dynamic, typeless environment. From computing trigonometric functions to verifying numeric ranges, the POCA Math API provides a robust toolset for numeric computations in POCA scripts.

  • Note: All trigonometric and hyperbolic functions in this API use radians.

ModuleManager

Overview

The POCA ModuleManager API provides a mechanism for dynamically loading, unloading, and reloading modules within POCA scripts. A “module” is simply a POCA script file (or code string) that can export symbols (variables, functions, etc.) for use in other scripts. Once a module is loaded, its exports and scope are cached, so subsequent imports or requires can reuse them. This system supports both a JavaScript-like import approach – which can selectively import symbols or import everything using import * from ... – and a Lua-style require concept – which returns whatever object the module exports or returns.

Modules are tracked internally by three global hashes:

  • moduleScopes: Stores the top-level scope (hash) of each loaded module.

  • moduleValues: Stores the exported object returned by the module (relevant for require).

  • moduleTimes: Stores a timestamp indicating when the module was last loaded (used for conditional reloads).

The POCA engine also provides “module loader functions” that know how to locate module files, load them, and return their code. When a module is loaded, its code is compiled and executed in a sub-context. The result is cached to avoid redundant work, though you can opt to force reload if the underlying file changed.


Global ModuleManager Object

The global ModuleManager object is a namespace for module operations. It stores references to the internal module registries and provides functions to load, remove, or check modules. Additionally, the core module-related functions (import and require) appear in both the global namespace and the ModuleManager object.

ModuleManager Properties

  • moduleScopes: A hash of module names to their scope objects.

  • moduleValues: A hash of module names to their exported objects or return values.

  • moduleTimes: A hash of module names to numeric timestamps of last load.


Global Module Functions

POCA provides two primary ways to load modules:

  1. import

  2. require

Although they differ in style, both retrieve (and possibly reload) the target module, storing or returning relevant objects.

ModuleManager.import

Usage:

import * from "MyModule";
import a, b from "MyOtherModule";
// or:
ModuleManager.import("MyModule", ["a", "b"]);
  • Description:

    • If called via language syntax (import a, b from "MyOtherModule"), it pulls the named exports into the current scope.

    • If called as a function (ModuleManager.import("name", importsArray[, reloadFlag])), it can import specific symbols or * from the module’s exported object (or scope).

    • The underlying logic checks whether the module is already loaded. If reloadFlag is true, the system checks if the file changed and may reload it.

    • The module can define its exported symbols in two ways:

      1. exports a, b, c; at the end (ECMAScript-like).

      2. return { a, b, c }; at the end (Lua-style require approach).

    • If an array of imports is specified, only those symbols are pulled into the local scope. If you specify ["*"] (or ["all"]), everything from the module is imported.

  • Parameters:

    • moduleName (string): The name (or path) of the module.

    • imports (array, optional): An array of symbols to import (e.g., ["symbol1", "symbol2"], or ["*"]).

    • allowReloadIfNewer (boolean, optional): If true, the system checks timestamps to see if the module changed on disk and reloads if it’s newer.

  • Return Value:

    • If used with the language syntax import ... from ...;, it doesn’t directly return a value.

    • If called as import(moduleName, imports, allowReloadIfNewer), it returns the module’s exported hash or the scope that was imported.

  • Example:

    import * from "MathLib";    // Imports all exported symbols from MathLib
    import sin, cos from "Trig"; // Imports only 'sin' and 'cos'
    
    // As a function call:
    ModuleManager.import("StringUtils", ["trim", "toUpperCase"], true);

ModuleManager.require

Usage:

let moduleObj = require("MyModule");

or

let moduleObj = ModuleManager.require("MyModule", allowReloadIfNewer);
  • Description:

    • require loads the specified module, returning whatever the module “returns”.

    • If the module is already cached, require uses the cached result unless allowReloadIfNewer is true and the module file has changed.

    • In the file, you can define:

      return {
        a: 123,
        b: function() { ... }
      };

      This object is returned by require.

  • Parameters:

    • moduleName (string): The name (or path) of the module.

    • allowReloadIfNewer (boolean, optional): If true, the system checks timestamps and reloads the module if it has changed.

  • Return Value: The module’s exported object, as determined by the final return statement or exports usage.

  • Example:

    let myModule = require("MyModule");
    if (myModule) {
      // Use the returned object
    }
    
    // Using ModuleManager form:
    let other = ModuleManager.require("OtherModule", true);

ModuleManager Functions

The ModuleManager object also provides the following additional utility functions:

ModuleManager.loaded

Usage:

let isLoaded = ModuleManager.loaded("MyModule");
  • Description: Checks whether the specified module is already loaded. If the module’s scope, value, and timestamp are present in the internal registries, it is considered loaded.

  • Parameters:

    • moduleName (string): The name (or path) of the module.

  • Return Value:

    • A numeric boolean (1 or 0), indicating whether the module is loaded.


ModuleManager.remove

Usage:

let removed = ModuleManager.remove("MyModule");
  • Description: Unloads (removes) the specified module from the internal caches. This allows a fresh load on subsequent import or require calls. If the module is currently not loaded, the function does nothing.

  • Parameters:

    • moduleName (string): The name (or path) of the module.

  • Return Value:

    • A numeric boolean (1 or 0): 1 if a loaded module was removed, 0 if the module was not found/loaded.


ModuleManager.getModuleFileTime

Usage:

let modTime = ModuleManager.getModuleFileTime("MyModule");
  • Description: Attempts to locate and load the module file via the registered module loader functions (without actually compiling or executing it), then returns the file’s timestamp. If the module is not found, an error is raised.

  • Parameters:

    • moduleName (string): The name (or path) of the module to check.

  • Return Value:

    • A numeric value representing the module file’s date/time stamp.

    • If no module loader can find the file, it raises an error.


Summary

  • Global & ModuleManager Usage: The functions import and require appear both in the global namespace and under ModuleManager. You can call them directly, as in import a, b from "SomeModule";, or via ModuleManager.import("SomeModule", [...]). The remove, loaded, and getModuleFileTime utilities are only in ModuleManager.

  • Workflow:

    1. POCA uses module loader functions to locate and read module source code.

    2. The source code is compiled in a sub-context.

    3. The module can define its exported API either via an exports hash (ECMAScript-like) or via a final return object (Lua-like).

    4. import selectively brings symbols into the local scope, while require returns the exported object.

    5. The loaded module’s scope, value, and timestamp are cached in three global hashes.

    6. Optional reloading logic checks timestamps if requested.

  • Usage: This comprehensive API lets you create modular POCA codebases. You can share or isolate functionality across multiple script files and decide whether to adopt ECMAScript-like or Lua-like styles for exporting symbols. The ModuleManager object and the global import/require calls provide powerful ways to structure and reuse code in a dynamic, typeless environment.

  • Note: The import and require functions should not be used in the POCA REPL (Read-Eval-Print Loop) environment, as they are not designed for interactive use. They are intended for use in script files or modules where you can define and manage dependencies and imports in a structured manner.

Number

Overview

The POCA Number API provides methods for converting number literals into string representations with various formatting options. These methods are available on Number literals and allow you to represent numbers in standard, exponential, fixed, precision, and different radix formats.


Global Number Object

The global Number object provides a set of native functions that operate on number literals. These functions are registered in the Number hash and can be invoked directly on any number literal.

Number.create

Usage:

let num = Number.create(value, radix);

or equivalently,

let num = new Number(value, radix);

or

let num = 123.456;
  • Description: Number.create() or new Number() creates a new number by invoking the underlying number creation routine. The resulting value represents a number literal, which is registered for subsequent number operations. The new Number() syntax is equivalent to Number.create().

  • Parameters:

    • value (number): The numeric value to be created, or a string representation of a number, which can be in decimal, hexadecimal (prefixed with 0x), octal (prefixed with 0o) or binary (prefixed with 0b) format or any other valid number string.

    • radix (number, optional): The base for numeral system (2 for binary, 8 for octal, 10 for decimal, 16 for hexadecimal), default is 10.

  • Return Value: A number literal representing the specified value.

  • Example:

    // Create a number using the factory function.
    let num1 = Number.create(123.456);
    let num2 = new Number(123.456); // Equivalent to Number.create()
    let num3 = 123.456; // Using literal syntax
    let num4 = Number.create("123.456", 10); // String to number conversion
    let num5 = new Number("ff", 16); // Hexadecimal to number
    let num6 = Number.create("100", 2); // Binary to number
    let num7 = new Number("0xff"); // Hexadecimal to number
    let num8 = Number.create("0b1010"); // Binary to number
    let num7 = Number.create("0xff.8"); // Floating-point hex to number
    let num8 = new Number("0b1010.1"); // Floating-point binary to number
  • Note: The new Number() syntax is equivalent to Number.create()

Number Instance

Number.toString

Usage:

let str = (123.456).toString();
  • Description: Returns the string representation of the number.

  • Parameters: None.

  • Return Value: A string representing the number.

  • Example:

    let str = (123.456).toString();
    puts(str); // "123.456"

Number.toExponential

Usage:

let expStr = (123.456).toExponential(3);
  • Description: Converts the number to its exponential notation. The argument specifies the number of digits after the decimal point.

  • Parameters:

    • precision (number): The number of digits after the decimal point plus. If it is -1, then the full representation is used.

  • Return Value: A string representing the number in exponential notation.

  • Example:

    let expStr = (123.456).toExponential(2);
    puts(expStr); // e.g., "1.23e+2"

Number.toFixed

Usage:

let fixedStr = (123.456).toFixed(2);
  • Description: Returns a string representation of the number in fixed-point notation. The argument specifies the number of decimal places.

  • Parameters:

    • decimalPlaces (number): The number of digits after the decimal point.

  • Return Value: A string representing the number in fixed-point format.

  • Example:

    let fixedStr = (123.456).toFixed(2);
    puts(fixedStr); // "123.46"

Number.toPrecision

Usage:

let precStr = (123.456).toPrecision(5);
  • Description: Returns a string representation of the number with the specified number of significant digits.

  • Parameters:

    • precision (number): The total number of significant digits.

  • Return Value: A string representing the number with the given precision.

  • Example:

    let precStr = (123.456).toPrecision(5);
    puts(precStr); // "123.46" (format may vary)

Number.toRadix

Usage:

let radixStr = (255).toRadix(16);
  • Description: Converts the number to a string in the numeral system of the specified radix. The argument determines the radix (base) to use for conversion.

  • Parameters:

    • radix (number): The base for the numeral system (e.g., 2 for binary, 16 for hexadecimal).

  • Return Value: A string representing the number in the specified radix.

  • Example:

    let radixStr = (255).toRadix(16);
    puts(radixStr); // "ff"

Summary

  • Global Object: The Number object provides methods that operate on number literals. These methods convert numbers into various string representations.

  • Number Methods:

    • toString: Returns the standard string representation of a number.

    • toExponential: Converts a number into exponential notation with a specified precision.

    • toFixed: Formats a number using fixed-point notation.

    • toPrecision: Formats a number with a specified number of significant digits.

    • toRadix: Converts a number to a string in a specified numeral system.

  • Usage: This comprehensive API lets you format number literals in POCA with flexibility similar to JavaScript, providing robust options for numeric string representation in a dynamic, typeless environment.

Path

Overview

The POCA Path API provides a variety of functions for manipulating file system paths. These functions allow you to extract directories, file names, file extensions, and perform path transformations (such as converting to relative or absolute paths), split or join path components, and perform file system operations (like creating directories, checking file existence, and copying or moving files). This API works with both Windows and Unix-style paths.


Path.dir

Usage:

let directory = Path.dir(path);
  • Parameters:

    • path (string): The full file path.

  • Description: Returns the directory portion of a path, excluding the file name and any trailing delimiter.

  • Return Value: A new string containing the directory portion.

  • Example:

let dir = Path.dir("/folder/file.txt");
// Returns "/folder"

Path.fileName

Usage:

let name = Path.fileName(path);
  • Parameters:

    • path (string): The full file path.

  • Description: Extracts and returns the file name from the given path.

  • Return Value: A new string containing the file name.

  • Example:

let fileName = Path.fileName("/folder/file.txt");
// Returns "file.txt"

Path.fileExtension

Usage:

let ext = Path.fileExtension(path);
  • Parameters:

    • path (string): The full file path.

  • Description: Returns the file extension from the given path.

  • Return Value: A new string with the file extension.

  • Example:

let extension = Path.fileExtension("/folder/file.txt");
// Returns ".txt"

Path.currentScriptFile

Usage:

let currentScript = Path.currentScriptFile(absolute);
  • Parameters:

    • absolute (boolean, optional):

      • true: Return an absolute file path.

      • false (or omitted): Return a relative file path.

  • Description: Returns the current script file name. The boolean flag determines whether the returned path is absolute or relative.

  • Return Value: A new string representing the current script file name.

  • Example:

let scriptPath = Path.currentScriptFile(true);
// Returns the absolute path of the current script file (e.g., "/home/user/project/script.poca")

Path.relative

Usage:

let relativePath = Path.relative(targetPath, basePath);
  • Parameters:

    • targetPath (string): The path to be converted.

    • basePath (string, optional): The base path to compare against (default is empty string).

  • Description: Converts a given path to a relative path based on an optional base path.

  • Return Value: A new string containing the relative path.

  • Example:

let relPath = Path.relative("/folder/subfolder/file.txt", "/folder");
// Returns "subfolder/file.txt"

Path.absolute

Usage:

let absolutePath = Path.absolute(relativePath, basePath);
  • Parameters:

    • relativePath (string): The relative path.

    • basePath (string, optional): The base path to expand from (default is empty string).

  • Description: Converts a relative path to an absolute path using an optional base path.

  • Return Value: A new string with the absolute path.

  • Example:

let absPath = Path.absolute("subfolder/file.txt", "/folder");
// Returns "/folder/subfolder/file.txt"

Path.split

Usage:

let parts = Path.split(path);
  • Parameters:

    • path (string): The file path to split.

  • Description: Splits a path string into its component parts, removing any empty segments.

  • Return Value: An array of strings representing each part of the path.

  • Example:

let segments = Path.split("/folder/subfolder/file.txt");
// Returns ["/", "folder", "subfolder", "file.txt"]

Path.join

Usage:

let fullPath = Path.join(pathList);
  • Parameters:

    • pathList (array): An array of path segments.

  • Description: Joins an array of path segments into a single path string, using the platform-specific delimiter.

  • Return Value: A new string with the combined path.

  • Example:

let pathJoined = Path.join(["/", "folder", "file.txt"]);
// Returns "/folder/file.txt"

Path.isAbsolute

Usage:

let isAbs = Path.isAbsolute(path);
  • Parameters:

    • path (string): The file path to check.

  • Description: Checks whether a given path is absolute.

  • Return Value: A numeric boolean: 1 if the path is absolute, 0 otherwise.

  • Example:

let absoluteCheck = Path.isAbsolute("/folder/file.txt");
// Returns 1

Path.delimiter

Usage:

let delim = Path.delimiter();
  • Parameters: None.

  • Description: Returns the directory delimiter character for the platform (forward slash on Unix, backslash on Windows).

  • Return Value: A new string containing the delimiter.

  • Example:

let delimiter = Path.delimiter();  // Returns "/" on Unix or "\" on Windows.

Path.current

Usage:

let currDir = Path.current();
  • Parameters: None.

  • Description: Returns the current working directory.

  • Return Value: A new string with the current directory path.

  • Example:

let currentDirectory = Path.current();
// Returns, for example, "/home/user/project"

Path.getEntries

Usage:

let entries = Path.getEntries(dirPath);
  • Parameters:

    • dirPath (string): The directory path.

  • Description: Retrieves an array of directory entry names (files and subdirectories) from the specified directory.

  • Return Value: An array of strings representing the directory entries.

  • Example:

let dirEntries = Path.getEntries("/usr/local/bin");
// Returns an array of file and directory names.

Path.stat

Usage:

let stats = Path.stat(path);
  • Parameters:

    • path (string): The file or directory path.

  • Description: Retrieves a hash containing file or directory statistics. The hash includes keys such as:

    • size: File size in bytes.

    • mtime: Modification time.

    • ctime: Creation time.

    • atime: Access time.

    • type: A string indicating the type (e.g., "file" or "directory").

    • symlink: A numeric boolean (0 or 1) indicating whether the path is a symbolic link.

      Note: The time values are returned as Object Pascal TDateTime values (64-bit doubles compatible with Delphi/FreePascal), not as Unix timestamps.

  • Return Value: A hash with keys size, mtime, ctime, atime, type, and symlink.

  • Example:

let fileStats = Path.stat("/folder/file.txt");
// Returns a hash like: { size: 1024, mtime: 44500.1234, ctime: 44400.5678, atime: 44500.1234, type: "file", symlink: 0 }

Path.isDir

Usage:

let isDirectory = Path.isDir(path);
  • Parameters:

    • path (string): The path to check.

  • Description: Checks if the given path represents a directory.

  • Return Value: A numeric boolean: 1 if it is a directory, 0 otherwise.

  • Example:

let dirCheck = Path.isDir("/folder");
// Returns 1 if "/folder" is a directory.

Path.isFile

Usage:

let isFile = Path.isFile(path);
  • Parameters:

    • path (string): The path to check.

  • Description: Checks if the given path represents a file.

  • Return Value: A numeric boolean: 1 if it is a file, 0 otherwise.

  • Example:

let fileCheck = Path.isFile("/folder/file.txt");
// Returns 1 if it is a file.

Usage:

let isLink = Path.isSymLink(path);
  • Parameters:

    • path (string): The path to check.

  • Description: Checks if the given path is a symbolic link.

  • Return Value: A numeric boolean: 1 if it is a symlink, 0 otherwise.

  • Example:

let symlinkCheck = Path.isSymLink("/usr/local/bin/symlink");
// Returns 1 if it is a symbolic link.

Path.resolve

Usage:

let resolved = Path.resolve(path);
  • Parameters:

    • path (string): The path to resolve.

  • Description: Resolves the target of a symbolic link. If the given path is a symlink, returns the target path.

  • Return Value: A new string representing the resolved path.

  • Example:

let targetPath = Path.resolve("/usr/local/bin/symlink");
// Returns the target path of the symlink.

Path.mkdir

Usage:

let created = Path.mkdir(path);
  • Parameters:

    • path (string): The directory path to create.

  • Description: Creates a new directory at the specified path. If the directory already exists, nothing is done.

  • Return Value: A numeric boolean: 1 if the directory was created successfully, 0 otherwise.

  • Example:

let success = Path.mkdir("/newFolder");
// Returns 1 if created successfully.

Path.chdir

Usage:

let changed = Path.chdir(path);
  • Parameters:

    • path (string): The directory path to change to.

  • Description: Changes the current working directory to the specified path.

  • Return Value: A numeric boolean: 1 if the directory was changed successfully, 0 otherwise.

  • Example:

let changeResult = Path.chdir("/folder");
// Returns 1 on success.

Path.rmdir

Usage:

let removed = Path.rmdir(path);
  • Parameters:

    • path (string): The directory path to remove.

  • Description: Removes the specified directory if it exists.

  • Return Value: A numeric boolean: 1 if removed successfully, 0 otherwise.

  • Example:

let removalStatus = Path.rmdir("/folder");
// Returns 1 if the directory was removed.

Path.exist

Usage:

let exists = Path.exist(path);
  • Parameters:

    • path (string): The file or directory path to check.

  • Description: Checks if a file or directory exists at the specified path.

  • Return Value: A numeric boolean: 1 if it exists, 0 otherwise.

  • Example:

let existence = Path.exist("/folder/file.txt");
// Returns 1 if the path exists.

Path.remove

Usage:

let success = Path.remove(path);
  • Parameters:

    • path (string): The file path to delete.

  • Description: Deletes a file at the specified path.

  • Return Value: A numeric boolean: 1 if deletion was successful, 0 otherwise.

  • Example:

let deleteResult = Path.remove("/folder/file.txt");
// Returns 1 if deletion succeeded.

Path.copy

Usage:

let success = Path.copy(sourcePath, destinationPath);
  • Parameters:

    1. sourcePath (string): The source file path.

    2. destinationPath (string): The destination file path.

  • Description: Copies a file from the source path to the destination path.

  • Return Value: A numeric boolean: 1 if the file was copied successfully, 0 otherwise.

  • Example:

let copyResult = Path.copy("/folder/source.txt", "/folder/dest.txt");
// Returns 1 on success.

Path.move

Usage:

let success = Path.move(sourcePath, destinationPath);
  • Parameters:

    1. sourcePath (string): The source file path.

    2. destinationPath (string): The destination file path.

  • Description: Moves a file from the source path to the destination path.

  • Return Value: A numeric boolean: 1 if the move was successful, 0 otherwise.

  • Example:

let moveResult = Path.move("/folder/source.txt", "/folder/dest.txt");
// Returns 1 on success.

Path.rename

Usage:

let success = Path.rename(sourcePath, newPath);
  • Parameters:

    1. sourcePath (string): The current file path.

    2. newPath (string): The new file path.

  • Description: Renames a file from the current file path to the new file path.

  • Return Value: A numeric boolean: 1 if renaming was successful, 0 otherwise.

  • Example:

let renameResult = Path.rename("/folder/old.txt", "/folder/new.txt");
// Returns 1 if renaming succeeded.

Summary

  • Global Object: The Path object provides a comprehensive API for working with file system paths. It enables you to extract and manipulate path components, determine path properties, and perform file system operations.

  • Path API Functions:

    • Path.dir: Extracts the directory portion of a path.

    • Path.fileName: Retrieves the file name from a path.

    • Path.fileExtension: Retrieves the file extension.

    • Path.currentScriptFile: Returns the current script file name, with a boolean flag (absolute) indicating whether the path is absolute (true) or relative (false).

    • Path.relative: Converts a path to a relative form based on an optional base.

    • Path.absolute: Converts a relative path to an absolute one using an optional base.

    • Path.split: Splits a path into its component parts.

    • Path.join: Joins an array of path segments into a single path.

    • Path.isAbsolute: Checks if a path is absolute.

    • Path.delimiter: Returns the path delimiter for the platform.

    • Path.current: Returns the current working directory.

    • Path.getEntries: Returns an array of directory entries from a given directory.

    • Path.stat: Retrieves file/directory statistics in a hash.

    • Path.isDir: Checks if a path represents a directory.

    • Path.isFile: Checks if a path represents a file.

    • Path.isSymLink: Checks if a path is a symbolic link.

    • Path.resolve: Resolves a symbolic link to its target path.

    • Path.mkdir: Creates a new directory.

    • Path.chdir: Changes the current working directory.

    • Path.rmdir: Removes a directory.

    • Path.exist: Checks if a file or directory exists.

    • Path.remove: Deletes a file.

    • Path.copy: Copies a file.

    • Path.move: Moves a file.

    • Path.rename: Renames a file.

  • Usage: The POCA Path API lets you handle file system paths and perform file operations easily in your POCA scripts. Whether you need to manipulate path strings or interact with the file system (e.g., create directories, check file existence, copy or move files), this comprehensive API provides the necessary functionality in a dynamic, typeless environment.

  • Note: The Path API is designed to work with both Windows and Unix file systems, making it versatile for cross-platform development. The API handles path delimiters and file operations in a consistent way, allowing you to write scripts that can run on different operating systems without modification.

RegExp

Overview

The POCA RegExp API brings powerful pattern matching to your POCA scripts. Regular expressions in POCA are dynamic, typeless objects (ghost objects) backed by a native engine. You can create these objects either by using a global RegExp factory or by using the native literal syntax (similar to JavaScript). Once created, RegExp ghost objects expose methods for executing, testing, finding, matching, splitting, and replacing text.


Global RegExp Object

The global RegExp object serves as both a factory and a namespace for regular expression operations. It provides methods to create and manipulate regular expressions before they are used in pattern matching.

RegExp.create, RegExp.compile, and the new Operator

Usage:

let re = new RegExp("/foo(bar)?/");

or equivalently,

let re = RegExp.create("/foo(bar)?/");

or

let re = RegExp.compile("/foo(bar)?/");
  • Description: These functions compile the provided pattern into a RegExp ghost object. The function accepts a plain string (or, if given a RegExp ghost object, its source pattern is used) and compiles it after checking its UTF-8 status. The resulting ghost object is registered in the global RegExp hash so that its methods become available dynamically. In POCA, the new operator is simply an alias for RegExp.create—there is no separate constructor.

  • Parameters:

    • pattern (string): The regular expression pattern to compile.

  • Return Value: A RegExp ghost object that encapsulates the compiled pattern and supports regex operations.

  • Examples:

    // Using the new operator (alias for RegExp.create):
    let re1 = new RegExp("/foo(bar)?/");
    
    // Using RegExp.create:
    let re2 = RegExp.create("/foo(bar)?/");
    
    // Using RegExp.compile:
    let re3 = RegExp.compile("/foo(bar)?/");

RegExp.escape

Usage:

let safePattern = RegExp.escape(pattern);
  • Description: Escapes all regex metacharacters in the provided string so that it can be safely used as a literal pattern. Special characters (such as (, |, ., *, ?, ^, $, -, [, {, }, ], ), \) are prefixed with a backslash.

  • Parameters:

    • pattern (string): The input string whose special characters should be escaped.

  • Return Value: A new string with all regex metacharacters escaped.

  • Example:

    let safe = RegExp.escape("(test)*");
    puts(safe); // Outputs: \(test\)\*

Native Literal Syntax

POCA supports a native regular expression literal syntax similar to JavaScript. When you enclose a pattern between forward slashes, it is automatically compiled into a RegExp ghost object.

  • Example:

    let reLiteral = /foo(bar)?/;
    // This is equivalent to:
    let reLiteral2 = RegExp.compile("/foo(bar)?/");

Note: Both the literal syntax and the factory methods produce ghost objects that offer the same methods for regex operations.


Methods on RegExp Ghost Objects

Once you have a RegExp ghost object (for example, from RegExp.create, RegExp.compile, or literal syntax), you can use its methods to perform various regex operations on strings. A RegExp ghost object is stateless and not stateful like in JS. Each method call is independent, thread-safe, and does not modify the object’s internal state, since it is designed to be used in a object-shared way in POCA’s environment which supports Threading and Coroutines. So there is no /g or /y flags or lastIndex property.


RegExp.exec

Usage:

let result = re.exec(input, start, limit);
  • Description: Executes the regular expression on the given input string. Returns an array of capture results for each match found.

    • If the regular expression uses named groups (flagged with rfNAMED), each match is returned as a hash mapping group names to capture details.

    • Otherwise, each match is represented as an array containing:

      • The starting code point of the match.

      • The length of the match.

      • The captured substring.

  • Parameters:

    • input (string): The string to search.

    • start (number): The starting code unit in the string (defaults to 0 if not specified).

    • limit (number): The maximum number of matches to process (defaults to 1 if not specified).

  • Return Value: An array of capture results or null if no match is found.

  • Example:

    let captures = re.exec("user@example.com", 0);
    // 'captures' contains details for each capture group found in the match.

RegExp.test

Usage:

let isMatch = re.test(input, start);
  • Description: Tests whether the regular expression matches the input string starting from the given position.

  • Parameters:

    • input (string): The string to test.

    • start (number): The starting code unit (defaults to 0 if not specified).

  • Return Value: A numeric boolean value (1 for true, 0 for false).

  • Example:

    if (re.test("user@example.com", 0)) {
      puts("Email format is valid.");
    }

RegExp.find

Usage:

let position = re.find(input, start);
  • Description: Finds the first occurrence of a match in the input string starting from the specified code unit.

  • Parameters:

    • input (string): The string in which to search.

    • start (number): The starting code unit (defaults to 0 if not specified).

  • Return Value: The starting code point of the first match or a special indicator if no match is found.

  • Example:

    let pos = re.find("The quick brown fox", 0);

RegExp.match

Usage:

let matches = re.match(input, start, limit);
  • Description: Returns an array of matches for the regular expression in the input string.

    • For regexes with named groups, each match is returned as a hash mapping group names to the captured substrings.

    • Otherwise, each match is returned as an array of captured substrings.

  • Parameters:

    • input (string): The input string.

    • start (number): The starting code unit (defaults to 0 if not specified).

    • limit (number): The maximum number of matches (defaults to 1 if not specified).

  • Return Value: An array of matches or null if there are no matches.

  • Example:

    let allMatches = re.match("user@example.com", 0, 1);

RegExp.split

Usage:

let parts = re.split(input, start, limit);
  • Description: Splits the input string at each occurrence where the regular expression matches.

  • Parameters:

    • input (string): The string to split.

    • start (number): The starting code unit (defaults to 0 if not specified).

    • limit (number): The maximum number of splits (defaults to -1, meaning no limit).

  • Return Value: An array of substrings resulting from the split.

  • Example:

    let tokens = re.split("a,b,c", 0, -1);

RegExp.replace

Usage:

let resultString = re.replace(input, replacement, start, limit);
  • Description: Replaces occurrences of the regular expression in the input string with the given replacement string.

  • Parameters:

    • input (string): The string to search.

    • replacement (string): The string to replace each match.

    • start (number): The starting code unit (defaults to 0 if not specified).

    • limit (number): The maximum number of replacements (defaults to -1, meaning no limit).

  • Return Value: A new string with the replacements applied.

  • Example:

    let result = re.replace("Hello World", "Universe", 0, -1);

Summary

  • Global Object: The RegExp object is both a factory and a namespace for regular expressions in POCA.

    • RegExp.create and RegExp.compile compile a pattern into a ghost object.

    • The new operator is an alias for RegExp.create (there is no separate constructor).

    • RegExp.escape produces a safe, escaped version of a string for literal pattern matching.

    • Native regex literal syntax (e.g., /pattern/) is supported.

  • RegExp Ghost Object Methods: Once created, RegExp objects provide the following methods:

    • exec: Executes the pattern and returns detailed capture results.

    • test: Checks if the input string matches the pattern.

    • find: Retrieves the starting position of the first match.

    • match: Collects an array of matches.

    • split: Divides the input string based on match positions.

    • replace: Replaces matched portions with a replacement string.

This comprehensive API lets you perform all common regex operations in a dynamic, typeless environment, making pattern matching and text manipulation both flexible and powerful in your POCA projects.

Semaphore

Overview

The POCA Semaphore API provides counting semaphore mechanisms for synchronizing access to shared resources in concurrent POCA scripts. Semaphores in POCA are dynamic, typeless ghost objects created via a factory function. With this API, you can control access to resources by decrementing (down) or incrementing (up) the semaphore count.


Global Semaphore Object

The global Semaphore object serves as both a factory and a namespace for semaphore operations. You can create semaphore ghost objects using either of the following variants:

Semaphore.create(), or new Semaphore()

Usage:

let sem = Semaphore.create();

or equivalently,

let sem = new Semaphore();
  • Description: Semaphore.create() or new Semaphore() creates a new semaphore ghost object by invoking the underlying semaphore creation routine. The resulting ghost object represents a counting semaphore, which is registered for subsequent semaphore operations.

  • Parameters: None.

  • Return Value: A semaphore ghost object that can be used to control access to shared resources.

  • Example:

    // Create a new semaphore using either syntax.
    let sem1 = Semaphore.create();
    let sem2 = new Semaphore();

Methods on Semaphore Ghost Objects

Once created, a semaphore ghost object provides the following methods:

Semaphore.down

Usage:

sem.down();
  • Description: Decrements the semaphore count, effectively acquiring a resource. If the semaphore count is zero, the calling thread may block until a resource is released. The garbage collector is unlocked while waiting for the semaphore.

  • Parameters: None.

  • Return Value: A null value (the function does not return a meaningful value).

  • Example:

    // Acquire a semaphore slot.
    sem.down();

Semaphore.up

Usage:

sem.up();
  • Description: Increments the semaphore count, releasing a resource. This operation signals the semaphore to allow waiting threads to proceed.

  • Parameters: None.

  • Return Value: A null value.

  • Example:

    // Release a semaphore slot.
    sem.up();

Summary

  • Global Object: The Semaphore object acts as a factory for creating semaphore ghost objects. Semaphore.create() or new Semaphore() creates a new semaphore ghost object by invoking the underlying semaphore creation routine. The resulting ghost object represents a counting semaphore, which is registered for subsequent semaphore operations.

  • Semaphore Ghost Object Methods: Once created, semaphore ghost objects provide the following methods to manage access:

    • down: Decrements the semaphore count (acquires a resource).

    • up: Increments the semaphore count (releases a resource).

  • Usage: Semaphores enable you to synchronize access to shared resources in concurrent POCA scripts by controlling how many execution contexts can access a resource simultaneously.

This comprehensive API lets you incorporate semaphore mechanisms into your POCA projects, providing essential synchronization for concurrent execution.

String

Overview

The POCA String API provides a rich set of operations for manipulating strings in POCA scripts. Strings in POCA are a native type (not ghost objects) that support extensive methods for inspection, conversion, searching, and modification. You can create string values using string literal syntax (using double quotes "" or single quotes '') or by using the global String object via factory functions such as String.create() or new String().

Strings in POCA are always UTF-8 encoded, and the API provides methods for working with both code points and code units. The API includes methods for counting code points, converting strings to numbers, checking for substring presence, splitting strings, trimming whitespace, and more. But POCA’s UTF-8 decoder fallbacks to Latin-1 if it detects an invalid UTF-8 sequence at a code unit boundary. This allows you to work with strings that may contain invalid UTF-8 sequences without raising problems. And it allows you to use the same string API for both UTF-8 and Latin-1 strings, and even mixed strings containing both encodings.

In contrast, JavaScript/ECMAScript strings are UTF-16 encoded, which can lead to issues when working with characters outside the Basic Multilingual Plane (BMP). POCA strings are always UTF-8 encoded, which means they can handle a wider range of characters without the complications of surrogate pairs. This makes POCA strings more straightforward to work with, especially for internationalization and localization.

  • Note: The POCA String API is designed to be similar to JavaScript’s String API, but it also includes some Lua-like features. This combination provides a familiar yet powerful string manipulation experience for developers coming from both JavaScript and Lua environments.


Global String Object

The global String object serves as both a factory and a namespace for string operations. You can create string values using any of the following variants:

String.create(), new String(), or Literal Syntax

Usage:

let str1 = String.create("Hello, POCA!");

or equivalently,

let str2 = new String("Hello, POCA!");

or simply using literals:

let str3 = "Hello, POCA!";
let str4 = 'Hello, POCA!';
  • Description: String.create(), new String(), or using literal syntax creates a new string value by invoking the underlying string creation routine. The resulting value represents the given sequence of characters and is available for subsequent string operations.

  • Parameters: A string value (if provided) used to initialize the string.

  • Return Value: A new string value.

  • Example:

    // Using factory functions:
    let greeting = String.create("Hello, World!");
    let farewell = new String("Goodbye!");
    
    // Using literal syntax:
    let literalStr1 = "Literal String";
    let literalStr2 = 'Another Literal';

API Functions

Below is a detailed description of every API function available for strings in POCA.

String.countCodePoints

Usage:

let count = "example".countCodePoints();
  • Description: Returns the number of Unicode code points in the string. If the string is encoded as UTF‑8, the function returns the UTF‑8 length; otherwise, it returns the raw length.

  • Parameters: None.

  • Return Value: A numeric value representing the number of code points.


String.countCodeUnits

Usage:

let count = "example".countCodeUnits();
  • Description: Returns the number of code units (raw characters) in the string.

  • Parameters: None.

  • Return Value: A numeric value representing the number of code units.


String.length

Usage:

let len = "example".length;
  • Description: A pseudo-property that returns the length of the string. For UTF‑8 strings, this is the number of Unicode code points; otherwise, it is the raw character count. As functional syntax, it is equivalent to calling 'String.size()', String.countCodePoints() or String.countCodeUnits().

  • Parameters: None.

  • Return Value: A numeric value representing the length.


String.size

Usage:

let len = "example".size();
  • Description: Returns the length of the string. For UTF‑8 strings, this is the number of Unicode code points; otherwise, it is the raw character count.

  • Parameters: None.

  • Return Value: A numeric value representing the length.


String.toNumber

Usage:

let num = "123.45".toNumber();
  • Description: Converts the string to a numeric value. An optional precision argument may be provided to control the conversion precision.

  • Parameters:

    • precision (optional, number): The number of digits to consider.

  • Return Value: A numeric value representing the converted number, or null if conversion fails.


String.toString

Usage:

let s = "Hello".toString();
  • Description: Returns the string itself. This function is useful for explicit conversion.

  • Parameters: None.

  • Return Value: The string value.


String.includes

Usage:

if ("Hello, World!".includes("World")) {
  puts("Found!");
}
  • Description: Checks whether the string contains the specified substring.

  • Parameters:

    • substring (string): The string to search for.

  • Return Value: A numeric boolean value: 1 if found, 0 otherwise.


String.indexOf

Usage:

let idx = "Hello, World!".indexOf("World");
  • Description: Returns the index (0-based) of the first occurrence of the specified substring. If not found, returns -1.

  • Parameters:

    • substring (string): The substring to search for.

  • Return Value: A numeric index (0-based), or -1 if the substring is not found.


String.lastIndexOf

Usage:

let idx = "Hello, World! Hello!".lastIndexOf("Hello");
  • Description: Returns the index (0-based) of the last occurrence of the specified substring. If not found, returns -1.

  • Parameters:

    • substring (string): The substring to search for.

  • Return Value: A numeric index (0-based), or -1 if the substring is not found.


String.split

Usage:

let parts = "a,b,c".split(delimiter, skipEmpty);
  • Description: Splits the string into an array of substrings using the specified delimiter.

  • Parameters:

    • delimiter (string): The string used to split the text.

    • skipEmpty (optional, number): If set to 1, empty substrings are ignored.

  • Return Value: An array of strings.


String.trim

Usage:

let trimmed = "  Hello  ".trim();
  • Description: Returns a new string with whitespace removed from both ends.

  • Parameters: None.

  • Return Value: A string with leading and trailing whitespace removed.


String.trimLeft

Usage:

let trimmed = "  Hello".trimLeft();
  • Description: Returns a new string with whitespace removed from the beginning (left side).

  • Parameters: None.

  • Return Value: A string with left-side whitespace removed.


String.trimRight

Usage:

let trimmed = "Hello  ".trimRight();
  • Description: Returns a new string with whitespace removed from the end (right side).

  • Parameters: None.

  • Return Value: A string with right-side whitespace removed.


String.toLowerCase

Usage:

let lower = "HeLLo".toLowerCase();
  • Description: Converts the string to lower case.

  • Parameters: None.

  • Return Value: A new string in lower case.


String.toUpperCase

Usage:

let upper = "HeLLo".toUpperCase();
  • Description: Converts the string to upper case.

  • Parameters: None.

  • Return Value: A new string in upper case.


String.escape

Usage:

let escaped = "Hello\nWorld\t!".escape();
  • Description: Escapes special characters in the string using standard escape sequences. Control characters (like newline, tab, etc.) are converted to their escape sequences (\n, \t, etc.). For UTF-8 strings, non-ASCII characters are escaped using Unicode escape sequences: \xXX for bytes 0-255, \uXXXX for Unicode code points 256-65535, and \UXXXXXXXX for code points above 65535. Printable ASCII characters (32-126) except special characters remain unescaped.

  • Parameters: None.

  • Return Value: A new string with special characters escaped.

  • Example:

    let s1 = "Hello\nWorld";
    puts(s1.escape()); // Output: Hello\nWorld
    
    let s2 = "Quote: \"test\"";
    puts(s2.escape()); // Output: Quote: \"test\"
    
    let s3 = "Unicode: \u4F60\u597D";
    puts(s3.escape()); // Output: Unicode: \u4F60\u597D

String.unescape

Usage:

let s = "The \\U0001F920 rides a \\U0001F40E!".unescape(); // Output: The 🤠 rides a 🐎!
  • Description: Unescapes escape sequences in the string back to their original characters. Recognizes standard escape sequences (\n, \t, etc.) as well as Unicode escape sequences (\xXX, \uXXXX, \UXXXXXXXX).

  • Parameters: None.

  • Return Value: A new string with escape sequences converted back to their original characters.

  • Example:

    let s = "The \\U0001F920 rides a \\U0001F40E!".unescape();
    puts(s); // Output: The 🤠 rides a 🐎!

String.substr

Usage:

let sub = "Hello, World!".substr(7, 5);
  • Description: Extracts a substring from the string starting at the specified index (0-based, with negative values counting from the end) and extending for the specified length. Indices are based on Unicode code points if the string is UTF‑8.

  • Parameters:

    • start (number): The starting index.

    • length (number): The number of characters to extract.

  • Return Value: A substring.


String.toLatin1

Usage:

let latin = "Some text".toLatin1();
  • Description: Converts the string to Latin1 encoding. Note: In strict UTF‑8 POCA builds, calling this function raises an error.

  • Parameters: None.

  • Return Value: A string in Latin1 encoding.


String.isLatin1

Usage:

let check = "Some text".isLatin1();
  • Description: Checks if the string is in Latin1 encoding.

  • Parameters: None.

  • Return Value: A numeric boolean value: 1 if true, 0 if false.


String.toUTF8

Usage:

let utf8 = "Some text".toUTF8();
  • Description: Converts the string to UTF‑8 encoding.

  • Parameters: None.

  • Return Value: A string in UTF‑8 encoding.


String.isUTF8

Usage:

let check = "Some text".isUTF8();
  • Description: Checks if the string is in UTF‑8 encoding.

  • Parameters: None.

  • Return Value: A numeric boolean value: 1 if true, 0 if false.


String.charAt

Usage:

let ch = "Hello".charAt(1);
  • Description: Returns the character at the specified code point index (0-based, with negative values allowed to count from the end).

  • Parameters:

    • index (number): The code point index.

  • Return Value: A string containing the character, or null if the index is out of bounds.


String.codePointAt

Usage:

let cp = "Hello".codePointAt(1);
  • Description: Returns the Unicode code point of the character at the specified index.

  • Parameters:

    • index (number): The code point index.

  • Return Value: A numeric value representing the Unicode code point.


String.codeUnitAt

Usage:

let cu = "Hello".codeUnitAt(1);
  • Description: Returns the raw code unit (character code) at the specified position.

  • Parameters:

    • index (number): The code unit index.

  • Return Value: A numeric value representing the code unit.


String.codePointToCodeUnit

Usage:

let unitIdx = "Hello".codePointToCodeUnit(2);
  • Description: Converts a code point index to its corresponding code unit index.

  • Parameters:

    • index (number): The code point index.

  • Return Value: A numeric value representing the code unit index.


String.codeUnitToCodePoint

Usage:

let pointIdx = "Hello".codeUnitToCodePoint(2);
  • Description: Converts a code unit index to its corresponding code point index.

  • Parameters:

    • index (number): The code unit index.

  • Return Value: A numeric value representing the code point index.


String.codePoints

Usage:

let cps = "Hello".codePoints();
  • Description: Returns an array of all Unicode code points in the string.

  • Parameters: None.

  • Return Value: An array of numeric code points.


String.codeUnits

Usage:

let cus = "Hello".codeUnits();
  • Description: Returns an array of all code units (raw character codes) in the string.

  • Parameters: None.

  • Return Value: An array of numeric code units.


String.concat

Usage:

let combined = "Hello".concat(", ", "World!");
  • Description: Concatenates the string with one or more other strings.

  • Parameters: One or more string values to concatenate.

  • Return Value: A new string resulting from the concatenation.


String.repeat

Usage:

let repeated = "abc".repeat(3);
  • Description: Returns a new string that consists of the original string repeated a specified number of times.

  • Parameters:

    • count (number): The number of times to repeat the string.

  • Return Value: A new string.


String.create

Usage:

let s = String.create("initial value");
  • Description: Creates a new string value. If no argument is provided, an empty string is created.

  • Parameters:

    • initialValue (string, optional): The string to initialize the new value.

  • Return Value: A new string value.


String.dump

Usage:

let info = String.dump(input);
  • Description: Returns a detailed dump (debug representation) of the input parameter. This is useful for debugging and inspecting the internal representation of the input.

  • Parameters: Input parameter (any type).

  • Return Value: A string containing the dump information.

  • Example:

    let dumpInfo = String.dump({a: 1, b: "text", c: [1, 2, 3]});
    puts(dumpInfo);
  • Output:

    {"a":1,"b":"text","c":[1,2,3]}
  • Note: The output format may vary based on the input type and implementation details. The dump function provides a human-readable representation of the input, which can be useful for debugging and inspecting complex data structures.


String.fromCodePoints

Usage:

let s = String.fromCodePoints(72, 101, 108, 108, 111);

or

let s = String.fromCodePoints([72, 101, 108, 108, 111]);
  • Description: Creates a new string from a sequence (or array) of Unicode code points.

  • Parameters: One or more numeric code points, or an array of code points.

  • Return Value: A new string constructed from the provided code points.


String.fromCodeUnits

Usage:

let s = String.fromCodeUnits(72, 101, 108, 108, 111);

or

let s = String.fromCodeUnits([72, 101, 108, 108, 111]);
  • Description: Creates a new string from a sequence (or array) of code units.

  • Parameters: One or more numeric code units, or an array of code units.

  • Return Value: A new string constructed from the provided code units.


Summary

  • Global Object: The String object acts as a factory for creating string values. String.create(), new String(), or using string literals ("" or '') creates a new string value by invoking the underlying string creation routine. The resulting value represents the text and is available for subsequent operations.

  • String Methods: The POCA String API provides a comprehensive suite of functions for string manipulation:

    • Inspection & Measurement: countCodePoints, countCodeUnits, 'size' and length return measurements of the string.

    • Conversion: toNumber and toString convert the string between different representations.

    • Search & Extraction: includes, indexOf, lastIndexOf, split, trim, trimLeft, trimRight, substr, and charAt allow searching and extracting parts of the string.

    • Code Unit/Point Operations: codePointAt, codeUnitAt, codePointToCodeUnit, codeUnitToCodePoint, codePoints, and codeUnits facilitate Unicode-related operations.

    • Modification: concat and repeat support combining and repeating strings.

    • Case Conversion: toLowerCase and toUpperCase change the case of the string.

    • Encoding Conversions: toLatin1, isLatin1, toUTF8, and isUTF8 handle encoding transformations.

    • Utility & Creation: dump, fromCodePoints, and fromCodeUnits provide utility functions and alternate ways to create strings.

  • Usage: The POCA String API offers robust text manipulation capabilities similar to those in JavaScript. Whether you create strings using literal syntax or factory functions, this comprehensive API lets you incorporate advanced text processing into your POCA projects in a dynamic, typeless environment.

  • Note: The String API is designed to be flexible and powerful, allowing you to work with strings in a way that suits your needs. The API is consistent and easy to use, making it a valuable tool for string manipulation in POCA.

Thread

Overview

The POCA Thread API allows you to execute functions concurrently in separate threads. Threads in POCA are dynamic, typeless ghost objects that encapsulate a separate OS thread running a POCA function. With this API you can create new threads, resume or suspend their execution, terminate them, check their status, and wait for them to finish.


Global Thread Object

The global Thread object serves as both a factory and a namespace for thread operations. It provides functions to create and manage threads within your POCA scripts.

Thread.create

Usage:

let th = Thread.create(function(a, b) {
  // Thread body: perform work with a and b.
  puts("Thread started with: " + a + ", " + b);
  // ... execute thread tasks ...
  return "Thread finished";
}, arg1, arg2);
  • Description: Thread.create creates a new thread ghost object with the the provided function. The first argument must be a function; any additional arguments will be passed to that function when the thread starts. Internally, a new execution context is created, and the thread ghost object is registered in the global thread hash.

  • Parameters:

    • func (function): The function to execute in the thread.

    • ...args (any): Additional arguments that will be passed to the thread function.

  • Return Value: A thread ghost object that encapsulates the newly created thread.

  • Example:

    // Create a thread that accepts two arguments.
    let th = Thread.create(function(a, b) {
      puts("Started with: " + a + " and " + b);
      // Perform thread-specific work...
      return "Done";
    }, "foo", "bar");

Methods on Thread Ghost Objects

Once created, a thread ghost object provides the following methods:

Thread.resume

(Alias: Thread.start)

Usage:

th.resume(value);
  • Description: Resumes the execution of a suspended thread. If the thread has not yet started, this signals its start semaphore to begin execution. Optionally, a value can be passed to the thread; this value will be available within the thread upon resumption. Like suspend, it is not supported on all platforms. On non-supporting platforms, calling this function will be a no-op. So usage of this function should be done with caution.

  • Parameters:

    • value (any): The value to pass to the thread on resume. If omitted, a null value is used.

  • Return Value: The thread ghost object itself.

  • Example:

    // Resume the thread, passing "continue" as the resume value.
    th.resume("continue");

Thread.suspend

Usage:

th.suspend();
  • Description: Suspends the execution of a running thread. On Windows systems, this is typically achieved by calling the appropriate system function to suspend the thread. However, it is not supported on all platforms. On non-supporting platforms, calling this function will be a no-op. So usage of this function should be done with caution.

  • Parameters: None.

  • Return Value: The thread ghost object itself.

  • Example:

    // Suspend the thread.
    th.suspend();

Thread.kill

(Alias: Thread.stop)

Usage:

th.kill();

or

th.stop();
  • Description: Terminates the thread forcibly. This function calls the underlying system routine (e.g., KillThread or TerminateThread) to stop the thread, marks the thread as terminated, and cleans up its resources. Like suspend and resume, it is not supported on all platforms. On non-supporting platforms, calling this function will be a no-op. So usage of this function should be done with caution.

  • Parameters: None.

  • Return Value: The thread ghost object itself.

  • Example:

    // Terminate the thread.
    th.kill();

Thread.terminated

Usage:

let status = th.terminated();
  • Description: Checks whether the thread has been terminated.

  • Parameters: None.

  • Return Value: A numeric boolean value: 1 if the thread is terminated, 0 otherwise.

  • Example:

    if (th.terminated()) {
      puts("Thread has terminated.");
    }

Thread.wait

Usage:

let finished = th.wait(timeout);
  • Description: Waits for the thread to terminate. If a timeout (in milliseconds) is provided, the function waits for that duration; otherwise, it waits indefinitely. After waiting, it returns whether the thread has terminated.

  • Parameters:

    • timeout (number): The maximum number of milliseconds to wait. If omitted, waits indefinitely.

  • Return Value: A numeric boolean value: 1 if the thread terminated, or 0 if the timeout expired and the thread is still running.

  • Example:

    // Wait indefinitely for the thread to terminate.
    if (th.wait()) {
      puts("Thread has terminated.");
    }
    
    // Wait up to 1000 milliseconds.
    if (th.wait(1000)) {
      puts("Thread terminated within 1 second.");
    }

Summary

  • Global Object: The Thread object acts as a factory for creating thread ghost objects. The Thread.create function creates a thread ghost object with a POCA function, registering it for execution management.

  • Thread Ghost Object Methods: Once created, thread ghost objects provide the following methods to manage their execution:

    • resume (start): Begins or resumes thread execution.

    • suspend: Suspends the thread.

    • kill (stop): Terminates the thread.

    • terminated: Checks if the thread has finished executing.

    • wait: Waits for the thread to complete, optionally with a timeout.

  • Usage: Threads enable concurrent execution in POCA. They run in their own execution context and manage their own arguments, state, and resource cleanup. This API allows you to offload work from the main thread and manage asynchronous operations in a dynamic, typeless environment.

This comprehensive API lets you incorporate multithreading into your POCA projects, providing flexible control over concurrent execution.

Clone this wiki locally