Skip to content

Custom Commands

GTG3000 edited this page Jan 28, 2019 · 18 revisions

Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

Now including Python.
Red Star ships with a Custom Command plugin that allows users to create their own commands that evaluate input and output text, using a custom lisp-based language - RSLisp.

Basic syntax

RSLisp is based on Lisp family of programming languages, and as such utilizes parenthesis and prefix notation to describe it's abstract syntax tree.

RSlisp has following constructs:

  • Symbol: -1 pi "string"
    • A symbol is the smallest unit in which RSLisp language operates, be it a number, a reference to some variable or a string.
      Note that strings have to be wrapped into double quotes ("). If you wish to include a quote in your string, you must escape it as follows: \".
      If you wish to include a backslash, it also needs to be escaped: \\.
      Keep in mind that strings are iterable.

RSLisp supports accessing the values of an iterable through following notation: list:index. For nested lists, it is possible to use multiple colons, as in list:first_level:second_level.
The index must be a symbol.

  • List: (a b c d)

    • A list is a sequence of Symbols, constrained by the brackets.
      The first symbol in the list is interpreted as a function to evaluate and the rest are the functions' arguments.
      For example: (+ 1 2) adds 1 and 2.
      Such notation is generally called "prefix notation".
  • Comment: ; any text here (+ a b)

    • A comment is a chunk of code that is ignored by the interpreter. Comments start with a semi-colon (;) and run until the end of the line (or the code), providing a way to remove chunks of code or leave helpful reminders.
      Same as quotes, if you wish (for whatever reason) to have a variable with a semicolon in it's name, you can escape it: \\;.

RSLisp evaluates the given expression recursively, and will output either the last returned value or value of a special environment variable, if (print) was used.

Standard Environment

The following is a list of functions and variables available by default to every RSLisp custom command.

Default language constructs

  • (pass)
    A non-operation. Can take any amount of arguments for comment purposes.
    Returns None, which can be useful for certain operations.
  • (def name value)
    Defines an environment variable to be the given value, creating a new variable in the process.
    The variable can then be accessed by simply putting it's name into the code.
  • (:= name value)
    Assigns a value to the given environment variable. Does not create a new environment variable if name is not valid.
    Supports assignment to a specific subscriptable iterable index through the list:index notation in the name field.
  • (lambda (arguments) body)
    Defines a new anonymous function, with arguments that will be available to the body when it's called and which will be required.
    For example, (def tri_sum (lambda (x y z) (+ x (+ y z)))) defines a function named tri_sum, that takes three arguments and returns their sum and which can be called as (tri_sum 1 2 3).
    The lambda can be passed directly as an argument to functions that require some function, for example: (map (lambda (x) (+ x 1)) (range 10)) will go over the range, adding 1 to each element.
  • (do a ... b)
    A block of expressions, evaluates the given expressions (or symbols) in order and returns the result of the last one.
  • (while condition body)
    A while loop, which will keep executing body as long as condition evaluates to True.
  • (if condition then else)
    A conditional instruction, executing then branch if condition evaluates to True, otherwise executing the else branch. No arguments are optional, if you do not want an else condition, substitute it with (pass).
  • (print a ... b)
    A simple print function. Outputs the given values as a line in the _rsoutput environment variable.
    The contents of this variable are prioritized when Red Star outputs the result of your custom command.
  • (assert var type [default])
    A helper function that attempts to ensure that the given var is of correct type - "int", "float" or "list".
    If the variable is indeed of correct type, returns the variable converted to specified type.
    Otherwise, returns default, if given, or raises a syntax error.
  • (apply function arguments)
    Given a function and arguments in a list, calls function(*arguments).
    Useful for dynamically varied number of arguments.
  • (quote expression)
    Returns the given expression as-is. Used internally to store strings.
    Can be used to define nested lists easier through (quote ((1 2)(3 4))) sort of syntax.
  • (unquote expression)
    The opposite of (quote), evaluates the given expression.
  • (>> "method" object [arguments])
    Function to access the methods of underlying python objects. Similar to calling object.method(arguments) in python.
  • (try body [except])
    A simple try-except function. Attempts evaluating body, returning text of exception or evaluating except if given.

Simple mathematical functions

  • (+ a b) (- a b) (* a b) (/ a b) (// a b) (% a b) (** a b)
    Do simple arythmetic on a and b.
    // stands for integer division (eg, (// 5 2) equals 2)
    % stands for modulo from division (eg, (% 5 2) equals 1)
    ** stands for power operator (eg, (** 5 2) equals 25)
  • (abs a) (fabs a)
    Returns the absolute value of a.
  • (max a ... b or iterable) (min a ... b or iterable)
    Returns the biggest or smallest value of those provided or those in the provided iterable if only one iterable is supplied.
  • (ceil a) (round a) (floor a)
    Rounds float a to the highest, nearest and lowest integer number respectively.
  • (modf a)
    Separates float a into it's fractional and integer parts.
    For example, (modf 5.5) will evaluate to (0.5, 5.0).

Simple logical functions

  • Comparison operators:
    • (> a b) (< a b) (>= a b) (<= a b) (== a b) (!= a b)
      Compare a and b.
      >= and <= stand for "bigger or equal" and "smaller or equal"
      != stands for "not equal"
  • Logical operators:
    • (<> a b) (not a) (and a b) (or a b)
      Operate on booleans and always return a boolean.
      <> stands for xor, exclusive or that returns True only if a or b is True but not both of them.
      and and or can be replaced with * and + respectively.

Inbuilt functions

  • (is a b)
    Returns True if a is the same object as b.
  • (f a ... b)
    Helper function, converts every given value to it's string representation and concatenates them all together.
  • (ord a) (chr a)
    Functions to turn a character (e.g. "a") into it's ascii code and back.
  • (zip a ... b)
    Manipulates lists, joining them together for consecutive iteration. Returns an iterator.
    For example, (zip (list 1 2 3 4) (list "a" "b" "c" "d")) creates the following list: ((1 "a") (2 "b") (3 "c") (4 "d")).
    (zip (zip a b)) will result in an iterator containing a and b.
    Keep in mind that (zip) is designed for making reading data from multiple lists at the same time easier. To get a list of lists you can edit, you may want to do the following: (map tolist (zip a b))
  • (int a) (float a) Attempt to convert a into an int or a float type.
  • (list? a) (null? a) (number? a) (procedure? a) (symbol? a)
    Varied checks for the nature of a.
    Note: (null? a) is equal to (== a (list)).
  • (file filename)
    Attempts to load a cc data file under the name filename. The name must be an identifier, and the data file must be uploaded using the UploadCCData command.
    The data is loaded from a json file and into a data structure which can be readily accessed.
    It is possible to use (unquote (file filename)) as an ad-hoc library implementation, if the JSON is formatted properly, for example (+ 1 2) would look like ["+", 1, 2].

Lists and iterators

  • (list a ... b) (l a ... b)
    Generates a list with all given elements, or an empty list if none are supplied.
  • (tolist iterator) (2l iterator)
    Converts a given iterator (result of (range), (imap) or (ireverse)) into a list, which can be accessed randomly.
  • (len list)
    Returns the length of the list.
  • (# index list)
    Returns the list item with given index.
    A functional alternative to list:index notation.
    Does not work for assignment.
  • (append list item)
    Adds the item on the end of the given list.
    Does not return the list.
  • (in iterable item)
    Returns true if item is found inside iterable, be it a character in a string or an item in a list.
  • (range a [b])
    A range iterator, giving a range of numbers from 0 to a-1 if given one argument or from a to b-1 if given two.
    Not subscriptable.
  • (slice [from] to [step])
    Slice operator, used to access a specific slice of a list, identical to python slice notation.
    Takes from one to three integer arguments, as follows: (slice to), (slice from to) and (slice from to step).
    To generate a slice from a given position and to the end of the list, use (pass): (slice from (pass)).
    Keep in mind that (slice 5) will give you elements with indices 0 through 4 inclusive, while (slice 5 (pass)) will give you indices from 5 and to the end of the list.
  • (reverse iterable)
    Returns a list with all the iterms of the iterable in reverse order.
    Keep in mind that this operator always returns a list, even if called on a string.
    For efficiency, (ireverse) variant is available if you do not require the result to be a subscriptable list.
  • (map function iterable)
    A map function - iterates over the supplied iterable, applying the function to each item.
    The given function must take one argument, and the result will be put into the resulting list.
    For efficiency, (imap) variant is available if you do not require the result to be a subscriptable list.
    Can be used as a for loop with following construct: (map function (range 10)) having the same effect as for i in range(10): function(i);
  • (reduce function iterable [initial])
    A special function that iterates over the given iterable and reduces it to a single value through a given function.
    The provided function must take two arguments, as follows: (function accumulator item); and return a value that will then be assigned to the accumulator.
    If initial value is not provided, the first element of the iterable will be used as the accumulator.
    This function is useful when a number of similar permutations need to be applied to some value.
  • (sort iterable [key] [reversed])
    Returns a sorted list of the items from a given iterable.
    Accepts an optional key function, which must take a single argument and return a value by which to sort the items it is given.
    Accepts an optional reversed flag. If you want to give the reversed flag without a key, replace key with (pass).
  • (filter function iterable)
    Given a function that takes one argument and returns either True or False, returns all the items of the given iterable for which that function returns True.
  • (all iterable)
    Returns True if all the items of given iterable are True.
    Can be used to test lists with help of (imap): (all (imap (lambda (x) (> x 1)) some_list)) will check if every item of some_list is bigger than 1.
  • (any iterable)
    Similarly to (all), returns True if any items of given iterable are True.
  • (sum iterable)
    Returns the sum of all the items of the given iterable.
    May take an extra argument for "start value" to add to the total sum.
  • (fsum iterable)
    Returns an accurate floating point sum of values in the iterable.
  • (dict iterable)
    Creates a python dict.
    Iterable must be a list of lists, formatted as ((key value) (key value)), most easily obtained by calling (zip keys values) with keys and values being lists.
    Keep in mind that while dict:index should still work, RSLisp does not support string indices in that format.

String methods

  • (str object) (str "method" string args)
    Gives access to python str class.
    If only one object is given, will return the string representation of that object, if possible.
    Otherwise, gives access to a method of str class:
    • "capitalize"
      Return the given string with it's first character capitalized and the rest lowercased.
    • "casefold"
      Return a casefolded version of the string.
      Casefolding is similar to lowercasing but more agressive, converting all possible letters to their lowercase counterparts.
    • "center"
      (str "center" string width [fillchar])
      Attempts to center the given string in a new string of given width, using provided fillchars or spaces.
    • "count"
      (str "count" string substring [start [end]])
      Returns the number of non-overlapping occurrences of substring in the given string.
      If given, optional start and end arguments are interpreted as in slice notation.
    • "endswith" "startswith"
      (str "endswith" string suffix/prefix [start [end]])
      Returns True if the string ends with the specified suffix or starts with the specified prefix, otherwise returns False.
      Suffix/prefix may also be a list of suffixes or prefixes to look for.
      Optional start and end arguments limit the comparison to that slice.
    • "expandtabs"
      (str "expandtabs" string [tabsize])
      Returns a copy of the string where all tab characters are replaced by one or more spaces, depending on the current column and the given tabsize, which defaults to 8.
    • "find" "rfind"
      (str "(r)find" string substring [start [end]])
      Returns the lowest (or highest) index in the given string where the substring is found within the slice between start and end, if given.
      Returns -1 if substring is not found.
    • "format"
      (str "format" string a ... b)
      Performs a formatting operation. The given string can contain literal text or replacement fields delimeted by braces {}.
      Each replacement field may be empty or contain the numeric index of a positional argument.
      (str "format" "{1} was after {0}" 1 2) will evaluate to "2 was after 1"
      See Format String Syntax for a full description of various formatting options.
    • "index" "rindex"
      Similar to "(r)find", but raises ValueError if substring is not found.
    • "isalnum"
      Returns True if the given string is alphanumeric and not zero length.
    • "isalpha"
      Returns True if the given string is alphabetic and not zero length.
      Alphabetic characters are those defined in the Unicode database as "Letter".
    • "isdecimal"
      Returns True if all characters in the given string are decimal characters and there is at least one character.
    • "isdigit"
      Returns True if all characters in the given string are digits and there is at least one character.
    • "isidentifier" Returns True if the given string is a valid identifier according to the python language definition, section Identifiers and keywords.
    • "islower" "isupper"
      Returns True if all cased characters in the given string are lower- or uppercase and there is at least one character.
    • "isnumeric"
      Returns True if all characters in the given string are numeric characters, including all digit character and all character that have the Unicode numeric value property.
    • "isprintable"
      Returns True if all characters in the given string are printable or the string is empty.
    • "isspace"
      Returns True if all characters in the given string are whitespace and there is at least one character.
    • "istitle"
      Returns True if the given string is titlecased and non-empty.
    • "join"
      (str "join" string iterable)
      Returns a string which is the concatenation of the strings in the given iterable with the given string as separator.
      Note that every item of the iterable must be a string. If you wish to join non-string lists, consider using (str "join" separator (imap str iterable)).
    • "ljust" "rjust"
      (str "ljust" string width [fillchar])
      Returns the string, left- or right-justified inside a string of given width using the provided fillchar or spaces for padding.
    • "lstrip" "strip" "rstrip"
      (str "strip" string [characters])
      Returns a copy of string with leading, trailing or both characters removed.
      If omitted or None, characters default to whitespace.
      Keep in mind that characters is not a prefix but a string containing all characters to be removed.
    • "lower" "upper"
      Returns the lower- or uppercase version of the string.
    • "maketrans"
      (str "maketrans" from to [default])
      Returns a translation table usable for "translate" method.
      from and to arguments must be strings of equal length, which will result in each character of string from mapped to character of string to of same position.
      Equal to (dict (zip (imap ord from) to)).
    • "partition" "rpartition"
      (str "(r)partition" string separator)
      Splits the string at the first occurence of separator, returning a tuple of three items: the part before separator, the separator itself and the part after the separator.
    • "replace"
      (str "replace" string old new [count])
      Returns the string with first count or all instances of old substring replaced with new.
    • "split" rsplit
      (str "(r)split" string [separator [maxsplit]])
      Returns a list of the words in the string, separated from beginning or the end by the given separator up to maxsplit times.
      If separator is None, it defaults to whitespace. Otherwise, multiple instances of separator are interpreted as delimited empty words. Separator may be multiple symbols long.
    • "splitlines"
      (str "splitlines" string [keepends])
      Returns a list of the lines in the string, breaking at line boundaries.
      If keepends is True, the line boundaries are included.
    • "swapcase"
      Returns a copy of the string with uppercase characters converted to lowercase and vice versa.
    • "title"
      Returns a titlecased version of the string, where words start with an uppercase character followed by lowercase characters.
    • "translate"
      (str "translate" string table)
      Returns a copy of the string in which each character has been mapped through the given translation table.
      When indexed by a unicode ordinal (an integer), the table object can do any of the following: return a unicode ordinal or a string, to map the character to one or more other characters; or return None, to delete the character from the return string.
      You can use (str "maketrans") to create a fitting translation table.
      You may also use the simplified (transcode) function.
    • "zfill"
      (str "zfill" string width)
      Returns a copy of the string with ASCII "0" digits to make a string of length width. A leading sign prefix ("+"/"-") is handled by inserting the padding after the sign character rather than before. The original string is returned if width is less than or equal to (len string).
  • (transcode string transcoding) (transcode string from to)
    Returns a string with characters mapped according either to given transcoding or to the given from and to strings.
    Note that from and to strings must be equal length as each character of from will be mapped to a character in to.
    Avaliable transcodings include:
    • "rot13"
    • "circled"
    • "circled_neg"
    • "fwidth"
    • "mbold"
    • "mbolditalic"
    • "frakturbold"
    • "fraktur"
    • "scriptbold"
    • "script"
    • "sans"
    • "sansbold"
    • "sansbolditalic"
    • "sansitalic"
    • "parenthesized"
    • "doublestruck"
    • "region"
    • "squared"
    • "squared_neg"
    • "subscript"
    • "superscript"
    • "inverted"
    • "reversed"
    • "smallcaps"
    • "weird1"
    • "weird2"
    • "weird3"
    • "weird4"
    • "weird5"
    • "weird6"
    • "sbancient"

Regexp functions

See this site for more information about regular expressions. Select python flavour.

  • (resub pattern replace string)
    Searches for the regexp pattern in given string and replaces it with the replace pattern.
  • (rematch pattern string)
    Returns a match object or None if the pattern is not found in string.
  • (refindall pattern string)
    Returns a list of all instances of pattern found in string. If pattern consists of groups, returns a list of lists corresponding to said groups.

Random functions

Keep in mind that the python random library is not suited to be used in secure encryption.

  • (random)
    Returns a random float between 0 and 1.
  • (randint a b)
    Returns a random integer so that a <= result <= b.
  • (choice list [weights])
    Returns a randomly selected item from the given list, weighted if given a list of weights.
  • (ezchoice a ... b)
    Equal to (choice (list a ... b)).

Time functions

  • (eztime [format [offset]])
    Outputs time and date in given format, with given offset.
    If format is given, it's interpreted according to strftime format. Otherwise, it defaults to "%Y-%m-%d @ %H:%M:%S".
    Offset is interpreted as hours:minutes:seconds. Each part is optional: 3:: is a valid offset for a UTC+3 timezone.
  • (time)
    Returns the time in seconds since the epoch as a floating point number.

Discord specific functions

  • (delcall)
    Removes the message that called the custom command.
  • (hasrole a ... b)
    Returns true if the calling user has any of the specified roles. Roles are specified by name, case-insensitive.
  • (embed a ... b)
    Generates a discord embed with given arguments. Arguments must be passed in as ":key" "value" pairs. Any key value that is not reserved is added to the embed as a field. Note that in that case, the key must be within 256 symbols and the value - within 1024.
    Reserved key values include:
    • ":!title"
      Sets embed title, accepts a string.
    • ":!colour"/":!color"
      Sets embed colour. Accepts an integer or a hexadecimal string value.
    • ":!url"
      Sets the url for the title to lead to.
    • ":!thumbnail"
      Sets the thumbnail image (upper right corner). Requires a valid http(s) link to an image.
    • ":!image"
      Sets the embed image (bottom). Requires a valid http(s) link to an image.
    • ":!desc"/":!description"
      Sets the embed description. Description can handle hidden links in [text](link) format.

Discord specific variables

  • username
    Stores the account name of the user calling the custom command. (the part before the #).
  • usernick
    Stores the nickname of the user calling the custom command.
  • usermention
    Stores a string that mentions the user calling the custom command.
  • authorname
    Stores the name of the user who created the custom command.
  • authornick
    Stores the nickname of the user who created the custom command.
  • argstring
    Stores all the arguments given to the custom command as one string.
  • args
    Stores all the given arguments (split by spaces) in a list.
  • (args [index]) (args [from to])
    A helper function for safe reference to specific argument.
    If given no index, returns argstring.
    If given an index, returns args:index or None if no such index exists. If index is "*", returns args.
    If given two arguments, returns a slice of args, using "*" to select to end or from beginning.
  • _rsoutput
    Stores the output of the (print). Not recommended to use directly.

Math module functions

Number-theroretic and representation functions

  • (copysign x y)
    Returns magnitude of x with the sign of y.
  • (factorial x)
    Returns x factorial. X must be integer and non-negative.
  • (fmod x y)
    Returns (% x y), accurate for floating point numbers.
  • (frexp x)
    Returns the mantissa and exponent of x as the pair (m e). m is a float and e is an integer such that x = m * 2**e (or (== x (* m (** 2 e))) evaluates to True).
    This is used to "pick apart" the internal representation of a float in a aportable way.
  • (gcd x y)
    Returns the Greatest Common Divisor of the integers x and y.
  • (isclose x y)
    Returns True if x and y are close to one another.
  • (isfinite x)
    Returns True if x is neither an infinity nor a NaN and False otherwise.
  • (isinf x)
    Returns True if x is a positive or negative infinity and False otherwise.
  • (isnan)
    Returns True if x is NaN (Not a Number) and False otherwise.
  • (ldexp x i)
    Returns (* x (** 2 i)), essentially reversing (frexp).
  • (trunc x)
    Returns the Real value x truncated to an Integral (usually an integer).

Power and logarythmic functions

  • (exp x)
    Returns e raised to the power x. More accurate than (** e x) or (pow e x).
  • (expm1 x)
    Returns e raised to the power x, minus 1. For small floats x, the subtraction in (- (exp x) 1) can result in a significant loss of precision, which this function avoids.
  • (log x [base])
    Returns the logarythm of x to the given base or e.
  • (log1p)
    Returns the natural logarythm of 1+x (base e). The result is calculated in a way which is accurate for x near zero.
  • (log10 x)
    Returns the base-10 logarythm of x. This is usually more accurate than (log x 10).
  • (log2)
    Returns the base-2 logarythm of x. This is usually more accurate then (log x 2).
  • (pow x y)
    Returns x raised to the power of y. Use (** x y) for exact integer powers.
  • (sqrt x)
    Returns square root of x.

Trigonometric functions

  • (acos x)
    Returns the arc cosine of x, in radians.
  • (asin x)
    Returns the arc sine of x, in radians.
  • (atan x)
    Returns the arc tangent of x, in radians.
  • (atan2 x y)
    Retusns (atan x/y), in radians.
    The result is between -pi and pi. The vector in angle from the origin to point (x y) makes this angle with the positive X axis. The point of (atan2) is that the signs of both inputs are known to it, so it can compute the correct quadrant for the angle.
    For example, (atan 1) and (atan 1 1) are both pi/4, but (atan2 -1 -1) is -3*pi/4.
  • (cos x)
    Returns the cosine of x radians.
  • (hypot x y)
    Returns the Euclidean norm, (sqrt (+ (* x x) (* y y))). This is the length of the vector from the origin to point (x y).
  • (sin x)
    Returns the sine of x radians.
  • (tan x)
    Returns the tangent of x radians.

Angular conversion

  • (radians x)
    Convert the angle x from radians to degrees.
  • (degrees x)
    Convert the angle x from degrees to radians.

Hyperbolic functions

  • (acosh x)
    Returns the inverse hyperbolic cosine of x.
  • (asinh x)
    Returns the inverse hyperbolic sine of x.
  • (atanh x)
    Returns the inverse hyperbolic tangent of x.
  • (cosh x)
    Returns the hyperbolic cosine of x.
  • (sinh x)
    Returns the hyperbolic sine of x.
  • (tanh x)
    Returns the hyperbolic tangent of x.

Special functions

  • (erf x)
    Returns the error function at x.
    The (erf) function can be used to compute traditional statistical functions such as the cumulative standard normal distribution:
    (def phi (lambda (x) (/ (+ 1 (erf (/ x (sqrt 2)))) 2)))
  • (erfc x)
    Returns the complimentary error function at x. The complimentary error function is defined as (- 1 (erf x)). It is used for large values of x where a subtraction from one would cause a loss of significance.
  • (gamma x)
    Returns the [Gamma function](Convert angle x from radians to degrees.) at x.
  • (lgamma x)
    Returns the natural logarithm of the absolute value of the Gamma function at x.

Constants

  • pi
    The mathematical constant π = 3.141592…, to available precision.
  • e
    The mathematical constant e = 2.718281…, to available precision.
  • tau
    The mathematical constant τ = 6.283185…, to available precision.
    Tau is a circle constant equal to , the ratio of circle's circumference to it's radius.
    To learn more about Tau, check out Vi Hart's video Pi is (still) Wrong, and start celebrating Tau day by eating twice as much pie!
  • inf
    A floating-point positive infinity.
  • nan
    A floating-point "not a number" value.