Fairytale

From Esolang
Jump to navigation Jump to search
This is still a work in progress. It may be changed in the future.
This article is not detailed enough and needs to be expanded. Please help us by adding some more information.

Fairytale is an esoteric programming language created by User:Doubi. It is designed in a way, that the code can be a fairy tale at the same time. It is inspired by Rockstar.

Grammar

 Program               ::= Expression+
 Expression            ::= (Declaration / IfExpression / WhileExpression / UntilExpression / Assignment / PrintExpression / FunctionDeclaration / FunctionCall) Delimiter
 Declaration           ::= VariableName ("was" / "read" / "wrote") ValueExpression
 VariableName          ::= ("a" / "the" / "his" / "her" / "its" / "their" / "our")? ([a-z]/[A-Z] )+
 ValueExpression       ::= (Number Delimiter / String Delimiter / PoeticNumberLiteral)
 PoeticNumberLiteral   ::= ([a-zA-Z ]+ (',' [a-zA-Z ]+)? DelimiterNoComma
 Number                ::= ([0-9]+ ("." [0-9]+)? / [a-zA-Z ]+ / "empty" / "nothing")
 String                ::= """ Text* """
 IfExpression          ::= ("When" / "If") BooleanExpression "," Expression+ (ElseIfExpression)* (ElseExpression)? BlankLine
 WhileExpression       ::= ("While" / "As long as" / "During the time") BooleanExpression "," Expression+ BlankLine
 UntilExpression       ::= ("Until") BooleanExpression "," Expression+ BlankLine
 Assignment            ::= LeftHandValue ("was" / "was linke") RightHandValue Delimiter
 LeftHandValue         ::= VariableName
 RightHandValue        ::= (SumExpression / ProductExpression / DivisionExpression / SubtractionExpression / BooleanExpression / VariableName / ValueExpression)
 SumExpression         ::= RightHandValue ("with" / "plus" / "added to") RightHandValue
 ProductExpression     ::= RightHandValue ("times" / "of" / "multiplied by") RightHandValue
 DivisionExpression    ::= RightHandValue ("over" / "from" / "between / "divided by") RightHandValue
 SubtractionExpression ::= RightHandValue ("without" / "minus" / "subtracted from") RightHandValue
 BooleanExpression     ::= AndExpression / OrExpression / CompareExpression / VariableName / ValueExpression
 AndExpression         ::= BooleanExpression ("and", "and additionally") BooleanExpression
 OrExpression          ::= BooleanExpression ("or", "regardless", "even if") BooleanExpression
 CompareExpression     ::= RightHandValue "that"? ("was like" / "was smaller than" / "was larger than" / "was too large for" / "Was too strong for" / "Was stronger than" / "was too high for" / "was too small for" / "was too low for" / "was not like" / "was unlike" / "was the opposite of") RightHandValue
 ElseIfExpression      ::= ("otherwise when" / "otherwise if" / "else when" / "else if" / "or else when" / "Or else if" / "But now that" / "But as" / "But because") BooleanExpression ","
 ElseExpression        ::= ("otherwise" / "else" / "or else" / "but now" / "but") BooleanExpression
 Delimiter             ::= ("." / "," / "!" / "?")
 DelimiterNoComma      ::= ("." / "!" / "?")
 PrintExpression       ::= ((VariableName / Word) ("said" / "told" / "said to") (VariableName / Word)) ":" """ PrintStringExpression (Delimiter """ / """ Delimiter / Delimiter """ Delimiter)
 PrintStringExpression ::= (Text* (VariableName / I / you / am / are / "\" VariableName)*)*
 FunctionDeclaration   ::= "In " FunctionName "there"? ("was" / "were") ("nothing" / ParameterDeclarations) DelimiterNoComma (Expression / ReturnStatement)+ BlankLine
 ParameterDeclarations ::= VariableName / (VariableName ("and" / "or" / ",") ParameterDeclarations)
 ReturnStatement       ::= RightHandValue "returned" Text*
 FunctionCall          ::= ParameterAssignments ("went" / "walked" / "drove" / "flew") to FunctionName
 ParameterAssignments  ::= RightHandValue / RightHandValue "," ParameterAssignments

Specification

Variable Definition

Syntax

A variable name can contain any alphanumeric character, including white space, excluding the language's keywords. A variable declaration has the format:

 name "was"|"read"|"wrote" value

The value is defined the same way as in Rockstar: It can be a number (1, 5, 100, 7.5, 34.9876), a string ("Hello World", "", " ") or a "poetic number literal".

Poetic Number Literals

A poetic number literal is a text, getting converted to a number the following way:

  • The literal is read until the first DelimiterNoComma ('.', '?', or '!')
  • Each word represents a digit (separated by spaces only).
  • The digit is calculated by counting the number of letters in a word and filtering this with modulo 10.
  • A comma (',') character represents a decimal point.

Examples

 A was 10                                                     => A = 10
 Hans was 12.5                                                => Hans = 12.5
 The letter read "Dear Madam"                                 => The letter = "Dear Madam"
 The knight was very old, but that was not a problem for him. => The knight = 43.34331733

Print

Just print text:

 They said: "Hello World."
   -> Hello World.
 I said: "Hello World."
   -> Hello World.
 Asdfg said: "I don't like my name!"
   -> I don't like my name!

Print text containing the value of a variable:

The print function replaces all variable names in the string with their value.

 Hans was 10.
 I said: "Hans is a round number."
   -> 10 is a round number.
 Hans said: "Hans is ten."
   -> 10 is ten.

Print the name of a variable

To print the name of a variable you can either escape it with a backslash or put its name into the signal phrase and refer to it with "I" or "you", depending on where in the signal phrase it stands. Additionally, the words "am" and "are" are replaced with "is", if the corresponding part of the signal phrase is set.

 Hans was 10.
 Bob was 12.
 They said: "This is \Hans."
   -> This is Hans.
 Hans said: "This is I. Bob are you."
   -> This is Hans. 12 are you.
 Hans said to Bob "Are you Bob?"
   -> Is bob 12?
 Bob said to Hans: "Yes, I am Bob and you are Hans."
   -> Yes, Bob is 12 and Hans is 10.

Example

FizzBuzz:

 In a small town there were the king and the princess.
 While the king was higher than the princess regardless the king was like the princess,
 the king was linke the king without the princess.
 
 The king returned to the castle looking for her.
 
 Old was 100.
 The knight was lovestruck,
 his squire was fat.
 Their horse was slow.
 Until the knight was old,
   The knight was the knight and 1
   When the knight, his squire went to a small town that was empty and the knight, their horse went to a small town that was empty,
     They said: "FizzBuzz!"
   But when the knight, his squire went to a small town that was empty,
     They said: "Fizz!"
   But as the knight, their horse went to a small town that was empty,
     They said: "Buzz!"
   Otherwise The knight said: "I am the knight."
The same as one text:

In a small town there were the king and the princess. While the king was higher than the princess regardless the king was like the princess, the king was linke the king without the princess.

The king returned to the castle looking for her.

Old was 100. The knight was lovestruck, his squire was fat. Their horse was slow. Until the knight was old, the knight was the knight and 1. When the knight, his squire went to a small town that was empty and the knight, their horse went to a small town that was empty, they said: "FizzBuzz!" But when the knight, his squire went to a small town that was empty, they said: "Fizz!" But as the knight, their horse went to a small town that was empty, they said: "Buzz!" Otherwise The knight said: "I am the knight."

Output
 The knight is 1.
 The knight is 2.
 Fizz!
 Buzz!
 The knight is 5.

Translated Python code

Identifier names are different, for readability purposes.

   def mod(a,b):
       while a>b or a==b:
           a=a-b
       return a
   END=100
   i=0
   NUM_FIZZ=3
   NUM_BUZZ=4
   while i!=END:
       i=i+1
       if mod(i,NUM_FIZZ)==0 and mod(i,NUM_BUZZ)==0:
           print("FizzBuzz!")
       elif mod(i,NUM_FIZZ)==0:
           print("Fizz!")
       elif mod(i,NUM_BUZZ)==0:
           print("BUZZ!")
       else:
           print(f"The knight is {i}.")

References