Skip to content

Instantly share code, notes, and snippets.

@tinkerer-red
Created April 12, 2025 15:11
Show Gist options
  • Save tinkerer-red/3dda4095dea382cca89994e1a78a1665 to your computer and use it in GitHub Desktop.
Save tinkerer-red/3dda4095dea382cca89994e1a78a1665 to your computer and use it in GitHub Desktop.
Tries buffer implementation in gml
function convert_to_array_map(_map) {
static __buff = buffer_create(0, buffer_grow, 1);
var root = array_create(256, undefined); // Root node
var _names = struct_get_names(_map);
var _length = array_length(_names);
for (var _i = 0; _i < _length; _i++) {
var _find = _names[_i];
var _replace = _map[$ _find];
buffer_write(__buff, buffer_text, _find);
var _byte_len = buffer_tell(__buff);
buffer_seek(__buff, buffer_seek_start, 0);
var node = root; // Start at root
var _j = 0;
while (_j < _byte_len) {
var _byte = buffer_read(__buff, buffer_u8);
_j++;
if (node[_byte] == undefined) {
node[_byte] = array_create(256, undefined); // Create new array node
}
node = node[_byte]; // Move to next depth
}
node[0] = _replace; // Store replacement in index `0`, since `0` in a string is a terminator byte.
buffer_resize(__buff, 0); // Reset buffer for next word
}
return root; // Return just the trie
};
function string_replace_all_struct(input_string, _map, _case_sensitive=true) {
static temp_buff = buffer_create(0, buffer_grow, 1); // literally only used to write a string into a fast buffer with buffer_copy
static input_buff = buffer_create(0, buffer_fast, 1);
static output_buff = buffer_create(0, buffer_grow, 1);
static holder_buff = buffer_create(0, buffer_fast, 1); // Temporary buffer to store bytes
//micro optimization
var _temp_buff = temp_buff;
var _input_buff = input_buff;
var _output_buff = output_buff;
var _holder_buff = holder_buff;
// Pre-allocate sizes
var byte_len = string_byte_length(input_string);
buffer_resize(_input_buff, byte_len)
buffer_resize(_output_buff, byte_len)
buffer_resize(_holder_buff, byte_len)
// Write input buffer
buffer_write(_temp_buff, buffer_text, input_string);
buffer_copy(_temp_buff, 0, byte_len, _input_buff, 0)
buffer_resize(_temp_buff, 0)
//probably want to cache this if possible
var lookup = _map; // Precompute nested hashmap
//used for keeping track of the last found replacement
var _replacement = undefined;
// Buffer Tell positions (optimization)
var input_pos = 0;
var output_pos = 0;
var holder_pos = 0;
var node = lookup;
var byte = undefined;
while (byte || input_pos < byte_len) {
if (byte == undefined){
byte = buffer_read(_input_buff, buffer_u8); // Read UTF-16 codepoint
input_pos += 1;
}
var _temp = node[byte]
if (!_case_sensitive && _temp == undefined) {
// A-Z → a-z
if (byte >= 65 && byte <= 90) {
var lookup_byte = byte + 32;
_temp = node[lookup_byte];
}
// a-z → A-Z
else if (byte >= 97 && byte <= 122) {
var lookup_byte = byte - 32;
_temp = node[lookup_byte];
}
}
if (_temp != undefined) {
node = _temp; // Move deeper into the nested hashmap
// Check if the static struct exists and has "value"
var _value = node[0];
if (_value != undefined) {
_replacement = _value;
buffer_seek(_holder_buff, buffer_seek_start, 0); // Reset holder buffer
holder_pos = 0;
}
else {
// Store byte in holder buffer
buffer_write(_holder_buff, buffer_u8, byte);
holder_pos++;
}
byte = undefined;
continue;
}
else {
if (_replacement != undefined) {
buffer_write(_output_buff, buffer_text, _replacement);
_replacement = undefined;
node = lookup;
continue;
}
//if we had a replacement char found in the map
if (holder_pos) {
buffer_copy(_holder_buff, 0, holder_pos, _output_buff, buffer_tell(_output_buff));
buffer_seek(_output_buff, buffer_seek_relative, holder_pos); // Reset holder buffer
buffer_seek(_holder_buff, buffer_seek_start, 0); // Reset holder buffer
holder_pos = 0;
}
// No match found, write the original character
buffer_write(_output_buff, buffer_u8, byte);
byte = undefined;
node = lookup;
}
}
// Final replacement in case we end on a valid match
if (_replacement != undefined) {
buffer_write(_output_buff, buffer_text, _replacement);
}
// Convert buffer back to string
buffer_seek(_output_buff, buffer_seek_start, 0);
var result = buffer_read(_output_buff, buffer_text);
buffer_resize(_input_buff, 0);
buffer_resize(_output_buff, 0);
buffer_resize(_holder_buff, 0);
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment