Kyu
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) andKronos-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.