Roflkode is an imperative, block structured, statically-typed programming language that is very similar to Adam Lindsay's language LOLCODE.
The language is designed to be implementable by small teams of undergraduate students in a single semester. Therefore it subsets LOLCODE in places; for example, it does not do interpolation within strings. In addition, in order to address some "interesting" aspects of compiler construction, it deviates from LOLCODE by adopting static typing, infix operators, operator precedence, and bracketing for array, bucket, and call expressions (!!!! 0_0 SIAS 0_0 !!!!).
This document defines the language Roflkode.
The source of a Roflkode program is a Unicode string. A lexically valid Roflkode program is a string that can be tokenized according to the usual "longest substring" rule, with comments and whitespace allowed to separate tokens. Whitespace is text matching the regex
[ \t]+and a comment is text matching
BTW[^\r\n\x85\u2028\u2029]*
This precludes any identifier from starting with BTW.
The Roflkode tokens are identifiers (id), reserved words, symbols, integer literals (intlit), number literals (numlit), string literals (strlit), character literals (charlit), and breaks (br). Identifiers are nonempty strings of letters (Unicode properties Lu, Ll, Lt, Lm, Lo) and decimal digits (Unicode property Nd) beginning with a letter, except for the reserved words. The reserved words and symbols can be inferred from the macrosyntax in the following section; the reserved words are the ones in ALL CAPS.
Identifiers and reserved words are case sensitive.
Integer literals are described with the regular expression
-?\d+
and number literals with:
-?\d+\.\d+([Ee][+-]?\d+)?
String literals are sequences of zero or more non-control characters or escape sequences, delimited by double quotes (U+0022). The escape sequences are:
Sequence | Meaning |
---|---|
:) | the newline character (U+000A) |
:> | the tab character (U+0009) |
:" | the double quote character (U+0022) |
:' | the single quote character (U+0027) |
:: | the colon character (U+003A) |
:( h) |
where h is a one to six character string of hexadecimal digits; this escape sequence stands for a character whose codepoint is the value of the hex string. |
A character literal is a non-control character or escape sequence surrounded by single quotes (U+0027).
The br token is defined by the regex
,|[\r\n\x85\u2028\u2029]
In other words, a br is generally a line end, but it can also be a comma for those cases when the programmer would like to pack extra code on a single line.
A syntactically valid Roflkode program is one that is lexically
valid and whose tokenization is derivable from the following grammar,
presented in an EBNF variant. Here the vertical bar
denotes alternatives, the question mark means optional, Kleene
star denotes zero or more, Kleene plus denotes one or more, and parentheses
are used for grouping. Symbols appear in single quotes.
Reserved words are shown here in all uppercase and are not quoted.
The start symbol is script
. The tokens intlit
,
numlit
, strlit
, charlit
, and br
are
defined above in the section on microsyntax.
script → br* HAI br+ import* stmt+ KTHXBYE br* import → CAN HAS id '?' br+ stmt → (dec | simplestmt modifier? | complexstmt) br+ dec → vardec | typedec | fundec vardec → I HAS A type? id (ITZ 4EVER? exp)? type → B00L | KAR | INT | NUMBR | YARN | id | type LIST typedec → TEH BUKKIT UV br* (type id br*)* AKA id fundec → I CAN (MAEK type)? id params? br+ stmt+ SRSLY | THEM CAN (MAEK type)? id params? params → WIF? UR type id (AN type id)* simplestmt → YO exp+ | FACEPALM exp+ | UPZORZ var | NERFZORZ var | var R exp | GTFO id | HWGA id? | HEREZ UR exp | DIAF exp? | GIMMEH var | BRB exp | id args modifier → (IF | CEPT IF | WHIEL | TIL) exp complexstmt → conditional | switch | loop | try conditional → exp '?' br+ WERD br+ stmt+ (MEBBE exp br* stmt+)* (NO WAI br* stmt+)? OIC switch → exp WTF '?' br+ (OMG literal br+ stmt+)+ OMGWTF br+ stmt+ OIC loop → IM IN UR id loopcontrol? br+ stmt+ LOL loopcontrol → (WHIEL | TIL) exp | (UPPIN | NERFIN) id (FROM exp TO exp | THRU exp) try → PLZ simplestmt br+ AWSUM THX br+ stmt+ O NOES br+ stmt+ MKAY exp → exp1 (ORELSE exp1)* exp1 → exp2 (ANALSO exp2)* exp2 → exp3 (BITOR exp)* exp3 → exp4 (BITXOR exp4)* exp4 → exp5 (BITAND exp5)* exp5 → exp6 (relop exp6)? exp6 → exp7 (shiftop exp7)* exp7 → exp8 (addop exp8)* exp8 → exp9 (mulop exp9)* exp9 → prefixop? exp10 exp10 → literal | var | id '<:' exp* ':>' | '[:' exp* ':]' | '(' exp* ')' literal → N00B | WIN | FAIL | intlit | numlit | charlit | stringlit var → id args? ('!?' exp '?!' | '!!!' id)* args → '(:' exp* ':)' relop → PWNS | PWNED BY | SAEM AS | PWNS OR SAEM AS | PWNED BY OR SAEM AS | DIVIDZ shiftop → BITZLEFT | BITZRIGHT addop → UP | NERF | '~~' mulop → TIEMZ | OVR | LEFTOVR prefixop → NAA | BITZFLIP | SIEZ UV | B00LZOR | INTZOR | NUMZOR | KARZOR | YARNZOR
A script is a sequence of zero or more imports followed by one or more statements, all bracketed by HAI and KTHXBYE. Some statements, called declaration statements, declare entities (types, variables, and functions); others simply execute.
BTW This is a pretty interesting Roflkode program. BTW It writes "hello, world" to standard output. HAI I HAS A YARN place ITZ "world" YO greet (: place :) I CAN MAEK YARN greet WIF UR YARN s HEREZ UR "hello, " ~~ s SRSLY KTHXBYE
An import is replaced with the contents of the named module at compile time.
CAN HAS module?
When compiled, the import is replaced with the contents of module and the module is compiled in place. All Roflkode implementations must have the standard modules defined in Section 4. If module is not the name of a standard module, then the module is fetched in some implementation dependent way — perhaps the module is contained in a file called module.rk.
In other words, the import acts like the #include directive in C — it brings in source code, not an intermediate compiled form.
A declaration binds an identifier to an entity. There are seven kinds of declarations:
Each occurrence of an identifier is either a defining occurrence or a using occurrence. Using occurrences are legal only in the visible region of the declaration that declares the identifier. The visible region of a declaration is the declaration's scope minus any holes in the scope created by declarations of identifiers with the same name within (inner) scopes nested within.
This means the visible region may be discontinuous.
This allows types and functions to be mutually recursive.
All of the declared identifiers that are part of the same statement sequence must be mutually distinct. Here "part of the same statement sequence" does not refer to any mixing of sequences with those nested inside of them.
HAI I HAS A NUMBR x I HAS A NUMBR x BTW error IM IN UR house I HAS A NUMBR x BTW this is okay, diff from "outer" x GTFO house LOL KTHXBYE
Declarations within inner statement sequences hide declarations with the same name in an enclosing outer ones.
The identifiers declared as parameters of a function must be unique among themselves and the identifiers declared at the top level of the function's body.
I CAN bat UR INT x AN INT y I HAS A NUMBR z I HAS A YARN x BTW error - x is already a parameter z PWNS 1.0? WERD I HAS A INT x ITZ 5 BTW this x is fine, however OIC SRSLY
The types INT and NUMBR are arithmetic types. The arithmetic types and the type KAR comprise the primitive types. Types that are not primitive types are called reference types.
Bukkit types must be declared. Examples of bukkit type declarations:
TEH BUKKIT UV NUMBR x NUMBR y AKA point
TEH BUKKIT UV YARN brand INT size NUMBR price YARN LIST colors B00L used AKA dress
A function has a name, an optional return type, a parameter list, and a body. The identifiers declared as parameters must all be unique. Functions without a return type in their declarations are called "void functions" or "procedures."
The signature of a function is a pair (t0, [t1, ..., tn]) where t0 is either the return type of the function or the string "void", and t1 through tn are, in order, the types of the parameters.
An expression list (e1, ..., en) is said to match a signature (t0, [t1, ..., tk]) whenever it holds that
Note that the return type has no effect on the definition of matching.
A variable is something that stores a value. Roflkode is a statically-typed language so all variables also have a type. Variables are either writable or not writable.
Variables are declared in a variable declaration or as a parameter declaration inside a function declaration. A variable declaration gives the variable name and optionally a type and an initializing expression. The initializing expression is always optional; the type my be omitted only if the type may be unambiguously inferred from the initializing expression.
I HAS A INT count ITZ 508
I HAS A NUMBR height BTW ok, height initially undefined
I HAS A weight ITZ 140 BTW ok, weight has type INT
I HAS A p ITZ point <: 3 9 :> BTW ok, p has type point
I HAS A v ITZ [: 3 1.0 8 2 :] BTW ok, v has type NUMBR LIST
I HAS A cheezburger BTW error - no can infer the type
I HAS A x ITZ x BTW error - no can infer the type here either
Parameter declarations must always have a type so there is no need to worry about inference in those cases.
The kinds of variable expressions used in referencing occurrences are:
i
(Simple variable)
Here i is a simple identifier with the
same name as an identifier declared in a visible variable declaration,
parameter declaration, or iterator declaration. (Notice that types, functions,
properties, and loops are not variables!) The type of this variable
is the type given the identifier in the innermost visible declaration.
It is writable unless it refers to an interator or is marked
4EVER
in its declaration.
v!?e?!
(Index variable) Here v is a variable of an array type or the YARN (string) type and e is an expression of type INT. The type of this variable is v's base type if v is an array, or KAR if a string. This variable is the array component or character at (zero-based) index e, and is writable unless v is a string. (Note: strings are immutable.) If during execution v is N00B, the string "N00BZORED" is thrown. If e evaluates to a value less than zero or greater than or equal to the length of v, the string "OUT_UV_BOWNDZ" is thrown.
I HAS A arr ITZ [: 3 6.2 9 :] YO arr !? 0 ?! BTW prints 3 YO arr !? 1 ?! BTW prints 6.2 YO arr !? 2 ?! BTW prints 9 YO "Bangarang" !? 7 ?! BTW prints 'n' YO arr !? -3 ?! BTW throws exception
v!!!p
(Property variable) Here v is a variable of a bukkit type and f must be an identifier declared as a property of v's type. This variable refers to the p-property of the object referred to by v. The type of this variable is the type associated with the property p, and is writable. If during execution v is N00B, the string "N00BZORED" is thrown.
TEH BUKKIT UV INT x INT y AKA point I HAS A p ITZ point <: 2 4 :> YO p!!!x BTW prints 2 YO p!!!y BTW prints 4
i (: e1 ... en :)
(Function call expression) Here the identifier i must name a function whose signature is matched by the argument list e1 through en. It is an error if the function was decared without a return type. First, each expression is evaluated in any order. Then i is called with the arguments copied to the parameters and the entire variable refers to the result of calling the function, and has the type of the function. The variable itself is not writable.
HAI CAN HAS txt? I HAS A message ITZ "howareyoutoday?" YO slice (: message 3 6 :) BTW prints "areyou" YO slice (: message 3 8 :) !? 2 ?! BTW prints 'e' slice(:message 3 8:)!?2?! R 'f' BTW okay to assign this slice(:message 3 8:) R 'x' BTW won't compile: Not writable!
A statement is code that is executed solely for its side effect; it produces no value.
UPZORZ v
(Increment statement) v must have type INT. Increments v.
NERFZORZ v
(Decrement statement) v must have type INT. Decrements v.
GTFO n
(Get-out statement) This statement may only appear within a loop named n that is not outside of the innermost enclosing function (if any) of the statement, or have its innermost enclosing function be a procedure (a function with no parameters) named n. If n names a loop, the statement terminates the execution of loop n; otherwise, it immediately exits the procedure.
HWGA
(Here-we-go-again statement) This statement may only appear within a loop that is not outside of the innermost enclosing function (if any) of the statement. It terminates the current iteration of the innermost enclosing loop statement.
HWGA n
(Labeled here-we-go-again statement) This statement may only appear within a loop named n that is not outside of the innermost enclosing function (if any) of the statement. It terminates the current iteration of the loop named n.
HEREZ UR e
(Return statement) Evaluates e then causes the innermost enclosing function to immediately return the value of e. The function must have been declared with a return type, and e must be type compatible with the return type.
DIAF e
(Die statement) Evaluates e, which must have the type YARN, and throws e.
YO e1 ... en
(Print statement) Evaluates each ei in order and prints the string representation of each to standard output.
FACEPALM e1 ... en
(Print error statement) Evaluates each ei in order and prints the string representation of each to standard error.
GIMMEH v
(Read statement) v must be a writable variable in scope. Reads from standard input into v. If v has string type then reads as much of standard input as it can up to and including the next line ending character (or characters). If v has KAR type then reads the next character from standard input. If v has a numeric type then reads as much a possible that parses as a value of the actual type; if the next characters to be read cannot be parsed as a number, throws "NO_SEE_NUMBR". If v is a B00L variable then reads the next character and produces WIN if the character matches the regex [1WwTtYy] or FAIL if the character matches [0FfNn] else throws "NO_SEE_B00L". If no characters can be read, throws "NO_MOAR_INPUT".
BRB e
(Be-right-back statement) Evaluates e which must have numeric type. Makes the current thread sleep for e seconds. The amount of time the thread actually sleeps is dependent on the resolution of the underlying operating system's timer.
v R e
(Assignment statement) e must be type compatible with the type of v. v is determined and e is evaluated, then the value of e is copied into v.
f (: e1 ... en :)
(Procedure call statement) f must name a function whose signature is matched by the argument list e1 through en, and be the only visible function that is so matched. Each expression is evaluated in any order and the function f is called with the arguments copied to the parameters. The function must have been declared with no return type.
s IF e
e must have type B00L. Evaluates e, then, only if it evaluated to WIN, executes s.
s CEPT IF e
e must have type B00L. Evaluates e, then, only if it evaluated to FAIL, executes s.
s WHIEL e
Evaluates e, which must have type B00L, then, only if it evaluated to WIN, executes s then executes the entire statement again.
s TIL e
Executes s, which must have type B00L, then evaluates e. It the evaluation produces WIN, the entire statement completes. Otherwise it is executed again.
e1?, WERD, b1, MEBBE e2, b2, MEBBE e3, b3, ... NO WAI, bn OIC
(Conditional statement) Each ei must have type B00L. Each ei is evaluated in order from left to right until one of them is true or they have all been evaluated. If any of the ei's evaluate to true the corresponding bi is executed, completing the execution of the conditional-statement. If none of the ei's evaluate to true, bn is executed (if it exists).
e WTF?, OMG e1, b1, OMG e2, b2, ... OMGWTF, bn OIC
(Switch statement) Evaluates e then checks its value against each of the ei's in order until it is equal, then executes the corresponding block, thereby completing the statement. If none of the ei's match, bn is executed (if it exists).
IM IN UR p, b, LOL
(Loop statement)
Repeatedly executes b. This loop is intended to be broken out of only by
a GTFO
, a DIAF
, or by an exception being thrown somewhere
in the body.
IM IN UR p WHIEL e, b, LOL
(While statement). Evaluates e, which must have type B00L. If e evaluates to WIN, Executes b and then executes the entire while-statement again. If e evaluates to FAIL, the statement completes.
IM IN UR p TIL e, b, LOL
(Until statement). Executes b. Then evaluates e, which must have type B00L. If e evaluates to WIN, Executes the whole until-statement again. If e evaluates to FAIL, the statement completes.
IM IN UR p UPPIN i THRU a, b, LOL
(Array iteration statement) a must be an expression with an array type. This statement declares a new variable i whose scope is b. It executes b once for each value of i in a from the first element to the last. The expression a is evaluated only once, at the beginning of the execution of the for statement. The variable i is not writable.
IM IN UR p NERFIN i THRU a, b, LOL
(Reverse array iteration statement) a must be an expression with an array type. This statement declares a new variable i whose scope is b. It executes b once for each value of i in a from the last element to the first. The expression a is evaluated only once, at the beginning of the execution of the for statement. The variable i is not writable.
IM IN UR p UPPIN i FROM e1 TO e2, b, LOL
(Range iteration statement) e1 and e2 must both have type INT. First these two expressions are evaluated, then a new variable i whose scope is b is declared. The statement executes b once for each value of i in the (now fixed) integer range e1...e2, starting at e1 and ending at e2 Note that if e1>e2 the range is empty and the body is never executed. The variable i is not writable.
IM IN UR p NERFIN i FROM e1 TO e2, b, LOL
(Reverse range iteration statement) e1 and e2 must both have type INT. First these two expressions are evaluated, then a new variable i whose scope is b is declared. The statement executes b once for each value of i in the (now fixed) integer range e1...e2, starting at e2 and going down to e1. Note that if e1>e2 the range is empty and the body is never executed. The variable i is not writable.
Each expression has a type and a value. The value of an expression with a reference type is either N00B or a reference to an object. Arrays and bukkits are therefore never manipulated directly, but only through references.
An expression e is type-compatible with a type t if and only if
An expression of type INT can appear anywhere an expression of type NUMBR is expected; in this case the integer value is implicitly converted to one of type NUMBR. The conversion must maintain the expression's value; this is always possible since the type NUMBR has 53 bits of precision.
The Roflkode expressions are:
WIN
The literal of type B00L denoting truth.
FAIL
The literal of type B00L denoting falsity.
N00B
A literal representing a reference to no object, and whose value is the sole value of the null type.
v
A variable: The type of this expression is the type of the variable v, and the value of this expression is the current value stored in v.
(e)
Evaluates e and produces this value.
[: e1 ... en :]
(Array object) This is an array expression whose values are each of the ei's evaluated in order from left to right.
i <: e1 ... en :>
(Bukkit expression) Here the identifier i must be the name of a bukkit type which is in scope. The ei's evaluated in order from left to right and their values are set as the properties on a new bukkit of type i, in the order given.
NAA e
e must have type B00L. If e evaluates to WIN, the entire expression produces FAIL, otherwise it produces WIN. This operator is pronounced "not at all".
BITZFLIP e
e must have type INT. Evaluates e and produces the bitwise complement of e.
SIEZ UV e
e must be an array or a string. Produces the number of items if an array, or the number of characters if a string.
I HAS A INT x ITZ SIEZ UV "dog" BTW x is now 3 I HAS A INTZ primes ITZ [: 2 3 5 7 11 :] x R SIEZ UV primes BTW x is now 5 I HAS A YARN s ITZ "" x R SIEZ UV s BTW x is now 0
B00LZOR x
Produces FAIL if x is N00B or FAIL. Otherwise produces WIN.
KARZOR i
i must have type INT. Produces the character whose codepoint is i.
INTZOR x
x must be have type KAR, INT, NUMBR, or YARN. If x has type KAR then produces the codepoint of x. If x has type INT then produces the value of x. If x has type NUMBR then produces the truncation of x. If x is a YARN that is the string value of an integer returns that integer, but if the yarn is not the string value of an integer then throws "NO_SEE_INT".
YO INTZOR '4' BTW prints 52 YO INTZOR "4" BTW prints 4 YO INTZOR -89.9453 BTW prints -89
NUMZOR e
e must be have type NUMBR, INT, or YARN. If a NUMBR then the value of e is produced; if an INT, then the value of e as a floating point value is produced. If x is a YARN that is the string value of an number returns that number, but if the yarn is not the string value of an number then throws "NO_SEE_NUMBR".
YARNZOR e
e can be any expression
whatsoever. Produces a string representation of its
argument. For INTs, KARs, NUMBRs and YARNs the produced
string is identical to the output of C's printf
with the
%d, %c, %g and %s format specifiers, respectively.
For B00Ls, the produced string is either "WIN" or
"FAIL". Arrays and bukkits produce JSON strings and
apply YARNZOR recursively. (This implies that
self-referential arrays will generate infinite strings thus causing a
stack overflow error on most machines, but that will be considered
the programmer's fault.). N00B produces "N00B".
e1 TIEMZ e2
Either both subexpressions must have arithmetic type, or e1 must have string type and e2 have type int. In the former case, the subexpressions are evaluated in any order and their product is produced. In the latter, the subexpressions are evaluated in any order and the entire expression produces the string which is e2 copies of e1 concatenated together.
e1 OVR e2
Each subexpression must have an arithmetic type. Both expressions are evaluated, in any order, and the entire expression produces the quotient of e1 divided by e2. The type of the quotient is NUMBR only if either operand is NUMBR, otherwise the type is INT.
e1 LEFTOVR e2
Both subexpressions must have type INT. Both expressions are evaluated, in any order, and the entire expression produces an INT which is the modulo of e1 and e2.
e1 UP e2
Both subexpressions must have arithmetic type. Evaluates the subexpressions in any order, then produces the sum of e1 and e2.
e1 NERF e2
Both subexpressions must have arithmetic type. Evaluates the subexpressions in any order, then produces the difference of e1 and e2.
e1 ~~ e2
Both subexpressions must be strings or arrays. Evaluates the subexpressions in any order, then produces the concatenation of e1 and e2.
e1 BITZLEFT e2
Each subexpression must have type INT. Produces the value of e1 shifted left e2 positions.
e1 BITZRIGHT e2
Each subexpression must have type INT. Produces the value of e1 arithmetically shifted right e2 positions.
e1 SAEM AS e2
e1 must be type-compatible with the type of e2, or e2 must be type compatible with the type of e1; however, neither expression can be a array or a bukkit. The subexpressions are evaluated in any order, and the entire expression produces whether these values are the same, taking into account any necessary promotions of INT values to NUMBR values where necessary.
e1 PWNS e2
Each subexpression must have arithmetic type, or must both be chars, or both must be strings. Both expressions are evaluated, in any order, and the entire expression produces whether the value of e1 is greater than the value of e2.
e1 PWNED BY e2
Each subexpression must have arithmetic type, or must both be chars, or both must be strings. Both expressions are evaluated, in any order, and the entire expression produces whether the value of e1 is less than the value of e2.
e1 PWNS OR SAEM AS e2
Each subexpression must have arithmetic type, or must both be chars, or both must be strings. Both expressions are evaluated, in any order, and the entire expression produces whether the value of e1 is greater than or equal to the value of e2.
e1 PWNED BY OR SAEM AS e2
Each subexpression must have arithmetic type, or must both be chars, or both must be strings. Both expressions are evaluated, in any order, and the entire expression produces whether the value of e1 is less than or equal to the value of e2.
e1 DIVIDZ e2
Both subexpressions must have type INT. Both expressions are evaluated, in any order, and the entire expression produces an B00L stating whether e1 evenly divides e2.
e1 BITAND e2
Each subexpression must have type INT. Both expressions are evaluated, in any order, and the entire expression produces an INT which is the bitwise and of e1 and e2.
e1 BITXOR e2
Each subexpression must have type INT. Both expressions are evaluated, in any order, and the entire expression produces an INT which is the bitwise exclusive or of e1 and e2.
e1 BITOR e2
Each subexpression must have type INT. Both expressions are evaluated, in any order, and the entire expression produces an INT which is the bitwise inclusive or of e1 and e2.
e1 ANALSO e2
Each subexpression must have type B00L. First e1 is evaluated. If it evaluates to FAIL, the entire expression immediately produces FAIL (without evaluating e2). Otherwise e2 is evaluated and the entire expression produces the value of e2.
e1 ORELSE e2
Each subexpression must have type B00L. First e1 is evaluated. If it evaluates to WIN, the entire expression immediately produces WIN (without evaluating e2). Otherwise e2 is evaluated and the entire expression produces the value of e2.
The following modules are officially a part of the Roflkode language, and must therefore be included in all implementations.
The tiem
library contains various operations for working with
dates and times.
THEM CAN MAEK INT nao BTW The number of milliseconds since the epoch. THEM CAN MAEK INT tmrw BTW The number of milliseconds since the epoch for midnight tomorrow BTW (in whatever timezone the agent is set to). THEM CAN MAEK YARN date WIF UR INT epochtime AN INT tzoffset BTW Returns a (proleptic) ISO 8601 date string for the timestamp BTW epochtime using the time zone offset tzoffset
The maf
library contains various mathematical constants and functions.
BTW This is the standard Roflkode maf library. THEM CAN MAEK NUMBR sqrt WIF UR NUMBR x BTW Returns the square root of x. I HAS A NUMBR pi ITZ 4EVER acos -1.0 BTW Convenient constant for π. THEM CAN MAEK NUMBR sin WIF UR NUMBR x BTW Returns the sine of x. THEM CAN MAEK NUMBR cos WIF UR NUMBR x BTW Returns the cosine of x. THEM CAN MAEK NUMBR acos WIF UR NUMBR x BTW Returns the arc cosine of x (might be NaN). THEM CAN MAEK NUMBR atan WIF UR NUMBR x AN NUMBR y BTW Returns the arctangent of the angle between the positive x-axis BTW and the line from the origin to (x,y) THEM CAN MAEK NUMBR ln WIF UR NUMBR x BTW Returns the natural log of x. THEM CAN MAEK INT confuzzle WIF UR INT x BTW Returns a random int between 0 (inclusive) and x (exclusive).
Usage examples:
HAI CAN HAS maf? YO sqrt(:400:) BTW 20 YO pi BTW 3.141592653589793 YO sin(:-0.3:) BTW -0.29552020666133955 YO cos(:2:) BTW -0.4161468365471424 YO acos(:0.5:) BTW 1.0471975511965976 YO atan(:5 -12:) BTW 0.3947911196997615 YO atan(:4 0:) BTW 1.5707963267948966 YO ln(:142341394:) BTW 18.77373891323974 YO confuzzle(:6:) BTW could be 0, 1, 2, 3, 4, or 5 KTHXBYE
The txt
library contains functions that operate on text strings.
THEM CAN MAEK YARN lc WIF UR YARN s BTW Returns the lower case version of s. THEM CAN MAEK YARN uc WIF UR YARN s BTW Returns the upper case version of s. THEM CAN MAEK INT pos WIF UR YARN s AN KAR c BTW Returns the leftmost position of c in s, or -1 if c does not appear in s. THEM CAN MAEK YARN slice WIF UR YARN s AN INT start AN INT length BTW Returns the slice (substring) of s from position start that BTW contains (at most) length characters.
Usage examples:
HAI CAN HAS txt? YO lc (: "CheezBurger" :) BTW "cheezburger" YO uc (: "cheezBuRGER" :) BTW "CHEEZBURGER" YO pos (: "kthxbye" 'x' :) BTW 3 YO pos (: "random" 'w' :) BTW -1 YO slice (: "ROTFLMAO" 2 5 :) BTW "TFLMA" YO slice (: "ROTFLMAO" 4 20 :) BTW "LMAO" KTHXBYE
The following are planned for Roflkode 2: