Quassaunt

Quassaunt is an esolang by User:BoundedBeans based around sets and reverse-polish notation.
==Data==
Everything in Quassaunt is either a set or a string. Variables can only be created as sets (other than @@[Whitespace], which contains a single string and cannot be set or deleted), but strings can be on the evaluation stack for the notation, and they can be manipulated there. Sets may contain either strings or sets. The variable @@[Whitespace] contains the string " \t\n\r", and this is the only way to obtain whitespace characters in strings. Variables with names beginning with ## or ^^ (such as @@##Argv ) are reserved. They may have special semantics for %%Store, %%Obtain, and %%Delete. ## variables are reserved for future additions to the Quassaunt standard, while ^^ variables are reserved for extensions to the language.
==Syntax==
Every piece of syntax is a word. Words can have any character except for space, tab, linefeed, or carriage return. (Vertical tabs and form feeds can be contained within words, but they aren't really necessary for anything. However, they do obfuscate code, a high priority of this language.) Strings are always represented as words, so they may never contain whitespace literally.
==Commands==
Commands starting with ^^ (like %%^^Whatever) are reserved for unofficial extensions to the language. Extensions officially sanctioned by the creator, User:BoundedBeans, will use no prefix.
%%Empty 	( -- set) Push an empty set.
@@(text) 	( -- str) Push a string with the text.
%%Store 	(str set -- ) Store the set into the variable with the name of the string. Any variables with names enclosed in square brackets are global, otherwise they are local.
%%Obtain 	(str -- set) Retrieve the set from the variable with the name of the string.
%%Concatenate 	(str str -- str) Concatenate the top string after the bottom string.
%%Makecontain 	(val set -- set) Add a value to a set. If it already contains it, store the set @@No_duplicates_are_allowed_in_a_set. %%Empty %%Makecontain in the global variable @@##Errormessage and push the empty set.
%%Makenotcontain 	(set val -- set) Make the set not contain the value. If it doesn't contain it, store the set @@The_set_does_not_contain_the_value_entered. %%Empty %%Makecontain in the global variable @@##Errormessage and push the empty set.
%%Concatenateall 	(str dummy set dummy -- str) Ignores some required useless values and gets the string with all the strings in the set concatenated with a separator in between. The order (or absence of one) that the strings are concatenated is implementation-dependant. Sets should not be included.
%%Evaluate 	(str -- ?) Evaluates the string on the top of the stack as Quassaunt code, with the stack shared. Words will be separated with "?" (without quotes) rather than whitespace.
%%Evaluatepermanently	(str -- ) Like %%Evaluate, but never returns. You can use this to accomplish tail recursion and truly infinite looping. Also completely throws the existing call stack away, since it won't be needed anymore.
%%Evaluatereplace 	(str -- ) Like %%Evaluate, but instead of making a new entry on the call stack, it replaces the top one. This is the new way to do tail recursion, allowing tail recursive functions to be called in another tail recursive function.
%%Ifpropersubset 	(str set str set -- ?) If the top set is a proper subset of the bottom set, evaluate the bottom string, otherwise, evaluate the top string.
%%Ifdisjoint 	(str set str set -- ?) If the top set is disjoint to the bottom set, evaluate the bottom string, otherwise, evaluate the top string.
%%Printtoconsole 	(str -- ) Prints a string to the console.
%%Inputchar 	( -- str) Gets a character of input as a single-character string.
%%Delete 	(str -- ) Deletes the variable with the name of the string.
%%Head 	(str -- str) Returns the first character of the string.
%%Tail 	(str -- str) Returns everything but the first character of the string.
%%Swap 	(a b -- b a) Swaps the top two elements on the stack.
===Extensions===
%%Multithread	(str str -- ) Evaluates the two strings in parallel, sharing global variables but having separate local variables.
===Special variables===
* @@##Errormessage
** Stores a set typically containing a single element, an error message string. The set will be empty if there was no error yet, and may contain more elements if set manually.
** %%Store changes the error set.
** %%Obtain retrieves the error set.
** %%Delete resets the error set to the empty set.
* @@##Argv
** Stores a queue of strings, with the name of the program in the front and the rest of the arguments following in order.
** %%Store enqueues a new string to the queue, for whatever purpose.
** %%Obtain dequeues and returns the front string.
** %%Delete empties the queue, but it still exists and more things can be enqueued (if you want to ignore the arguments for whatever reason).
* @@##Argvsupport
** Stores whether @@##Argv is supported (it may not be if the system Quassaunt is running on doesn't have those, or if the interpreter doesn't do that).
** %%Store evaluates @@##Errormessage @@@@##Argvsupport_does_not_support_%%Store. %%Empty %%Makecontain %%Store.
** %%Obtain evaluates @@Y %%Empty %%Makecontain if @@##Argv is supported, otherwise @@N %%Empty %%Makecontain.
** %%Delete evaluates @@##Errormessage @@@@##Argvsupport_does_not_support_%%Delete. %%Empty %%Makecontain %%Store.
==Other conditions besides %%Ifpropersubset and %%Ifdisjoint==
They can all be emulated.
A NOT gate can be made by using the else block.
An OR gate can be made by having the false blocks be empty and having two conditions with the same true block, the true block setting a flag to signify to another if block that they ran (that third if block being the else).
An AND gate can be made by nesting conditions.
(The examples here work if the stack contains if bottom else top)
Checking for a proper superset can be emulated by switching the sets around:
 %%Swap @@Dummy %%Swap %%Empty %%Makecontain %%Store
 %%Swap @@Dummy %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 %%Swap %%Ifpropersubset
 @@Dummy %%Delete
Checking for disjoint or equal can be emulated with NOT proper subset AND NOT proper superset.
 @@[DummyTop] %%Swap %%Store
 @@[DummyElse] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?
 %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 @@[DummyBottom] %%Swap %%Store
 @@[DummyIf] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?
 %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 
 @@[DummyElse] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@[DummyBottom] %%Obtain
 @@@@[DummyElse]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?@@[DummyTop]?%%Obtain?
 @@@@[DummyIf]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?@@[DummyBottom]?%%Obtain?
 @@%%Ifpropersubset
 %%Concatenate %%Concatenate
 @@[DummyTop] %%Obtain
 %%Ifpropersubset
Checking for equal can be emulated with (disjoint or equal) AND NOT disjoint.
 @@[DummyTop] %%Swap %%Store
 @@[DummyElse] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 @@[DummyBottom] %%Swap %%Store
 @@[DummyIf] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 
 @@[DummyNest]
 @@[DummyElse]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?
 @@[DummyBottom]?%%Obtain?
 @@[DummyIf]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall? 
 @@[DummyTop]?%%Obtain?
 @@%%Ifdisjoint
 %%Concatenate %%Concatenate %%Concatenate %%Concatenate
 %%Empty %%Makecontain %%Store
 
 @@[DummyElse] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@[DummyBottom] %%Obtain
 @@@@[DummyElse]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?@@[DummyTop]?%%Obtain?
 @@@@[DummyNest]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?@@[DummyBottom]?%%Obtain?
 @@%%Ifpropersubset
 %%Concatenate %%Concatenate
 @@[DummyTop] %%Obtain
 %%Ifpropersubset
Checking for a superset can be emulated with proper superset OR equal.
 @@[DummyFlag] %%Empty @@D %%Makecontain %%Store
 
 @@[DummyTop1] %%Swap %%Store
 @@[DummyElse1] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 @@@@[DummyTop1]?%%Delete?@@[DummyBottom1]?%%Delete?@@[DummyIf1]?%%Delete?
 %%Concatenate %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 @@[DummyBottom1] %%Swap %%Store
 @@[DummyIf1] %%Swap 
 @@[DummyIf1] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 @@@@[DummyTop1]?%%Delete?@@[DummyBottom1]?%%Delete?@@[DummyIf1]?%%Delete?
 @@@@[DummyFlag]?@@?%%Empty?@@D?%%Swap?%%Makecontain?@@?%%Swap?%%Makecontain?%%Store?
 %%Concatenate %%Concatenate %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 
 @@[DummyIf1] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@[DummyBottom1] %%Obtain
 @@
 @@[DummyTop1] %%Obtain
 
 @@[DummyTop] %%Swap %%Store
 @@[DummyElse] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 @@[DummyBottom] %%Swap %%Store
 @@[DummyIf] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 
 @@[DummyNest]
 @@[DummyElse]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?
 @@[DummyBottom]?%%Obtain?
 @@[DummyIf]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall? 
 @@[DummyTop]?%%Obtain?
 @@%%Ifdisjoint
 %%Concatenate %%Concatenate %%Concatenate %%Concatenate
 %%Empty %%Makecontain %%Store
 
 @@[DummyElse] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@[DummyBottom] %%Obtain
 @@@@[DummyElse]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?@@[DummyTop]?%%Obtain?
 @@@@[DummyNest]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?@@[DummyBottom]?%%Obtain?
 @@%%Ifpropersubset
 %%Concatenate %%Concatenate
 @@[DummyTop] %%Obtain
 %%Ifpropersubset
 
 @@[DummyIf1] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@[DummyBottom1] %%Obtain
 @@
 @@[DummyTop1] %%Obtain
 
 %%Swap @@Dummy %%Swap %%Empty %%Makecontain %%Store
 %%Swap @@Dummy %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 %%Swap %%Ifpropersubset
 @@Dummy %%Delete
 
 @@@@[DummyElse1]?%%Delete?@@[DummyFlag]?%%Delete
 @@[DummyFlag] %%Obtain
 @@[DummyElse1] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@@@[DummyElse1]?%%Delete?@@[DummyFlag]?%%Delete?
 %%Concatenate
 %%Empty @@D %%Swap %%Makecontain
 %%Ifpropersubset
 
Checking for a subset can be emulated with proper subset OR equal. 
 @@[DummyFlag] %%Empty @@D %%Makecontain %%Store
 
 @@[DummyTop1] %%Swap %%Store
 @@[DummyElse1] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 @@@@[DummyTop1]?%%Delete?@@[DummyBottom1]?%%Delete?@@[DummyIf1]?%%Delete?
 %%Concatenate %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 @@[DummyBottom1] %%Swap %%Store
 @@[DummyIf1] %%Swap 
 @@[DummyIf1] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 @@@@[DummyTop1]?%%Delete?@@[DummyBottom1]?%%Delete?@@[DummyIf1]?%%Delete?
 @@@@[DummyFlag]?@@?%%Empty?@@D?%%Swap?%%Makecontain?@@?%%Swap?%%Makecontain?%%Store?
 %%Concatenate %%Concatenate %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 
 @@[DummyIf1] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@[DummyBottom1] %%Obtain
 @@
 @@[DummyTop1] %%Obtain
 
 @@[DummyTop] %%Swap %%Store
 @@[DummyElse] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 @@[DummyBottom] %%Swap %%Store
 @@[DummyIf] %%Swap 
 @@@@[DummyTop]?%%Delete?@@[DummyBottom]?%%Delete?@@[DummyElse]?%%Delete?@@[DummyIf]?%%Delete?@@[DummyNest]?%%Delete?
 %%Swap %%Concatenate
 %%Empty %%Makecontain %%Store
 
 @@[DummyNest]
 @@[DummyElse]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?
 @@[DummyBottom]?%%Obtain?
 @@[DummyIf]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall? 
 @@[DummyTop]?%%Obtain?
 @@%%Ifdisjoint
 %%Concatenate %%Concatenate %%Concatenate %%Concatenate
 %%Empty %%Makecontain %%Store
 
 @@[DummyElse] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@[DummyBottom] %%Obtain
 @@@@[DummyElse]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?@@[DummyTop]?%%Obtain?
 @@@@[DummyNest]?%%Obtain?@@?%%Swap?@@?%%Swap?@@?%%Concatenateall?@@[DummyBottom]?%%Obtain?
 @@%%Ifpropersubset
 %%Concatenate %%Concatenate
 @@[DummyTop] %%Obtain
 %%Ifpropersubset
 
 @@[DummyIf1] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@[DummyBottom1] %%Obtain
 @@
 @@[DummyTop1] %%Obtain
 
 %%Ifpropersubset
 
 @@@@[DummyElse1]?%%Delete?@@[DummyFlag]?%%Delete
 @@[DummyFlag] %%Obtain
 @@[DummyElse1] %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@@@[DummyElse1]?%%Delete?@@[DummyFlag]?%%Delete?
 %%Concatenate
 %%Empty @@D %%Swap %%Makecontain
 %%Ifpropersubset
Checking if a set contains an element can be implemented with a non-proper subset or non-proper superset where one of the sets contains only one element.
Checking if strings are equal can be implemented with a check for equality where both sets contain only one element.
These may be easier to understand if the false block is empty.
You can also make recursion (for looping) by running storing a evaluatable string in a global variable and running it within itself (possibly conditionally).
==Stack manipulation==
You may notice there is no stack manipulation other than swap. This can be emulated.
You can emulate a pop by storing into a dummy variable:
 @@Dummy %%Swap %%Store @@Dummy %%Delete
You can emulate a duplicate by storing into a dummy variable and retrieving it twice:
 @@Dummy %%Swap %%Store
 @@Dummy %%Obtain
 @@Dummy %%Obtain
 @@Dummy %%Delete
The above pop and duplicate snippets in parenthesis only work when popping or duplicating a set. In order to pop or duplicate a string, you have to convert a string into a set containing only one string and back.
Convert from string to set:
 %%Empty %%Makecontain
Convert from set to string:
 @@ %%Swap @@ %%Swap @@ %%Concatenateall
Pop string:
 @@Dummy %%Swap %%Empty %%Makecontain %%Store @@Dummy %%Delete
Duplicate string:
 @@Dummy %%Swap %%Empty %%Makecontain %%Store
 @@Dummy %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@Dummy %%Obtain @@ %%Swap @@ %%Swap @@ %%Concatenateall
 @@Dummy %%Delete
==Examples==
===Hello_world!===
 @@Hello_world! %%Printtoconsole
===Hello world! (with space)===
 @@Hello @@[Whitespace] %%Obtain %%Head 
 %%Concatenate @@world! %%Concatenate %%Printtoconsole
===Truth-machine===
 @@[Input] %%Inputchar %%Empty %%Makecontain %%Store
 @@[0] @@0 %%Empty %%Makecontain %%Store
 @@[1Out]
 @@@@1?%%Printtoconsole?@@?@@?@@[1Out]?%%Obtain?@@?
 @@%%Concatenateall?%%Evaluatepermanently
 %%Concatenate
 %%Empty
 %%Makecontain
 %%Store
 
 @@@@0?%%Printtoconsole
 @@dummy @@[Input] %%Obtain %%Empty %%Makecontain %%Makecontain
 @@@@?@@?@@[1Out]?%%Obtain?@@?%%Concatenateall?%%Evaluatepermanently
 @@[0] %%Obtain %%Empty %%Makecontain
 
 %%Ifpropersubset
Category:Languages
Category:Stack-based
Category:2023
Category:Unimplemented