Last active
December 16, 2025 10:16
-
-
Save IFcoltransG/4829a8d292fbca621fc3014530cb4c8d to your computer and use it in GitHub Desktop.
Stack data structure (first in = first out) for LIST items in Ink
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Ink stack code created by IFcoltransG | |
| // Released into public domain | |
| // May be used under the MIT No Attribution License | |
| LIST weekdays = Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday | |
| // store a new item on the top of `my_stack` | |
| // by calling it on a list pair with the command `Push` and the weekday we want to put on `my_stack` | |
| ~ my_stack((Push, Monday)) | |
| ~ my_stack((Push, Tuesday)) | |
| ~ my_stack((Push, Wednesday)) | |
| ~ my_stack((Push, Thursday)) | |
| ~ my_stack((Push, Friday)) | |
| ~ my_stack((Push, Saturday)) | |
| ~ my_stack((Push, Sunday)) | |
| // now we can pop values back off the stack | |
| Last day: {my_stack(Pop)} | |
| Second to last day: {my_stack(Pop)} | |
| Third to last day: {my_stack(Pop)} | |
| Middle day: {my_stack(Pop)} | |
| Third day: {my_stack(Pop)} | |
| Second day: {my_stack(Pop)} | |
| First day: {my_stack(Pop)} | |
| // USER-DEFINED STACK | |
| // storage has five cache variables and a string for long-term storage | |
| VAR my0 = () | |
| VAR my1 = () | |
| VAR my2 = () | |
| VAR my3 = () | |
| VAR my4 = () | |
| VAR my_rest = "" | |
| // convenience function for operating on specific user-defined stack | |
| // (only possible if your stack is stored in global variables) | |
| // (otherwise need to use `stack_push` and `stack_pop` directly) | |
| === function my_stack(operation) | |
| {operation == Pop: | |
| ~ temp all_options = LIST_ALL(weekdays) | |
| ~ return stack_pop(my0, my1, my2, my3, my4, my_rest, all_options) | |
| } | |
| ~ return stack_push(operation - Push, my0, my1, my2, my3, my4, my_rest) | |
| // STACK INTERNALS BELOW | |
| // the two operations that can be done to a stack | |
| LIST stack_op = Push, Pop | |
| // put `value` on top of stack represented by five cache vars and a string for long-term storage | |
| === function stack_push(value, ref s0, ref s1, ref s2, ref s3, ref s4, ref rest) | |
| ~ temp new = var_swap(s0, value) | |
| ~ new = var_swap(s1, new) | |
| ~ new = var_swap(s2, new) | |
| ~ new = var_swap(s3, new) | |
| ~ new = var_swap(s4, new) | |
| {new != (): | |
| ~ rest = "{new}," + rest | |
| } | |
| // take value from top of stack, possibly leaving one or more cache vars empty. | |
| // if all five cache vars are empty, refill all five variables | |
| // (plus the popped/returned value) using the long-term storage list | |
| // which must contain only comma-separated values from `all_options` | |
| === function stack_pop(ref s0, ref s1, ref s2, ref s3, ref s4, ref rest, all_options) | |
| ~ temp old = var_swap(s4, ()) | |
| ~ old = var_swap(s3, old) | |
| ~ old = var_swap(s2, old) | |
| ~ old = var_swap(s1, old) | |
| ~ old = var_swap(s0, old) | |
| {old == (): | |
| // refill cache from long-term storage list | |
| ~ temp cursor = "" | |
| ~ old = list_get_item(rest, cursor, all_options) | |
| ~ s0 = list_get_item(rest, cursor, all_options) | |
| ~ s1 = list_get_item(rest, cursor, all_options) | |
| ~ s2 = list_get_item(rest, cursor, all_options) | |
| ~ s3 = list_get_item(rest, cursor, all_options) | |
| ~ s4 = list_get_item(rest, cursor, all_options) | |
| ~ rest = list_remove(rest, cursor, all_options) | |
| } | |
| ~ return old | |
| // delete `cursor` from the start of a `list` containing comma-separated `all_options` values | |
| === function list_remove(list, cursor, all_options) | |
| {cursor == list: | |
| ~ return "" | |
| } | |
| ~ temp next_item = list_get_item(list, cursor, all_options) | |
| ~ return "{next_item}," + list_remove(list, cursor, all_options) | |
| // get first value after `cursor` from `list` containing comma-separated `all_options` values | |
| // then advance `cursor` past it | |
| === function list_get_item(list, ref cursor, all_options) | |
| {all_options == (): | |
| ~ return () | |
| } | |
| ~ temp sentinel = "@@@" // should never appear in argument strings | |
| ~ temp check_option = pop(all_options) | |
| {"{sentinel}{list}" ? "{sentinel}{cursor}{check_option},": | |
| ~ cursor += "{check_option}," | |
| ~ return check_option | |
| } | |
| ~ return list_get_item(list, cursor, all_options) | |
| // GENERIC UTILITY FUNCTIONS | |
| // sets a `variable` to a `value`, returning its old value | |
| === function var_swap(ref variable, new_value) | |
| ~ temp old_value = variable | |
| ~ variable = new_value | |
| ~ return old_value | |
| === function pop(ref list) | |
| ~ temp _x = LIST_MIN(list) | |
| ~ list -= _x | |
| ~ return _x |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment