From 8601a6665e4301a6dea44de0c1f79ba8bf031108 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sun, 19 Mar 2023 16:17:04 +0100 Subject: [PATCH] includes/std: Added first set of documentation to the std library --- includes/std/array.pat | 10 +++++++ includes/std/bit.pat | 28 ++++++++++++++++-- includes/std/core.pat | 64 ++++++++++++++++++++++++++++++++++++++++- includes/std/ctype.pat | 65 ++++++++++++++++++++++++++++++++++++++++++ includes/std/file.pat | 61 ++++++++++++++++++++++++++++++++++++++- includes/std/hash.pat | 14 +++++++++ includes/std/io.pat | 25 ++++++++++++++++ includes/std/ptr.pat | 20 +++++++++++++ includes/std/sys.pat | 24 ++++++++++++++++ 9 files changed, 307 insertions(+), 4 deletions(-) diff --git a/includes/std/array.pat b/includes/std/array.pat index 3e02cc4..3f05805 100644 --- a/includes/std/array.pat +++ b/includes/std/array.pat @@ -1,7 +1,17 @@ #pragma once +/*! + The array library contains various helper functions and types to make + it easier to work with Arrays. +*/ + namespace std { + /** + Simple one dimensional array wrapper + @tparam T The array types + @tparam Size Size of the array + */ struct Array { T data[Size] [[inline]]; }; diff --git a/includes/std/bit.pat b/includes/std/bit.pat index 935e628..fd1c034 100644 --- a/includes/std/bit.pat +++ b/includes/std/bit.pat @@ -2,8 +2,17 @@ #include +/*! + This library contains various helper functions for common bit operations. +*/ + namespace std::bit { + /** + Calculates the number of 1 bits in a given number + @param x The number + @return The number of bits set to 1 in `x` + */ fn popcount(u128 x) { x = (x & (std::limits::u128_max() / 3)) + ((x >> 1) & (std::limits::u128_max() / 3)); x = (x & (std::limits::u128_max() / 5)) + ((x >> 2) & (std::limits::u128_max() / 5)); @@ -12,10 +21,20 @@ namespace std::bit { return x % 0xFF; }; + /** + Checks if only a single bit is set to 1 in a given number + @param x The number + @return True if there's a single bit set to 1 in `x`, false otherwise + */ fn has_single_bit(u128 x) { return x != 0 && (x & (x - 1)) == 0; }; + /** + Rounds the given number up to the next bigger power of two + @param x The number + @return Next bigger power of two that can fit `x` + */ fn bit_ceil(u128 x) { if (x == 0) return 0; @@ -24,8 +43,13 @@ namespace std::bit { i = i + 1; return 1 << i; - }; - + };ยจ + + /** + Rounds the given number down to the next bigger power of two + @param x The number + @return Next smaller power of two + */ fn bit_floor(u128 x) { if (x == 0) return 0; diff --git a/includes/std/core.pat b/includes/std/core.pat index 8081c99..dd4ed54 100644 --- a/includes/std/core.pat +++ b/includes/std/core.pat @@ -2,58 +2,120 @@ #include +/*! + The core library contains intrinsics and "compiler magic" functions that + get extra help from the runtime to fulfill their purpose. +*/ + namespace std::core { + /** + The default ordering of bitfield members + */ enum BitfieldOrder : u8 { LeftToRight = 0, RightToLeft = 1 }; + /** + Checks if a pattern has a specific attribute assigned to it + @param pattern The pattern to check + @param attribute The attribute's name to check for + */ fn has_attribute(ref auto pattern, str attribute) { return builtin::std::core::has_attribute(pattern, attribute); }; - + /** + Returns the first parameter of the attribute of a pattern if it has one + @param pattern The pattern to check + @param attribute The attribute's name to query + */ fn get_attribute_value(ref auto pattern, str attribute) { return builtin::std::core::get_attribute_value(pattern, attribute); }; + /** + Sets the current default endianess. + Any patterns created following this attribute will be created using the set endianess. + @param endian The new default endianess + */ fn set_endian(std::mem::Endian endian) { builtin::std::core::set_endian(u32(endian)); }; + /** + Gets the current default endianess. + @return The currently set default endianess + */ fn get_endian() { return builtin::std::core::get_endian(); }; + /** + Sets the default bitfield order. + @param order The new default bitfield order + */ fn set_bitfield_order(BitfieldOrder order) { builtin::std::core::set_bitfield_order(u32(order)); }; + /** + Gets thee current default bitfield order + @return The currently set default bitfield order + */ fn get_bitfield_order() { return builtin::std::core::get_bitfield_order(); }; + /** + When used inside of a pattern that's being created using a pattern, + returns the current array index that's being processed. + If used outside of an array, always yields 0. + @return The current array index + */ fn array_index() { return builtin::std::core::array_index(); }; + /** + Queries the number of members of a struct, union or bitfield or the number of entries in an array + @param pattern The pattern to check + @return The number of members in `pattern` + */ fn member_count(ref auto pattern) { return builtin::std::core::member_count(pattern); }; + /** + Checks whether or not a given pattern has a member with a given name + @param pattern The pattern to check + @param name The name of the member to look for + @return True if a member called `name` exists, false otherwise + */ fn has_member(ref auto pattern, str name) { return builtin::std::core::has_member(pattern, name); }; + /** + Formats a pattern using it's default formatter or its custom formatter function set through + the `[[format]]` or `[[format_read]]` attribute + @param pattern The pattern to format + @return Formatted string representation of `pattern` + */ fn formatted_value(ref auto pattern) { return builtin::std::core::formatted_value(pattern); }; + /** + Checks if the given enum value corresponds has a corresponding constant + @param pattern The enum value to check + @return True if pattern has a valid enum representation, false if not + */ fn is_valid_enum(ref auto pattern) { return builtin::std::core::is_valid_enum(pattern); }; diff --git a/includes/std/ctype.pat b/includes/std/ctype.pat index c8a37be..1417718 100644 --- a/includes/std/ctype.pat +++ b/includes/std/ctype.pat @@ -1,51 +1,116 @@ #pragma once +/*! + The ctype library has functions to check if a character is part of a specific category + of ASCII characters. +*/ + namespace std::ctype { + /** + Checks if the given character `c` is a digit between '0' and '9' + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn isdigit(char c) { return c >= '0' && c <= '9'; }; + /** + Checks if the given character `c` is a hexadecimal digit between '0' and '9', `A` and `F` or `a` and `f` + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn isxdigit(char c) { return std::ctype::isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); }; + /** + Checks if the given character `c` is a upper case letter between 'A' and 'Z' + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn isupper(char c) { return c >= 'A' && c <= 'Z'; }; + /** + Checks if the given character `c` is a lower case letter between 'a' and 'z' + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn islower(char c) { return c >= 'a' && c <= 'z'; }; + /** + Checks if the given character `c` is either a upper or lower case letter between 'A' and 'Z' or 'a' and 'z' + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn isalpha(char c) { return std::ctype::isupper(c) || std::ctype::islower(c); }; + /** + Checks if the given character `c` is a upper or lower case letter or a number + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn isalnum(char c) { return std::ctype::isalpha(c) || std::ctype::isdigit(c); }; + /** + Checks if the given character `c` is a space character + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn isspace(char c) { return (c >= 0x09 && c <= 0x0D) || c == 0x20; }; + /** + Checks if the given character `c` is a invisible character + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn isblank(char c) { return c == 0x09 || c == ' '; }; + /** + Checks if the given character `c` has a printable glyph + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn isprint(char c) { return c >= '0' && c <= '~'; }; + /** + Checks if the given character `c` is a control code + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn iscntrl(char c) { return !std::ctype::isprint(c); }; + /** + Checks if the given character `c` has a visible glyph + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn isgraph(char c) { return std::ctype::isprint(c) && !std::ctype::isspace(c); }; + /** + Checks if the given character `c` is a punctuation character + @param c The character to check + @return True if `c` is part of this range, false otherwise + */ fn ispunct(char c) { return std::ctype::isgraph(c) && !std::ctype::isalnum(c); }; diff --git a/includes/std/file.pat b/includes/std/file.pat index 9c3b99e..209ea8b 100644 --- a/includes/std/file.pat +++ b/includes/std/file.pat @@ -1,9 +1,25 @@ #pragma once +/*! + The File library allows reading and writing from/to external files using + a C-like File IO API. + + **These functions are considered dangerous and require the user to manually permit them** +*/ + namespace std::file { + /** + A handle representing a file that has been opened + */ using Handle = s32; + /** + The mode to open a file in. + Read opens the file in read-only mode + Write opens the file in read and write mode + Create creates a new file if it doesn't exist and overwrites an existing file + */ enum Mode : u8 { Read = 1, Write = 2, @@ -11,41 +27,84 @@ namespace std::file { }; + /** + Opens a file + @param path The path to the file to open + @param mode File open mode + @return Handle to the newly opened file + */ fn open(str path, Mode mode) { return builtin::std::file::open(path, u32(mode)); }; + /** + Closes a file handle that has been opened previously + @param handle The handle to close + */ fn close(Handle handle) { builtin::std::file::close(handle); }; + /** + Reads the content of a file into a string + @param handle The file handle to read from + @param size Number of bytes to read + @return String containing the read data + */ fn read(Handle handle, u64 size) { return builtin::std::file::read(handle, size); }; + /** + Writes the content of a string into a file + @param handle The file handle to write to + @param data String to write to the file + */ fn write(Handle handle, str data) { - return builtin::std::file::write(handle, data); + builtin::std::file::write(handle, data); }; + /** + Sets the current cursor position in the given file handle + @param handle The file handle to set the cursor position in + @param offset The offset to move the cursor to + */ fn seek(Handle handle, u64 offset) { builtin::std::file::seek(handle, offset); }; + /** + Queries the size of a file + @param handle The handle of the file to get the size of + @return The file's size + */ fn size(Handle handle) { return builtin::std::file::size(handle); }; + /** + Resizes a file + @param handle The handle of the file to resize + */ fn resize(Handle handle, u64 size) { builtin::std::file::resize(handle, size); }; + /** + Flushes changes made to a file to disk + @param handle The handle of the file to flush + */ fn flush(Handle handle) { builtin::std::file::remove(handle); }; + /** + Deletes a file from disk. This will also automatically close this file + @param handle The handle of the file to delete + */ fn remove(Handle handle) { builtin::std::file::remove(handle); }; diff --git a/includes/std/hash.pat b/includes/std/hash.pat index ea0a1e8..175b30f 100644 --- a/includes/std/hash.pat +++ b/includes/std/hash.pat @@ -1,7 +1,21 @@ #pragma once +/*! + The hash library contains various data hash functions +*/ + namespace std::hash { + /** + Calculates the CRC32 hash of the bytes inside of a given pattern + @param pattern The pattern to calculate the crc32 hash of + @param init The CRC32 init value + @param poly The CRC32 polynomial + @param xorout The CRC32 XOR-Out value + @param reflect_in Whether or not the input bytes should be reflected + @param reflect_out Whether or not the output should be reflected + @return Calculated CRC32 hash + */ fn crc32(ref auto pattern, u32 init, u32 poly, u32 xorout, bool reflect_in, bool reflect_out) { return builtin::std::hash::crc32(pattern, init, poly, xorout, reflect_in, reflect_out); }; diff --git a/includes/std/io.pat b/includes/std/io.pat index 6ac3427..816c588 100644 --- a/includes/std/io.pat +++ b/includes/std/io.pat @@ -1,20 +1,45 @@ #pragma once +/*! + The IO library allows formatting strings and outputting text to the console +*/ + namespace std { + /** + Formats the given arguments using the format string and prints the result to the console + This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax. + @param fmt Format string + @param args Values to use in the formatting + */ fn print(str fmt, auto ... args) { builtin::std::print(fmt, args); }; + /** + Formats the given arguments using the format string and returns the result as a string + This function uses the C++20 `std::format` or libfmt's `fmt::format` syntax. + @param fmt Format string + @param args Values to use in the formatting + @return The formatted string + */ fn format(str fmt, auto ... args) { return builtin::std::format(fmt, args); }; + /** + Aborts evaluation of the code immediately and prints a error message to the console + @param message The message to print + */ fn error(str message) { builtin::std::error(message); }; + /** + Prints a warning message to the console + @param message The message to print + */ fn warning(str message) { builtin::std::warning(message); }; diff --git a/includes/std/ptr.pat b/includes/std/ptr.pat index 8bac79c..f8677cc 100644 --- a/includes/std/ptr.pat +++ b/includes/std/ptr.pat @@ -1,15 +1,35 @@ #pragma once +/*! + The Pointer library contains helper functions to deal with pointer types. + The `relative_to` functions are meant to be used with the `[[pointer_base]]` attribute +*/ + namespace std::ptr { + /** + Use the offset of the current pointer as start address + @param offset The pointer's value + @return The new pointer base + */ fn relative_to_pointer(u128 offset) { return $; }; + /** + Use the offset of the pointer's parent as start address + @param offset The pointer's value + @return The new pointer base + */ fn relative_to_parent(u128 offset) { return addressof(parent); }; + /** + Use the end of the file as pointer base address and use its value as offset backwards from there + @param offset The pointer's value + @return The new pointer base + */ fn relative_to_end(u128 offset) { return std::mem::size() - offset * 2; }; diff --git a/includes/std/sys.pat b/includes/std/sys.pat index 23b8fd0..fc81a73 100644 --- a/includes/std/sys.pat +++ b/includes/std/sys.pat @@ -2,14 +2,28 @@ #include +/*! + Basic helper functions +*/ + namespace std { + /** + Asserts that a given value is true. If it's not, abort evaluation and print the given message to the console + @param conditoon The condition that is required to be true + @param message The message to print in case the assertion doesn't hold + */ fn assert(bool condition, str message) { if (!condition) { std::error(std::format("assertion failed '{0}'", message)); } }; + /** + Asserts that a given value is true. If it's not, print the given message to the console as a warning + @param conditoon The condition that is required to be true + @param message The message to print in case the assertion doesn't hold + */ fn assert_warn(bool condition, str message) { if (!condition) { std::warning(std::format("assertion failed '{0}'", message)); @@ -17,10 +31,20 @@ namespace std { }; + /** + Queries the value of a set environment variable given it's name + @param name The name of the env variable + @return The value of that variable + */ fn env(str name) { return builtin::std::env(name); }; + /** + Returns the number of parameters in a parameter pack. + @param pack The pack to check + @return Number of parameters in `pack` + */ fn sizeof_pack(auto ... pack) { return builtin::std::sizeof_pack(pack); };