NeverGonna
NeverGonna is an esoteric programming language that is designed to look like the famous song "Never Gonna Give You Up".
Syntax
To declare a variable named foo with the value of 2:
we're no strangers to foo gotta make foo 2
To make an if statement checking if foo == "orange", using a user input:
we're no strangers to foo gotta make foo your heart's been aching but you're too shy to say 'Please type in "orange"' -- get user input inside we both know foo == "orange" then -- if statement i just wanna tell you "You did it!" never gonna let you down -- else i just wanna tell you "You failed." never gonna give you up -- end
To add two numbers into a variable named bar:
we're no strangers to bar gotta make bar foo + 1
To make a for loop that prints the numbers 0 through 10:
we're no strangers to foo gotta make foo 0 we've known foo for 10 -- for loop i just wanna tell you foo never gonna give you up -- end for loop
To make a while loop
we're no strangers to foo we're no strangers to bar gotta make foo True a full commitment's what I'm thinking of foo -- while loop (while foo) gotta make bar your heart's been aching but you're too shy to say 'Please type in "orange"' inside we both know bar == "orange" then gotta make foo False never gonna turn around bar == "" then -- elif i just wanna tell you "You didn't type anything." never gonna let you down -- else i just wanna tell you "You didn't type orange." never gonna give you up never gonna give you up i just wanna tell you "You did it!"
The language's syntactical aspects shall be elucidated in an Extended Backus-Naur Form (EBNF) description:
program := { innerEmptyLine } , { innerCommandLine | innerEmptyLine } , [ lastCommandLine | lastEmptyLine ] ; innerEmptyLine := [ comment ] , newlines ; lastEmptyLine := [ comment ] ; innerCommandLine := statement , [ comment ] , newlines ; lastCommandLine := statement , [ comment ] ; comment := "--" , { character - newline } ; statementList := { statementListItem } ; statementListItem := { innerEmptyLine } , [ innerCommandLine ] , { innerEmptyLine } ; statement := varDeclaration | varAssignment | inputExpression | printCommand | ifStatement | forLoop | whileLoop ; varDeclaration := "we're no strangers to" , varName ; varAssignment := "gotta make" , varName , expression ; printCommand := "i just wanna tell you" , expression ; ifStatement := ifThenPart , newlines , { elseIfPart } , [ elsePart ] , endOfStatement ; ifThenPart := "inside we both know" , expression , "then" , newlines , statementList ; elseIfPart := "never gonna turn around" , expression , "then" , newlines , statementList ; elsePart := "never gonna let you down" , newlines , statmentList ; forLoop := "we've known" , varName , "for" , expression , newlines , statementList , newlines , endOfStatement ; whileLoop := "a full commitment's what I'm thinking of" , expression , newlines , statementList , newlines , endOfStatement ; endOfStatement := "never gonna give you up" ; expression := booleanValue | number | singleQuoteString | doubleQuoteString | varName | inputExpression | unaryOperator , expression | expression , binaryOperator , expression | expression , relationOperator , expression | "(" , expression , ")" ; inputExpression := "your heart's been aching but you're too shy to say" , expression ; unaryOperator := "+" | "-" | "!" ; binaryOperator := "+" | "-" | "*" | "/" | "%" | "^" | "&&" | "||" ; relationOperator := "==" | "!=" | "<" | "<=" | ">" | ">=" ; varName := varNameCharacter , { varNameCharacter } ; varNameCharacter := "a" | ... | "z" | "A" | ... | "Z" | "_" | digit ; booleanValue := "False" | "True" ; singleQuoteString := "'" , { character - "'" } , "'" ; doubleQuoteString := '"' , { character - '"' } , '"' ; number := [ "+" | "-" ] , digit , { digit } ; digit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; newline := "\n" ; newlines := newline , { newline } ; optionalNewlines := { newline } ;
Commands
The arithmetic sign and logical NOT operators intrine to form the unary operation set:
Operator | Operand | Effect |
---|---|---|
+
| ||
Boolean | invalid | |
integer | plus sign | |
string | invalid | |
-
| ||
Boolean | invalid | |
integer | minus sign | |
string | invalid | |
!
| ||
Boolean | logical NOT | |
integer | invalid | |
string | invalid |
The following binary operations, with respect to the possible operand type combinations, exist:
Operator | Left operand | Right operand | Effect |
---|---|---|---|
+
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | addition | |
integer | string | string concatenation | |
string | Boolean | invalid | |
string | integer | string concatenation | |
string | string | string concatenation | |
-
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | subtraction | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | invalid | |
*
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | multiplication | |
integer | string | string repetition | |
string | Boolean | invalid | |
string | integer | string repetition | |
string | string | invalid | |
/
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | division | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | invalid | |
%
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | remainder | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | invalid | |
^
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | exponentiation, power | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | invalid | |
&&
| |||
Boolean | Boolean | logical AND | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | invalid | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | invalid | |
||
| |||
Boolean | Boolean | logical OR | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | invalid | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | invalid | |
==
| |||
Boolean | Boolean | equality | |
Boolean | integer | equality | |
Boolean | string | equality | |
integer | Boolean | equality | |
integer | integer | equality | |
integer | string | equality | |
string | Boolean | equality | |
string | integer | equality | |
string | string | equality | |
!=
| |||
Boolean | Boolean | inequality | |
Boolean | integer | inequality | |
Boolean | string | inequality | |
integer | Boolean | inequality | |
integer | integer | inequality | |
integer | string | inequality | |
string | Boolean | inequality | |
string | integer | inequality | |
string | string | inequality | |
<
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | less than | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | less than (lexicographic) | |
<=
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | less than or equal to | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | less than or equal to (lexicographic) | |
>
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | greater than | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | greater than (lexicographic) | |
>=
| |||
Boolean | Boolean | invalid | |
Boolean | integer | invalid | |
Boolean | string | invalid | |
integer | Boolean | invalid | |
integer | integer | greater than or equal to | |
integer | string | invalid | |
string | Boolean | invalid | |
string | integer | invalid | |
string | string | greater than or equal to (lexicographic) |
Examples
Hello World
i just wanna tell you "Hello World"
FizzBuzz
we're no strangers to i gotta make i 0 we've known i for 100 inside we both know i % 15 == 0 then i just wanna tell you "FizzBuzz" never gonna turn around i % 3 == 0 then i just wanna tell you "Fizz" never gonna turn around i % 5 == 0 then i just wanna tell you "Buzz" never gonna let you down i just wanna tell you i never gonna give you up never gonna give you up
Truth-Machine
A truth-machine shall be demonstrated:
we're no strangers to yourInput gotta make yourInput your heart's been aching but you're too shy to say 'Please input 0 or 1' i just wanna tell you yourInput a full commitment's what I'm thinking of yourInput == 1 i just wanna tell you yourInput never gonna give you up
Looping Counter
This program counts from inclusive one (1) to inclusive 100, printing on each line a tally of asterisks (“*”) tantamount to the respective counter state:
we're no strangers to counter gotta make counter 1 we've known counter for 100 i just wanna tell you '*' * counter never gonna give you up
Cat Program
An infinitely repeating cat program is implemented as such:
a full commitment's what I'm thinking of True i just wanna tell you your heart's been aching but you're too shy to say 'Please input a character:' never gonna give you up
99 Bottles of Beer
The following program prints the lyrics of the song “99 Bottles of Beer”:
we're no strangers to number_of_bottles gotta make number_of_bottles 99 a full commitment's what I'm thinking of number_of_bottles > 0 inside we both know number_of_bottles > 2 then i just wanna tell you number_of_bottles + ' bottles of beer on the wall,' i just wanna tell you number_of_bottles + ' bottles of beer.' i just wanna tell you 'Take one down, pass it around,' i just wanna tell you number_of_bottles - 1 + ' bottles of beer on the wall.' i just wanna tell you never gonna turn around number_of_bottles == 2 then i just wanna tell you number_of_bottles + ' bottles of beer on the wall,' i just wanna tell you number_of_bottles + ' bottles of beer.' i just wanna tell you 'Take one down, pass it around,' i just wanna tell you number_of_bottles - 1 + ' bottle of beer on the wall.' i just wanna tell you never gonna let you down i just wanna tell you number_of_bottles + ' bottle of beer on the wall,' i just wanna tell you number_of_bottles + ' bottle of beer.' i just wanna tell you 'Take one down, pass it around,' i just wanna tell you 'No bottles of beer on the wall.' i just wanna tell you never gonna give you up gotta make number_of_bottles number_of_bottles - 1 never gonna give you up
Interpreter
- Common Lisp implementation of the NeverGonna programming language.
Computational class
It is easy to implement a 2 register minsky machine in NeverGonna, so it is Turing complete.