Kyu

From Esolang
Jump to navigation Jump to search

Kyu is a weird semi-esoteric language by User:BoundedBeans created for an unpublished scratch project of a weird console-only queue-based operating system called Kronos-QOS. However, the language is not very queue-based itself. Also, the language has many dependencies on the weirdness of the operating system (such as in file I/O), so a custom environment would have to be created for it. This custom environment is pretty simple though.

Environment

Most string comparisons (command checks and script value equality) are case-insensitive. Case is preserved but there's no way to check case in the original scratch implementation (this is because Scratch is case-insensitive and case-preserving. There are ways to check case, but they are complicated, and Kronos-QOS doesn't use them).

Kronos-QOS uses one big queue of "entries" as its filesystem. An entry with contents File:[name] denotes a range of entries as being in a file up until an entry named @FileEnd. Similar things existed for folders (replacing File with Folder) but these never worked well. Entries don't have to be in files, and they mainly serve as a convenient grouping or label for certain contents.

Kronos-QOS also has a list of named matrices, which are always 10x10 and default to all entries being "0". The character "‒" (U+2012 FIGURE DASH) is not allowed in matrix entries due to being a delimiter. These matrices can only be manipulated by scripts.

There are also named alternative drives containing separate queues and matrices.

Kronos-QOS has a console which things are output to. It isn't used for reading data much but it can be as it's stored and displayed as a scratch list (@@@substring indexes the console, but this is probably a mistake).

Finally, there is a recycle bin which is not saved when the OS is shut down. There's no built-in way to clear it besides shutting down, so deleting files clutters your memory.

In any entries, whitespace and the characters "⁞" (U+205E VERTICAL FOUR DOTS), "‗" (U+2017 DOUBLE LOW LINE), or "‖" (U+2016 DOUBLE VERTICAL LINE) are not allowed due to being either delimiters or simplified to a space (which is a delimiter).

Shell commands

Kronos-QOS has a basic shell with only predefined commands. However, commands are executed by whether the entered text contains the command name, not by an exact match. If multiple commands exist, they will be executed in this order, without duplicates. These are part of Kronos-QOS and are only accessible to Kyu via @@@shellcommand.

Command Name Function
createfile Asks the user for a file name, then asks the user for the number of entries in the file, then asks the user for all the entries in sequence. If run through a script, it will still ask for input.
movefile Moves all entries of the file at the front of the queue to the back.
load In the scratch implementation, loads the disk state from a string (prompts the user for it). Ideally, on a desktop implementation, the process should be streamlined with files or autosave.
save In the scratch implementation, saves the disk state to a string that should be copied and pasted somewhere to be loaded later. Ideally, on a desktop implementation, the process should be streamlined with files or autosave.
push Asks the user for an entry, enqueues it. @current uses the current value from scripting. If used by a script, uses the first entry in function memory.
pop Dequeues an entry from the file queue and discards it.
app:time Adds the number of seconds (as a decimal) since boot to the file queue, also prints out the year, day, hour, minute, and second to the console (without the month for some reason).
deletefile Deletes the file at the front of the queue. Adds it to the back of the recycle bin.
execute If the front file of the queue is a script, executes it and moves it to the back.
findfile Given a file name, finds the file in the queue and puts it at the front. The file name is prompted for in shell mode, or from the first entry in function memory in script mode.
shift Takes the front entry and moves it to the back.
restore Restores the front file of the recycle bin.
createfolder Prompts for a name, a level, and a length in subfolders/files. If the level is 0, runs createfile [length] times, otherwise calls itself recursively [length] times with the level decremented by one.
movefolder Moves all entries of the folder at the front of the queue to the back.
findfolder Given a folder name, finds the folder in the queue and puts it at the front. The folder name is prompted for in shell mode, or from the first entry in function memory in script mode.
drivesend Given a drive name, save the current state of the queue and matrices to that drive. The drive name is prompted for in shell mode, or from the first entry in function memory in script mode.
driveget Given a drive name, load the current state of the queue and matrices from that drive. The drive name is prompted for in shell mode, or from the first entry in function memory in script mode.
drivedelete Given a drive name, delete the drive and all of its contents. The drive name is prompted for in shell mode, or from the first entry in function memory in script mode.
clearconsole Clears the console.
directories Shows the folder/file structure in a nice format.

Scripts

If a file's first entry is @script, it can be executed with the execute shell command. Most commands begin with @@@, apart from @ScriptEnd which immediately halts the program. By convention, extension commands should begin with @&& or &&&, and this has been used previously in other private implementations. Commands are in entries of the file, and arguments are written in subsequent entries. Invalid commands are ignored.

When a script is loaded, an @ScriptEnd command is automatically inserted at the end. While it can be self-modified to something else, this will cause problems if the code pointer goes off the edge.

While a script is running, it has access to "function memory", a 1-based integer-indexed list of strings. There's also a "function filesystem", which is a list of entries that gets appended to the regular filesystem queue when the script is finished. Scripts also use two "current values" which are essentially accumulator registers.

Scripts can be self-modifying, and this is the only way to output text dynamically to the console or modify matrices dynamically.

Script commands

Command Function
@ScriptEnd Halts the program.
@@@push Appends the next entry to function memory. If the entry is @@@[current], appends current value 1, if it's @@@[current2], appends current value 2.
@@@skip Skips the code pointer [current value 1] entries forward in the script. Note that the code pointer will be incremented after this, so it's a go-to to the entry ([current value 1] + 1) entries forward.
@@@skipback Skips the code pointer [current value 1] entries backward in the script. Note that the code pointer will be incremented after this, so it's a go-to to the entry ([current value 1] - 1) entries backward.
@@@add Sets current value 1 to current value 1 + current value 2.
@@@sub Sets current value 1 to current value 1 - current value 2.
@@@mult Sets current value 1 to current value 1 * current value 2.
@@@div Sets current value 1 to current value 1 / current value 2.
@@@mod Sets current value 1 to current value 1 modulo current value 2.
@@@clearmem Clears function memory.
@@@getmem Sets current value 1 to the value of function memory at the index in the next entry in the script.
@@@makefile The next entries in the script should be the file name (which will be prefixed with File:__:_), the number of entries in the file, then that number of values that are either a plain entry or 2 entries (the first being @@@[funcmem] and the second being an index into function memory). It takes all the entries, the latter structure using values from function memory, and puts them with the file name and @FileEnd into the function filesystem.
@@@joinmem The next 3 entries in the script should be indexes into function memory. Replaces the value at index 3 with the concatenation of the values at indexes 1 and 2.
@@@console Prints the next entry to the console.
@@@gen Adds a random number from 1-100 to the end of function memory.
@@@set1 Sets current value 1 to the next entry in the script. If the entry is @@@[funcmem], the next entry should be an index into function memory, then the value in function memory will be assigned to current value 1.
@@@set2 Sets current value 2 to the next entry in the script. If the entry is @@@[funcmem], the next entry should be an index into function memory, then the value in function memory will be assigned to current value 2.
@@@destroy The next entry should be an index into function memory, deletes that index, shifting everything after it back.
@@@integrate The next two entries should be a start and end index of a range of function memory. Everything in the range is appended to the script code (or rather, inserted before the final @ScriptEnd).
@@@input Appends a line of input to function memory.
@@@letter The next two entries should be integers 1 or greater. Index 1 is the index of a string in function memory, while index 2 is a character position. The character at that position is extracted, then inserted in function memory directly after index 1, moving everything after index 1 forward.
@@@substring The next three entries should be integers 1 or greater. Index 1 points to the base string in function memory, index 2 is the start index in the base string, and index 3 is the end index in the base string. Inserts the resulting substring directly at index 1, moving the base string and everything after forward. In the scratch implementation, index 1 reads from the CONSOLE and inserts into the function memory, but this is probably a programming mistake. However, the console can be output to and cleared for technically full manipulation so this is in theory functional, and quite possibly the only way to read data from the console.
@@@insert The next two entries should be an index in function memory and a value. If the value is @@@[current], uses current value 1, if it's @@@[current2], uses current value 2. Inserts the resulting value into function memory at the index, moving the previous entry at that index and anything after forward.
@@@label The next entry should be an index into function memory, which is used for the label name (allowing for computed labels). Does a go-to to the first entry with contents @@@LABEL:[name] (though it's case sensitive, so they could both be lowercase. however, using different casing makes it easier to read).
@@@romstoragewrite The next two entries should be an index into the queue and an index into function memory. Replaces the entry at the former with the entry at the latter.
@@@romstorageread The next two entries should be an index into the queue and an index into function memory. Inserts the entry at the former to function memory at the latter index.
@@@romstoragecreate The next three entries should be a file name, and start and end indices of a range in function memory. Creates a file with the name and the contents and appends it to the queue.
@@@mempointer The next two entries should be indices into function memory. Index 1 is dereferenced twice (the value directly in function memory from the first should be another index), while index 2 is used as a plain index. The value given by index 1's dereferencing is inserted into function memory at index 2, moving the value previously at that index and everything after it forwards.
@@@clabel The next two entries should be an index into function memory and a literal label name. If the value in function memory at the index is greater than "0", (using either number comparison or string lexicographical ordering depending on the contents of function memory at that index), does a go-to to the first entry with contents @@@LABEL:[name] (though it's case sensitive, so they could both be lowercase. however, using different casing makes it easier to read).
@@@modifycode The next two entries should be indices into the code and into function memory, respectively. Replaces the entry in the code at index 1 with the value in function memory at index 2. Interestingly, since these indices are hardcoded also, there's an incentive to use this command to modify other @@@modifycode commands.
@@@matrixstoragecreate The next entry should be a matrix name. Creates the matrix.
@@@matrixstorageset The next four entries should be a matrix name, a column, a row, and a value. Sets the entry at the indices in the matrix with the name to the value.
@@@matrixstorageget The next three entries should be a matrix name, column, and row. Gets the entry at the indices in the matrix with the name and sets current value 1 to it.
@@@shellcommand Executes a Kronos-QOS shell command, sometimes taking the first few values of function memory as an argument. In case the command is execute, all of the current script state is saved before the command is run and reloaded afterwards.

External syntax

Since script entries cannot contain whitespace, a very easy method of notating QOS queues or Kyu scripts in plain text is just to list out the entries, separated by whitespace. Often newlines are the best, since this allows indices into the code (such as self-modification) to be easily obtained from line numbers.

Examples

Hello, world!

@@@console
Hello_world!

Truth-machine

@@@input
@@@clabel
1
it's_true
@@@console
0
@ScriptEnd
@@@LABEL:it's_true
@@@console
1
@@@set1
6
@@@skipback

Cat

@@@push
start
@@@LABEL:start
@@@input
@@@modifycode
9
2
@@@console
output
@@@destroy
2
@@@label
1

External resources

  • While I don't want to make the scratch project public on scratch, my terrible scratch implementation is available on this git repo as files Kronos-QOS v6.sb3 (the original scratch project) and Kronos-QOS v6.html (a fast version runnable directly in your browser, packaged/compiled with TurboWarp): [1].
  • A loose remake by the original author in Visual Basic .NET from 2022 is also available: [2]. The README.md explains most of the differences.