From 8cb7a66a138ddeb2e70c48c89fdee377d2eab5c8 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Thu, 20 Aug 2026 17:16:15 -0700 Subject: [PATCH] Add standard library documentation --- docs/README.md | 45 +++ docs/stdlib.json | 751 ++++++++++++++++++++++++++++++++++++++++++++++ docs/stdlib.md.py | 80 +++++ 3 files changed, 876 insertions(+) create mode 100644 docs/README.md create mode 100644 docs/stdlib.json create mode 100644 docs/stdlib.md.py diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..46b57c4 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,45 @@ +# Documentation + +This directory is used to generate documentation for the SimplicityHL +standard library, which eventually should end up at + +BlockstreamResearch/simplicity-lang-org/docs/documentation/stdlib.md + +and so become visible on the web at + +https://docs.simplicity-lang.org/documentation/stdlib + + +## Files + +`stdlib.json` + +This is a JSON file inspired by the jets documentation (`elements.json`) +from the [SimplicityHL codegen](https://github.com/BlockstreamResearch/SimplicityHL/tree/master/codegen). + +Please keep this up-to-date with the standard library content itself +by documenting all stdlib functions and their content here. + +It is assumed that "sections" in this file are *contiguous*, so please +put documentation for all library functions related to the same topic +(normally present in the same stdlib `.simf` file) together within +the JSON file. + + +`stdlib.md.py` + +This Python script can be used to translate from `stdlib.json` to +`stdlib.md`, including some provided header and footer text. The format +of `elements.json` is very close to `stdlib.json`, and the format of +`jets.md` is very close to `stdlib.md`. + + +## Workflow changes + +Feel free to replace this with other tools and workflows, as long as +they document the entire standard library and generate useful Markdown +for the developer docs site! + +Feel free to add deployment hooks that rebuild the Markdown file and +cause a PR or commit on the developer documentation repository when the +`stdlib.json` file changes. diff --git a/docs/stdlib.json b/docs/stdlib.json new file mode 100644 index 0000000..7ca1b90 --- /dev/null +++ b/docs/stdlib.json @@ -0,0 +1,751 @@ +[ + { + "simplicityhl_name": "assert_eq_1", + "section": "Asserts", + "input_type": "u1, u1", + "output_type": "()", + "description": "Assert that two `u1` values are equal.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_eq_8", + "section": "Asserts", + "input_type": "u8, u8", + "output_type": "()", + "description": "Assert that two `u8` values are equal.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_eq_16", + "section": "Asserts", + "input_type": "u16, u16", + "output_type": "()", + "description": "Assert that two `u16` values are equal.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_eq_32", + "section": "Asserts", + "input_type": "u32, u32", + "output_type": "()", + "description": "Assert that two `u32` values are equal.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_eq_64", + "section": "Asserts", + "input_type": "u64, u64", + "output_type": "()", + "description": "Assert that two `u64` values are equal.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_eq_128", + "section": "Asserts", + "input_type": "u128, u128", + "output_type": "()", + "description": "Assert that two `u128` values are equal.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_eq_256", + "section": "Asserts", + "input_type": "u256, u256", + "output_type": "()", + "description": "Assert that two `u256` values are equal.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_none_1", + "section": "Asserts", + "input_type": "Option", + "output_type": "()", + "description": "Assert that the given `Option` is `None`.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_none_8", + "section": "Asserts", + "input_type": "Option", + "output_type": "()", + "description": "Assert that the given `Option` is `None`.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_none_16", + "section": "Asserts", + "input_type": "Option", + "output_type": "()", + "description": "Assert that the given `Option` is `None`.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_none_32", + "section": "Asserts", + "input_type": "Option", + "output_type": "()", + "description": "Assert that the given `Option` is `None`.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_none_64", + "section": "Asserts", + "input_type": "Option", + "output_type": "()", + "description": "Assert that the given `Option` is `None`.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_none_128", + "section": "Asserts", + "input_type": "Option", + "output_type": "()", + "description": "Assert that the given `Option` is `None`.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_none_256", + "section": "Asserts", + "input_type": "Option", + "output_type": "()", + "description": "Assert that the given `Option` is `None`.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "not", + "section": "Binary logic", + "input_type": "bool", + "output_type": "bool", + "description": "Return the logical NOT of the given value." + }, + { + "simplicityhl_name": "or", + "section": "Binary logic", + "input_type": "bool, bool", + "output_type": "bool", + "description": "Return the logical OR of the two given values." + }, + { + "simplicityhl_name": "and", + "section": "Binary logic", + "input_type": "bool, bool", + "output_type": "bool", + "description": "Return the logical AND of the two given values." + }, + { + "simplicityhl_name": "xor", + "section": "Binary logic", + "input_type": "bool, bool", + "output_type": "bool", + "description": "Return the logical XOR of the two given values." + }, + { + "simplicityhl_name": "is_output_op_return", + "section": "OP_RETURN", + "input_type": "u32", + "output_type": "bool", + "description": "Return `true` if the output at the given index is an OP_RETURN (null data) output, `false` otherwise (including if the output does not exist)." + }, + { + "simplicityhl_name": "assert_output_is_op_return", + "section": "OP_RETURN", + "input_type": "u32", + "output_type": "()", + "description": "Assert that the output at the given index is an OP_RETURN (null data) output.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "ge_to_point", + "section": "secp256k1 operations", + "input_type": "Ge", + "output_type": "Point", + "description": "Compress an affine point to `(parity, x)`, where `parity = 1` if and only if `y` is odd." + }, + { + "simplicityhl_name": "point_to_gej", + "section": "secp256k1 operations", + "input_type": "Point", + "output_type": "Gej", + "description": "Decompress a compressed `Point` into a Jacobian point with `z = 1`.\n\n## Panics\nPanics if the compressed point does not decode to a valid curve point." + }, + { + "simplicityhl_name": "safe_gej_normalize", + "section": "secp256k1 operations", + "input_type": "Gej", + "output_type": "Ge", + "description": "Convert a Jacobian point into affine coordinates.\n\n## Panics\nPanics if the point is the point at infinity, which has no affine representation." + }, + { + "simplicityhl_name": "fe_sub", + "section": "secp256k1 operations", + "input_type": "Fe, Fe", + "output_type": "Fe", + "description": "Subtract two field elements." + }, + { + "simplicityhl_name": "scalar_sub", + "section": "secp256k1 operations", + "input_type": "Scalar, Scalar", + "output_type": "Scalar", + "description": "Subtract two scalars." + }, + { + "simplicityhl_name": "gej_sub", + "section": "secp256k1 operations", + "input_type": "Gej, Gej", + "output_type": "Gej", + "description": "Subtract two Jacobian points." + }, + { + "simplicityhl_name": "fe_eq", + "section": "secp256k1 operations", + "input_type": "Fe, Fe", + "output_type": "bool", + "description": "Check field-element equality modulo `p`." + }, + { + "simplicityhl_name": "scalar_eq", + "section": "secp256k1 operations", + "input_type": "Scalar, Scalar", + "output_type": "bool", + "description": "Check scalar equality modulo the curve order `n`." + }, + { + "simplicityhl_name": "ge_eq", + "section": "secp256k1 operations", + "input_type": "Ge, Ge", + "output_type": "bool", + "description": "Check whether two affine points are equal." + }, + { + "simplicityhl_name": "point_point_eq", + "section": "secp256k1 operations", + "input_type": "Point, Point", + "output_type": "bool", + "description": "Check whether two compressed `Point` values are equal (same parity and same x-coordinate)." + }, + { + "simplicityhl_name": "gej_point_eq", + "section": "secp256k1 operations", + "input_type": "Gej, Point", + "output_type": "bool", + "description": "Check whether a Jacobian point and a compressed `Point` represent the same curve point.\n\n## Panics\nPanics if the compressed point does not decode to a valid curve point." + }, + { + "simplicityhl_name": "assert_fe_eq", + "section": "secp256k1 operations", + "input_type": "Fe, Fe", + "output_type": "()", + "description": "Assert field-element equality modulo `p`.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_scalar_eq", + "section": "secp256k1 operations", + "input_type": "Scalar, Scalar", + "output_type": "()", + "description": "Assert scalar equality modulo the curve order `n`.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_ge_eq", + "section": "secp256k1 operations", + "input_type": "Ge, Ge", + "output_type": "()", + "description": "Assert that two affine points are equal.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_point_eq", + "section": "secp256k1 operations", + "input_type": "Point, Point", + "output_type": "()", + "description": "Assert that two compressed `Point` values are equal (same parity and same x-coordinate).\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_gej_point_eq", + "section": "secp256k1 operations", + "input_type": "Gej, Point", + "output_type": "()", + "description": "Assert that a Jacobian point equals the point encoded by a compressed `Point`.\n\n## Panics\nThe assertion fails, or the compressed point does not decode to a valid curve point." + }, + { + "simplicityhl_name": "assert_gej_eq", + "section": "secp256k1 operations", + "input_type": "Gej, Gej", + "output_type": "()", + "description": "Assert that two Jacobian points represent the same curve point, without normalizing either one first.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "assert_gej_ge_eq", + "section": "secp256k1 operations", + "input_type": "Gej, Ge", + "output_type": "()", + "description": "Assert that a Jacobian point equals an affine point, without normalizing the Jacobian point first.\n\n## Panics\nThe assertion fails." + }, + { + "simplicityhl_name": "checked_add_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "Option", + "description": "Add two `u8` values. Return `Some` of the sum, or `None` if the result overflows `u8`." + }, + { + "simplicityhl_name": "safe_add_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "u8", + "description": "Add two `u8` values.\n\n## Panics\nPanics if the result overflows `u8`." + }, + { + "simplicityhl_name": "checked_sub_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "Option", + "description": "Subtract the second `u8` value from the first. Return `Some` of the difference, or `None` if the result would underflow `u8`." + }, + { + "simplicityhl_name": "safe_sub_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "u8", + "description": "Subtract the second `u8` value from the first.\n\n## Panics\nPanics if the result would underflow `u8`." + }, + { + "simplicityhl_name": "checked_mul_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "Option", + "description": "Multiply two `u8` values. Return `Some` of the product, or `None` if the result overflows `u8`." + }, + { + "simplicityhl_name": "safe_mul_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "u8", + "description": "Multiply two `u8` values.\n\n## Panics\nPanics if the result overflows `u8`." + }, + { + "simplicityhl_name": "checked_div_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "Option", + "description": "Divide the first `u8` value by the second. Return `Some` of the quotient, or `None` if the divisor is zero." + }, + { + "simplicityhl_name": "safe_div_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "u8", + "description": "Divide the first `u8` value by the second.\n\n## Panics\nPanics if the divisor is zero." + }, + { + "simplicityhl_name": "gt_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "bool", + "description": "Check if the first `u8` value is greater than the second." + }, + { + "simplicityhl_name": "ge_8", + "section": "`u8` arithmetic", + "input_type": "u8, u8", + "output_type": "bool", + "description": "Check if the first `u8` value is greater than or equal to the second." + }, + { + "simplicityhl_name": "checked_add_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "Option", + "description": "Add two `u16` values. Return `Some` of the sum, or `None` if the result overflows `u16`." + }, + { + "simplicityhl_name": "safe_add_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "u16", + "description": "Add two `u16` values.\n\n## Panics\nPanics if the result overflows `u16`." + }, + { + "simplicityhl_name": "checked_sub_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "Option", + "description": "Subtract the second `u16` value from the first. Return `Some` of the difference, or `None` if the result would underflow `u16`." + }, + { + "simplicityhl_name": "safe_sub_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "u16", + "description": "Subtract the second `u16` value from the first.\n\n## Panics\nPanics if the result would underflow `u16`." + }, + { + "simplicityhl_name": "checked_mul_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "Option", + "description": "Multiply two `u16` values. Return `Some` of the product, or `None` if the result overflows `u16`." + }, + { + "simplicityhl_name": "safe_mul_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "u16", + "description": "Multiply two `u16` values.\n\n## Panics\nPanics if the result overflows `u16`." + }, + { + "simplicityhl_name": "checked_div_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "Option", + "description": "Divide the first `u16` value by the second. Return `Some` of the quotient, or `None` if the divisor is zero." + }, + { + "simplicityhl_name": "safe_div_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "u16", + "description": "Divide the first `u16` value by the second.\n\n## Panics\nPanics if the divisor is zero." + }, + { + "simplicityhl_name": "gt_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "bool", + "description": "Check if the first `u16` value is greater than the second." + }, + { + "simplicityhl_name": "ge_16", + "section": "`u16` arithmetic", + "input_type": "u16, u16", + "output_type": "bool", + "description": "Check if the first `u16` value is greater than or equal to the second." + }, + { + "simplicityhl_name": "checked_add_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "Option", + "description": "Add two `u32` values. Return `Some` of the sum, or `None` if the result overflows `u32`." + }, + { + "simplicityhl_name": "safe_add_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "u32", + "description": "Add two `u32` values.\n\n## Panics\nPanics if the result overflows `u32`." + }, + { + "simplicityhl_name": "checked_sub_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "Option", + "description": "Subtract the second `u32` value from the first. Return `Some` of the difference, or `None` if the result would underflow `u32`." + }, + { + "simplicityhl_name": "safe_sub_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "u32", + "description": "Subtract the second `u32` value from the first.\n\n## Panics\nPanics if the result would underflow `u32`." + }, + { + "simplicityhl_name": "checked_mul_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "Option", + "description": "Multiply two `u32` values. Return `Some` of the product, or `None` if the result overflows `u32`." + }, + { + "simplicityhl_name": "safe_mul_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "u32", + "description": "Multiply two `u32` values.\n\n## Panics\nPanics if the result overflows `u32`." + }, + { + "simplicityhl_name": "checked_div_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "Option", + "description": "Divide the first `u32` value by the second. Return `Some` of the quotient, or `None` if the divisor is zero." + }, + { + "simplicityhl_name": "safe_div_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "u32", + "description": "Divide the first `u32` value by the second.\n\n## Panics\nPanics if the divisor is zero." + }, + { + "simplicityhl_name": "gt_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "bool", + "description": "Check if the first `u32` value is greater than the second." + }, + { + "simplicityhl_name": "ge_32", + "section": "`u32` arithmetic", + "input_type": "u32, u32", + "output_type": "bool", + "description": "Check if the first `u32` value is greater than or equal to the second." + }, + { + "simplicityhl_name": "checked_add_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "Option", + "description": "Add two `u64` values. Return `Some` of the sum, or `None` if the result overflows `u64`." + }, + { + "simplicityhl_name": "safe_add_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "u64", + "description": "Add two `u64` values.\n\n## Panics\nPanics if the result overflows `u64`." + }, + { + "simplicityhl_name": "checked_sub_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "Option", + "description": "Subtract the second `u64` value from the first. Return `Some` of the difference, or `None` if the result would underflow `u64`." + }, + { + "simplicityhl_name": "safe_sub_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "u64", + "description": "Subtract the second `u64` value from the first.\n\n## Panics\nPanics if the result would underflow `u64`." + }, + { + "simplicityhl_name": "checked_mul_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "Option", + "description": "Multiply two `u64` values. Return `Some` of the product, or `None` if the result overflows `u64`." + }, + { + "simplicityhl_name": "safe_mul_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "u64", + "description": "Multiply two `u64` values.\n\n## Panics\nPanics if the result overflows `u64`." + }, + { + "simplicityhl_name": "checked_div_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "Option", + "description": "Divide the first `u64` value by the second. Return `Some` of the quotient, or `None` if the divisor is zero." + }, + { + "simplicityhl_name": "safe_div_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "u64", + "description": "Divide the first `u64` value by the second.\n\n## Panics\nPanics if the divisor is zero." + }, + { + "simplicityhl_name": "gt_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "bool", + "description": "Check if the first `u64` value is greater than the second." + }, + { + "simplicityhl_name": "ge_64", + "section": "`u64` arithmetic", + "input_type": "u64, u64", + "output_type": "bool", + "description": "Check if the first `u64` value is greater than or equal to the second." + }, + { + "simplicityhl_name": "u64_into_u256", + "section": "`u64` arithmetic", + "input_type": "u64", + "output_type": "u256", + "description": "Widen a `u64` value to a `u256` value, placing it in the least-significant word and zero-filling the rest." + }, + { + "simplicityhl_name": "and_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "u128", + "description": "Bitwise AND of two `u128` values." + }, + { + "simplicityhl_name": "or_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "u128", + "description": "Bitwise OR of two `u128` values." + }, + { + "simplicityhl_name": "eq_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "bool", + "description": "Check if two `u128` values are equal." + }, + { + "simplicityhl_name": "left_shift_128", + "section": "`u128` arithmetic", + "input_type": "u8, u128", + "output_type": "u128", + "description": "Left-shift a `u128` value by the given amount. Bits shifted out are discarded; vacated low bits are filled with zeroes." + }, + { + "simplicityhl_name": "right_shift_128", + "section": "`u128` arithmetic", + "input_type": "u8, u128", + "output_type": "u128", + "description": "Right-shift a `u128` value by the given amount. Bits shifted out are discarded; vacated high bits are filled with zeroes." + }, + { + "simplicityhl_name": "is_zero_128", + "section": "`u128` arithmetic", + "input_type": "u128", + "output_type": "bool", + "description": "Check if a `u128` value is zero." + }, + { + "simplicityhl_name": "lt_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "bool", + "description": "Check if the first `u128` value is strictly less than the second." + }, + { + "simplicityhl_name": "le_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "bool", + "description": "Check if the first `u128` value is less than or equal to the second." + }, + { + "simplicityhl_name": "gt_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "bool", + "description": "Check if the first `u128` value is strictly greater than the second." + }, + { + "simplicityhl_name": "ge_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "bool", + "description": "Check if the first `u128` value is greater than or equal to the second." + }, + { + "simplicityhl_name": "add_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "(bool, u128)", + "description": "Add two `u128` values. Return the carry bit and the (possibly wrapped) sum." + }, + { + "simplicityhl_name": "add_128_64", + "section": "`u128` arithmetic", + "input_type": "u128, u64", + "output_type": "(bool, u128)", + "description": "Add a `u64` value to a `u128` value. Return the carry bit and the (possibly wrapped) sum." + }, + { + "simplicityhl_name": "checked_add_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "Option", + "description": "Add two `u128` values. Return `Some` of the sum, or `None` if the result overflows `u128`." + }, + { + "simplicityhl_name": "safe_add_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "u128", + "description": "Add two `u128` values.\n\n## Panics\nPanics if the result overflows `u128`." + }, + { + "simplicityhl_name": "sub_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "(bool, u128)", + "description": "Subtract the second `u128` value from the first. Return the borrow bit and the (possibly wrapped) difference." + }, + { + "simplicityhl_name": "checked_sub_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "Option", + "description": "Subtract the second `u128` value from the first. Return `Some` of the difference, or `None` if the result would underflow `u128`." + }, + { + "simplicityhl_name": "safe_sub_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "u128", + "description": "Subtract the second `u128` value from the first.\n\n## Panics\nPanics if the result would underflow `u128`." + }, + { + "simplicityhl_name": "mul_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "u256", + "description": "Multiply two `u128` values. The full, non-truncated product is returned as a `u256`, so this operation can never overflow." + }, + { + "simplicityhl_name": "checked_mul_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "Option", + "description": "Multiply two `u128` values. Return `Some` of the product, or `None` if the result overflows `u128`." + }, + { + "simplicityhl_name": "safe_mul_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "u128", + "description": "Multiply two `u128` values.\n\n## Panics\nPanics if the result overflows `u128`." + }, + { + "simplicityhl_name": "split_256_into_64", + "section": "`u128` arithmetic", + "input_type": "u256", + "output_type": "((u64, u64), (u64, u64))", + "description": "Split a `u256` value into four `u64` words, most-significant first." + }, + { + "simplicityhl_name": "normalize_to_threshold", + "section": "`u128` arithmetic", + "input_type": "u128, u128, bool", + "output_type": "(u256, u128)", + "description": "Helper for `jet::div_mod_128_64`-based division algorithms. Multiplies both `a` and `b` by the same factor so that the most-significant non-zero word of `b` is at least `2^63`, as required by the division jets, which operate in base `2^64`. Set `is_b_u128` to `true` if `b`'s upper 64 bits may be non-zero, or `false` if `b` is known to fit in `u64` (in which case its upper 64 bits must already be zero).\n\n## Panics\nThe assertion fails if `is_b_u128` is `false` but `b`'s upper 64 bits are non-zero, or if `b` is zero." + }, + { + "simplicityhl_name": "algorithm_d", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "(u64, u128)", + "description": "Divide `dividend` by `divisor`, returning the `u64` quotient and the `u128` remainder. Implements Knuth's Algorithm D. Requires the upper 64 bits of `divisor` to be non-zero; use `div_mod_128_64` instead when the divisor fits in `u64`." + }, + { + "simplicityhl_name": "div_mod_128_64", + "section": "`u128` arithmetic", + "input_type": "u128, u64", + "output_type": "(u128, u64)", + "description": "Divide a `u128` value by a `u64` value, returning the `u128` quotient and the `u64` remainder.\n\n## Panics\nPanics if the divisor is zero." + }, + { + "simplicityhl_name": "div_mod_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "(u128, u128)", + "description": "Divide the first `u128` value by the second, returning the quotient and the remainder.\n\n## Panics\nPanics if the divisor is zero." + }, + { + "simplicityhl_name": "div_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "u128", + "description": "Divide the first `u128` value by the second, returning the quotient.\n\n## Panics\nPanics if the divisor is zero." + }, + { + "simplicityhl_name": "checked_div_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "Option", + "description": "Divide the first `u128` value by the second. Return `Some` of the quotient, or `None` if the divisor is zero." + }, + { + "simplicityhl_name": "safe_div_128", + "section": "`u128` arithmetic", + "input_type": "u128, u128", + "output_type": "u128", + "description": "Divide the first `u128` value by the second.\n\n## Panics\nPanics if the divisor is zero." + } +] diff --git a/docs/stdlib.md.py b/docs/stdlib.md.py new file mode 100644 index 0000000..eff5278 --- /dev/null +++ b/docs/stdlib.md.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +# This consumes stdlib.json and generates docs/documentation/stdlib.md. +# +# Adapted from jets.md.py, which generates the jets reference page +# from a JSON file with the same general structure. + +import datetime +import json +import os +import sys + +SCRIPT_NAME = os.path.basename(__file__) + + +def build_preamble(source_path): + return """# SimplicityHL standard library reference + + +The SimplicityHL standard library provides various functions useful in developing smart contracts. + +Here is a complete list of the available library functions, their type signatures, and a description of what they do. + +Some library functions can fail or panic. This allows a Simplicity program to refuse a proposed transaction by performing a mandatory assertion; these functions' return type is `()` below. The failure or panic effect produced by these functions, or the corresponding behavior of jets, is ultimately the *only* way to decline a transaction. + +For more built-in SimplicityHL functions, see the [jets reference](../documentation/jets). +""".format(source_path, SCRIPT_NAME, datetime.datetime.now().date().isoformat()) + + +def new_section(section_name, introduction=""): + template = """ +## {} + +{} + +???+ "Click to hide" + |
Standard library function
| Description | + | ----------------------------------- | ----------- |""" + return template.format(section_name, introduction) + + +def escape_cell(text): + """Escape characters that would break a Markdown table cell.""" + return text.replace("|", "\\|") + + +def format_function(name, input_type, output_type, description): + signature = escape_cell("{}({}) -> {}".format(name, input_type, output_type)) + description = escape_cell(description) + return " | `{}` | {} |".format(signature, description) + + +def main(): + if len(sys.argv) != 2: + sys.exit("usage: {} ".format(SCRIPT_NAME)) + + source_path = sys.argv[1] + with open(source_path) as f: + functions = json.load(f) + + output = [build_preamble(source_path)] + + # Assumes that all functions in a section are adjacent in the .json input! + current_section = None + for func in functions: + description = func["description"].replace("\n", "
") + section = func["section"] + if section != current_section: + output.append(new_section(section)) + current_section = section + output.append(format_function( + func["simplicityhl_name"], func["input_type"], func["output_type"], description + )) + + print("\n".join(output)) + print() + + +if __name__ == "__main__": + main()