1) { return FALSE; } return ord($single_char) < 0x80; } /** * Does the one-character string contain an ascii control character? * * @param string $char * @return bool */ function is_ctrl(string $char): bool { $c = ord($char); return is_ascii($char) && ( $c === 0x7f || $c < 0x20 ); } /** * Does the one-character string contain an ascii number? * * @param string $char * @return bool */ function is_digit(string $char): bool { $c = ord($char); return is_ascii($char) && ( $c > 0x2f && $c < 0x3a ); } /** * Does the one-character string contain ascii whitespace? * * @param string $char * @return bool */ function is_space(string $char): bool { return match($char) { KeyCode::CARRIAGE_RETURN, KeyCode::FORM_FEED, KeyCode::NEWLINE, KeyCode::SPACE, KeyCode::TAB, KeyCode::VERTICAL_TAB => true, default => false, }; } // ---------------------------------------------------------------------------- // ! Helper functions // ---------------------------------------------------------------------------- /** * Does the one-character string contain a character that separates tokens? * * @param string $char * @return bool */ function is_separator(string $char): bool { if ( ! is_ascii($char)) { return FALSE; } $isSep = str_contains(',.()+-/*=~%<>[];', $char); return is_space($char) || $char === KeyCode::NULL || $isSep; } /** * Replaces a slice of an array with the same value * * @param array $array The array to update * @param int $offset The index of the first location to update * @param int $length The number of indices to update * @param mixed $value The value to replace in the range */ function array_replace_range(array &$array, int $offset, int $length, mixed $value):void { if ($length === 1) { $array[$offset] = $value; return; } $replacement = array_fill(0, $length, $value); array_splice($array, $offset, $length, $replacement); } /** * Does the string $haystack contain $str, optionally searching from $offset? * * @param string $haystack * @param string $str * @param int|null $offset * @return bool */ function str_contains(string $haystack, string $str, ?int $offset = NULL): bool { if (empty($str)) { return FALSE; } return ($offset !== NULL) ? strpos($haystack, $str, $offset) !== FALSE : \str_contains($haystack, $str); } /** * Get the ASCII color escape number for the specified syntax type * * @param int $hl * @return int */ function syntax_to_color(int $hl): int { return match ($hl) { Highlight::COMMENT => Color::FG_CYAN, Highlight::ML_COMMENT => Color::FG_BRIGHT_BLACK, Highlight::KEYWORD1 => Color::FG_YELLOW, Highlight::KEYWORD2 => Color::FG_GREEN, Highlight::STRING => Color::FG_MAGENTA, Highlight::NUMBER => Color::FG_BRIGHT_RED, Highlight::OPERATOR => Color::FG_BRIGHT_GREEN, Highlight::VARIABLE => Color::FG_BRIGHT_CYAN, Highlight::DELIMITER => Color::FG_BLUE, Highlight::INVALID => Color::BG_BRIGHT_RED, Highlight::MATCH => Color::INVERT, Highlight::IDENTIFIER => Color::FG_BRIGHT_WHITE, default => Color::FG_WHITE, }; } /** * Replace tabs with the specified number of spaces. * * @param string $str * @param int $number * @return string */ function tabs_to_spaces(string $str, int $number = KILO_TAB_STOP): string { return str_replace(KeyCode::TAB, str_repeat(KeyCode::SPACE, $number), $str); }