SATire

SATire is an esolang by User:BoundedBeans made to look like the math section of a standardized test. It was lost due to accidental deletion, but this is a recreation with a lot of extra functionality.
==Syntax==
Before processing anything else, any text between ?|( and ?|), as well as the those delimiters themselves, are removed from the program. These function as multiline comments, inline comments, and line splitters (insert a newline between them).
All programs start with Please fill out the following form., followed by a newline. Then there is a list of variable declarations, each on a separate line, of the form:
 name: value
Names should contain only letters, underscores, and digits, and should not start with a digit. They are case-sensitive. They cannot be true, false, or None. Variables starting with SATire_ are reserved for the language, SATireI_ for the implementation, SATireX_ for extensions to the language using getters and setters wrapping variables, and SATire[one or more decimal digits]_ for further reservations.
These do not support expressions, only the literals shown in #Types. To use full expressions, use the problems.
Variables are statically typed, and the variable's type depends on its initial value.
Then the program should contain the text Calculator section. followed by a blank line (a.k.a. two newlines), and then the questions, each separated by a blank line.
Extension syntax elements such as custom operators or modifiers, as well as custom types, should begin with the caret character ^. Further language additions will begin with ?. Also, the syntax None-[valid variable name]-[valid variable name]-[valid variable name] is reserved as follows, with earlier rules taking priority over later ones:
* None-of-[name1]-[name2] is for literal values by the language
* None-containing-[name1]-[name2] is for literal values by extensions
* None-pertaining_to-[name1]-[name2] is for other syntax by the language
* None-in-[name1]-[name2] is for other syntax by extensions
* None-enum-[name1]-[name2] represents a values of type None-enum.
* None-[name1]-[name2]-[name3], where name1 begins with a capital letter or underscore, is for anything by extensions
* None-[name1]-[name2]-[name3], where name1 begins with a lowercase letter, is for future language use
==Types==
Here are the different types:
Type name 	Literal regex 	Notes 	 	
Integer 	[0-9]+ 	Signed 64-bit 	 	
String 	\\[0-9A-F][0-9A-F])*" 	Strings support the escape sequence \[two hex digits] for arbitrary bytes. The hex digits A-F must be uppercase. Double quotes, backslashes, question marks, and newlines must be escaped this way. 	 	
Boolean 	false) 	 	 	
Stack 	\[(L,)*\] where L is any other literal (not expressions, but things can be dynamically pushed using expressions in code) 	The last element must still be succeeded by a comma. 	 	
None-of-the-above	None-of-the-above 	To check if a value is None-of-the-above, the best way to do it is to put it in a stack and check the stack for [] # None-of-the-above. In most useful cases that stack must be nested in another stack since None-of-the-above is also checked when a modifier is used.	 	
Hashtable 	\?\{\{(L,L,)*\?\}\} where L is any other literal (not full expressions, but pairs can be dynamically added using expressions in code) 	The last element must still be succeeded by a comma. 	 	
Function 	\?FNS, where S is a string literal. 	Represents a SATire program with the string literal as its text. Functions sometimes wrap a string of SATire code, such that the string can be retrieved, other times it encodes semantic meaning with no string.
Function code has an implicit variable of type Hashtable called SATire_params which will sent from the caller when the function is called, and returned back when the function is finished. The main program also has this variable, with the following keys:
{| class="wikitable"	Key	Value
"ARGS" 	A stack with the number of command-line arguments at the top, and the command-line arguments from first to last, top to bottom of the stack, starting with the program name. 	 	 	
"ENV" 	A stack with the number of environment variables at the top, and then the environment variables in any order. The key is separated from the value by an =. In the key, \ is replaced by \B, and = is replaced by \E.	 	 	
Each type also has an "undefined value" which is used in certain situations where the value is missing but that code might need to check.
Type 	Undefined literal
Integer 	None-of-the-digits
String 	None-of-the-characters
Boolean 	None-of-the-logic
Stack 	None-of-the-entries
None-of-the-above	None-of-the-Above (with capital A)
Hashtable 	None-of-the-hashes
Function 	None-of-the-code
Class 	None-of-the-methods
Object 	None-of-the-classes
None-enum 	None-of-the-enum_values
==Questions==
Questions follow the format:
 ([n]): Evaluate [e]. [m].
 a. [e]
 b. [e]
 c. [e]
 d. [e]
Where [n] is the question number, cases of [e] are expressions, and [m] is a modifier. 
Answers should always evaluate to stack expressions, so that the modifier can process them.
There must always be four answers, but an answer can be None-of-the-above to do a sort of else statement.
===Modifiers===
Modifiers make the questions check their answers with the top element of a stack expression, rather than checking them literally. The second element is used for other purposes.
Modifier 	Action
Round down. 	The second should be a string representing a variable name (the variable should be either of type String or of type Integer). Inputs the variable as a string or integer from standard input.
Round up. 	The second should be any value. Outputs that value.
Justify your reasoning. 	The second should be an integer from 0-255 which will be printed as a byte, the third should be an output stream identifier (the standard ones are "stdout" and "stderr").
Justify your thinking. 	The second should be a string representing a variable name of type Integer, the third should be an input stream identifier (the standard one is "stdin"). Inputs a byte as an integer from 0-255 and stores it in the variable.
Round to the nearest integer.	The second should be a number. Runs a goto to that question number. If the question number is zero, halts the program.
Round to the nearest tenth. 	The second should be a string representing a variable name, the third should be a value with the type matching the variable's type. Stores the third value into the variable. All variables set here must be declared at the top of the program, except for some special ones that may be defined by extensions or the core language.
==Execution==
It starts at question 1. Each question, it checks the top element of each stack expression answer against the expression after "Evaluate", and checks if they are equal. If multiple answers are valid, the first one will be used. If none of them are valid, the rest of the process is skipped. It then does an operation on other elements on the stack depending on the modifier. After the question is done, if a goto is not used, it will move to the next question, or halt the program if there are no more questions. Questions with gotos that want to either jump to the next line or somewhere else must specify the next line explicitly.
==Expressions==
Literals are discussed in the types section. Expressions are made up of subexpressions, operators, literals, and variable references (notated by the variable's name). Subexpressions must be surrounded by parenthesis.
===Operators===
Operators should hold the property that an operator call with the same left type/operator/right type triplet should have the same result type.
[Left type] [Operator] [Right type] 	Result type	Semantics
Integer + Integer 	Integer 	Addition
String + Integer 	String 	If the integer is in the range 0-255, adds the byte onto the end of the string and returns the new string.
String + None-of-the-above 	Function 	Converts the left operand into a dynamic function, ignoring the right operand.
Function + Function 	Function 	Returns a Function that runs the left operand and passes its return value to the right operand, then returns the right operand's return value.
Stack + Stack 	Stack 	Pushes all elements of the right stack onto the left, preserving order.
Stack + Integer 	Stack 	
* If the right argument is 0, return the length of the stack as an integer pushed to an empty stack.
* If the right argument is 1, create an empty stack. Push a String corresponding to the type name in the tables defined in the [#Types] section of this specification, for the type of the top element on the stack. Push true if the top element is an undefined value, otherwise false.
* Negative right arguments are for extensions. Further positive right arguments are reserved.
[T: Hashtable or Object] + Stack 	T 	The stack should contain two elements. The top element will be the key, the second element will be the value. Adds an entry to the Hashtable.
[T: Hashtable or Object] + Hashtable 	T 	Combines the entries of the two Hashtables, with the right operand taking priority if they share keys.
Hashtable + None-of-the-above 	Class 	Converts a Hashtable into a Class.
Class + None-of-the-above 	Hashtable 	Converts a Class into a Hashtable.
Class + Hashtable 	Object 	Creates an instance of an object.
Object + None-of-the-above 	Hashtable 	Gets the underlying Hashtable of an object.
Object + Stack 	Hashtable 	The right operand should contain two elements, the key to the function on the bottom, and the parameters to the function (which must be a hashtable) on top. The actual parameters passed to the function will be "Object" mapped to the Object, "Params" mapped to the parameters in the right operand, and "Key" mapped to the function's key. Other string keys are reserved, while non-string keys are extension points.
None-of-the-above + None-of-the-above	Function 	Returns the currently-executing function, which you can use for recursion.
Integer - Integer 	Integer 	Subtraction
Stack - Stack 	Stack 	Pushes all elements of the right stack onto the left, in a pop-push loop, return the new stack.
[T: Hashtable or Object] - [Anything]	T 	Removes the right operand as a key from the Hashtable along with any corresponding value, returns the new Hashtable. If the key isn't in the Hashtable, return the Hashtable unchanged.
Integer * Integer 	Integer 	Multiplication
Stack * Integer 	Stack 	Gets N concatenated copies of the stack.
Integer / Integer 	Integer 	Floor division
Stack $ [T: Anything] 	T 	Peeks the top element of the stack. If the type is not the same as the type of the right operand, return the undefined value of the right operand's type.
Integer $ Stack 	Stack 	Removes a number of elements from the right operand corresponding to the left operand, returns the new stack.
[Hashtable or Object] $ [Anything] 	Stack 	Create an empty stack. Get a value from the Hashtable using the right argument as a key, and push it, except if the key is not mapped, in which case nothing should be pushed. Return the resulting stack.
Function $ Hashtable 	Hashtable 	Calls the left operand. The implicit variable SATire_params is set to the right operand before the function runs anything, and is returned when the function is finished.
String $ Hashtable 	Stack 	Evaluates the left operand as an expression, using the Hashtable as a variable table if it contains only valid variable name strings as keys. If the Hashtable contains invalid keys, check for the key "level" for a number of enclosing scopes (like functions or this operator) to go up to retrieve a copy of the variable table. If there is no such key, or the Hashtable is None-of-the-hashes, use the current scope. If "level" exists but is mapped to something other than a positive integer, it's another extension point unless "level" is mapped to None-of-the-above which is reserved. 
Returns the result of the expression pushed to the empty stack, or just the empty stack if there was an error.
Stack # [Anything] 	Stack 	Returns a copy of the stack with the right side pushed onto it.
String & String 	String 	Concatenation
Integer & Integer 	Boolean 	Return true if the left integer is less than the right integer, otherwise return false.
String @ Stack 	String 	The stack should have two numbers. takes the substring starting at the index of the top element, with the length of the second element. Indexes are zero-based.
String @ String 	Function 	Takes the left argument as an extension class name, and the right argument as an individual extension function name. This allows custom functions to be added to programs by the user rather than the implementer.
Boolean ??A Boolean 	Boolean 	AND gate
Boolean ??O Boolean 	Boolean 	OR gate
Boolean ??X Boolean 	Boolean 	XOR gate (use boolean ??X true for a NOT gate)
String ?-> None-of-the-above 	Stack 	Gets the value of the variable with the left operand as its name, pushes it onto an empty stack. If the variable does not exist, return an empty stack. Ignore the right-operand.
a mod m can be implemented as a - (m * (a / m)).
Equality is checkable by the problems themselves, and you can use Round to the nearest tenth. to store a boolean. You can then use an OR gate to create less than or equal, and reverse the order for greater than and greater than or equal.
==Examples==
===Hello world===
 Please fill out the following form.
 greeting: "Hello, world!\0A"
 Calculator section.
 
 (1) Evaluate 1. Round up.
 a. ([] # greeting) # 1
 b. ["",2,]
 c. ["",3,]
 d. ["",None-of-the-above,]
===Truth-machine===
 Please fill out the following form.
 truth: 0
 Calculator section.
 
 (1) Evaluate 1. Round down.
 a. ["truth",1,]
 b. ["truth",2,]
 c. ["truth",5,]
 d. ["truth",8,]
 
 (2) Evaluate truth. Round to the nearest integer.
 a. [5,0,]
 b. [3,1,]
 c. [2049,] # ([] # 19)
 d [9,"pi^2",]
 
 (3) Evaluate 1. Round up.
 a. ([] # truth) # 1
 b. ([] # truth) # 396
 c. ([] # truth) # 205
 d. ([] # truth) # 2945
 
 (4) Evaluate 1. Round to the nearest integer.
 a. [3,1,]
 b. [3,2,]
 c. [3,3,]
 d. [3,4,]
 
 (5) Evaluate 1. Round up.
 a. ([] # truth) # 1
 b. ([] # truth) # 2
 c. ([] # truth) # 5
 d. ([] # truth) # 7
===FizzBuzz===
 Please fill out the following form.
 index: 0
 numRounds: 0
 Calculator section.
 
 (1) Evaluate 1. Round down.
 a. ["numRounds",1,]
 b. ["numRounds",2,]
 c. ["numRounds",5,]
 d. ["numRounds",6,]
 
 ?|( Modulo operator emulation.
 ?|)(2) Evaluate index - (3 * (index / 3)). Round to the nearest integer.
 a. [4,0,]
 b. [3,1,]
 c. [3,2,]
 d. [3,None-of-the-above,]
 
 (3) Evaluate index - (5 * (index / 5)). Round to the nearest integer.
 a. [5,0,]
 b. [7,1,]
 c. [7,2,]
 d. [7,None-of-the-above,]
 
 (4) Evaluate index - (5 * (index / 5)). Round to the nearest integer.
 a. [9,0,]
 b. [11,1,]
 c. [11,2,]
 d. [11,None-of-the-above,]
 
 (5) Evaluate 1. Round up.
 a. ["Buzz\0A",1,]
 b. [1,2,]
 c. [1,3,]
 d. [1,4,]
 
 (6) Evaluate 1. Round to the nearest integer.
 a. [13,1,]
 b. [13,2,]
 c. [13,3,]
 d. [13,4,]
 
 (7) Evaluate 1. Round up.
 a. ([] # index) # 1
 b. [1,2,]
 c. [1,3,]
 d. [1,4,]
 
 (8) Evaluate 1. Round to the nearest integer.
 a. [15,1,]
 b. [15,2,]
 c. [15,3,]
 d. [15,4,]
 
 (9) Evaluate 1. Round up.
 a. ["FizzBuzz\0A",1,]
 b. [1,2,]
 c. [1,3,]
 d. [1,4,]
 
 (10) Evaluate 1. Round to the nearest integer.
 a. [13,1,]
 b. [13,2,]
 c. [13,3,]
 d. [13,4,]
 
 (11) Evaluate 1. Round up.
 a. ["Fizz\0A",1,]
 b. [1,2,]
 c. [1,3,]
 d. [1,4,]
 
 (12) Evaluate 1. Round to the nearest integer.
 a. [13,1,]
 b. [13,2,]
 c. [13,3,]
 d. [13,4,]
 
 (13) Evaluate 1. Round to the nearest tenth.
 a. (([] # (index + 1)) # "index") # 1
 b. [1,2,]
 c. [1,3,]
 d. [1,4,]
 
 (14) Evaluate numRounds - index. Round to the nearest integer.
 a. [0,0,]
 b. [2,1,]
 c. [2,2,]
 d. [2,None-of-the-above,]
 
 (15) Evaluate 1. Round up. ?|( Print a newline after numbers. ?|)
 a. ["\0A",1,]
 b. [0,2,]
 c. [0,3,]
 d. [0,4,]
 
 (16) Evaluate 1. Round to the nearest tenth.
 a. [13,1,]
 b. [13,2,]
 c. [13,3,]
 d. [13,4,]
Category:2025
Category:Languages
Category:Unimplemented