译者 | 薛命灯
Rockstar 是一门图灵完备的动态编程语言。设计这门语言的目的是能够像写歌词一样开发计算机程序。它的歌词风格主要受 20 世纪 80 年代重摇滚和电力民谣的影响。
为什么会有 Rockstar?
如果我们让 Rockstar 成为一门真正的(虽然毫无意义)编程语言,招聘人员就不会在招聘时对“摇滚开发者”颇有微词。
另外,它很有趣,一门基于歌词编译的编程语言很值得我们一试。
我们还可以用它做贴纸,谁不想在自己的笔记本电脑上贴上“认证 Rockstar 开发者”这样的贴纸呢?
Rockstar 语言规范
注释
我们不建议在 Rockstar 程序中使用注释。这可是 Rockstar,所以要让阅读代码的人自己从中寻找意义。但如果你坚持要使用注释,那么请把注释放在括号里。是的,这意味着你不能在算术表达式中使用括号,如果有复杂的表达式,要将它们分解为多个子句。
Tommy was a lean mean wrecking machine. (initialises Tommy with the value 14487)
变量
在 Rockstar 中,有两种声明和使用变量的方式。
公共变量由一个关键字(a、an、the、my 或 your)和关键字后面的变量名组成,变量名只能包含小写 ASCII 字母 a-z。
特定变量由专有名词组成,专有名词是指任何不是保留关键字并以大写字母开头的单词。特定变量名称可以包含空格,只要每个空格后跟一个大写字母。可能有一些开发人员会创建类似 Customer ID、Tax Rate 或 Distance In KM 这样的变量名称,不过我们建议你使用惯用的变量名称,如 Tommy、Gina、Doctor Feelgood、Mister Crowley、Kayleigh、Tom Sawyer、Billie Jean 和 Janie。
Eleanor Rigby、Peggy Sue、Black Betty、Layla 和 Johnny B Goode 在 Rockstar 中也都是有效的变量名,尽管严格来说它们算不上是惯用的。
与 Ruby、Python 和 VBScript 一样,Rockstar 的变量是动态类型的,所以不需要在使用前进行声明。
代词
关键词 it、he、she、him、her、them、they 总是指向最近命名的变量。
类型
Rockstar 使用了与 ECMAScript 非常相似的类型系统,不过 undefined 听起来不是非常摇滚,所以我们使用 mysterious 替代它。
Mysterious——任何未赋值的变量,使用关键字 mysterious 表示。
——空值类型,在计算时等于 0 或 false。关键字 nothing、nowhere 和 nobody 是 的别名。
Boolean——具有 true 和 false 值的逻辑实体。(关键字 maybe 和 definitely maybe 被保留下来,可能在未来会用到)。
right、yes 和 ok 是 true 的有效别名。
wrong、no 和 lies 是 false 的有效别名。
Number——Rockstar 中的数字使用 DEC64 数字类型进行存储。
String——Rockstar 中的字符串是 16 位无符号整数值的序列。
Object——数据属性的集合,与 ECMAScript 一样。
字面量和赋值
Rockstar 中的字符串字面量使用双引号括起来。
“Hello World”
Rockstar 中的单引号被视为普通的字母。这似乎有点不寻常,直到你想起来 ain't talkin’ 'bout love 在摇滚中其实是一句完美有效的歌词。
Rockstar 中的数字字面量是十进制数字。
123
3.141592654
赋值使用 put/into 关键字组合:
Put 123 into X 表示将 123 赋值给变量 X。
Put “Hello World” into the message 表示将“Hello World”赋值给 the message 变量。
递增和递减
我们分别使用 Build {variable} up 和 Knock {variable} down 关键字进行递增和递减。
Build my world up 将会让 my world 的值增加 1。
Knock the walls down 将会让 the walls 的值减 1
算术
基本的算术运算使用 plus、minus、times、over 和 by 关键字。
算术表达式:
plus {b}——加法,别名为 with。
minus {b}——减法,别名为 without。
times {b}——乘法,别名为 of。
over {b}——除法,别名为 by。
例子:
Put the whole of your heart into my hands——把 your heart 和 the whole 相乘,并把结果赋值给 my hands。
My world is nothing without your love——将零减去 your love,并将结果赋值给 my world。
If the tears of a child is nothing——检查 the tears 乘以 a child 是否等于零。
My love by your eyes——返回 my love 除以 your eyes 的值。
诗意字面量
Rockstar 还支持一种独特的语言特性,称为诗意字面量(poetic literal)。受 here-document 语法的启发,诗意字面量允许程序员在初始化变量的同时表达他们内心深处的焦灼。
诗意类型字面量
在使用关键字 true、false、nothing、nobody 和 nothing 进行赋值时,使用单行代码,包括变量名、is 关键字和字面量。
My heart is true——使用布尔值 true 来初始化 my heart。
Tommy is nobody——使用 nobody 别名将 Tommy 的值初始化为 。
诗意字符串字面量
在进行诗意字符串字面量赋值时,以变量名作为开头,后面跟一个关键字(如 Says),然后再跟上一个空格。剩余部分(直到碰到\n 终止符)被视为不带引号的字符串字面量。
Billy says hello world!\n 表示使用字符串字面量 hello world! 来初始化 Billy。
The world says hello back\n 表示使用字符串字面量 hello back 来初始化 the world。
诗意数字字面量
在进行诗意数字字面量赋值时,以变量名作为开头,后面跟上关键字 is,或者别名 was 或 were。只要下一个符号不是保留关键字,这一行的其余部分将被视为一个十进制数,这个数由连续出现的字符串长度对应的数字组成。为了表示数字零,也为了弥补摇滚中缺少单字母单词和双字母单词,单词长度需要对 10 取模。句点(.)表示小数位。除第一个句点外,任何非字母字符都将被忽略。
Tommy was a lovestruck ladykiller 表示使用 100 来初始化 Tommy。
Sweet Lucy was a dancer 表示使用 16 初始化 Sweet Lucy。
A killer is on the loose 表示使用 235 初始化 a killer。
My dreams were ice. A life unfulfilled; wakin' everybody up, taking booze and pills 表示使用 3.1415926535 初始化 my dreams。
请注意,诗意字面量可以包含保留关键字,比如这个例子中的 taking。
比较操作
与 Visual Basic 和一些脚本语言中的单个等号运算符类似,Rockstar 中的 is 关键字出现在语句中还是出现在表达式中所表示的意思也不一样。
Rockstar 中的比较操作只能在表达式中完成。
Tommy is nobody 使用 nobody 来初始化 Tommy。
If Tommy is nobody 表示在 Tommy 等于 nobody 时执行后面的代码块。
修饰符 not 会反转比较操作的结果,类似于 SQL 中的 IS / IS NOT 。关键字 ain’t 是 is not 的别名。这种用法与惯用英语相反,其中“Tommy isn’t anybody”、“Tommy ain’t nobody”和“Tommy ain’t not nobody”表示相同的意思。
Rockstar 还支持以下的比较语法:
is higher/greater/bigger/stronger than 表示“大于”。
is lower/less/smaller/weaker than 表示“小于”。
is as high/great/big/strong as 表示“大于等于”。
is as low/little/small/weak as 表示”小于等于“。
输入输出
在 Rockstar 中,我们使用 Listen 关键字从 STDIN 读取一行输入,并使用 Listen to 将输入赋值给变量。
Listen to your heart——从 STDIN 读取一行,并将它赋值给 your heart。
使用 Say 关键字将变量的值写到 SDTOUT。
Say Tommy——将 Tommy 的值输出到 STDOUT。
Rockstar 将 Shout、Whisper 和 Scream 作为 Say 的别名。
流程控制和块语法
条件语句
条件表达式以 If 关键字作为开头,后面跟上表达式。如果表达式的计算结果为 true,则执行后续的代码块。在 If 代码块之后可以有可选的 Else 代码块。如果 If 表达式计算结果为 false,则执行 Else 关键字后面的代码块。
循环
与 If 语句类似,循环使用 While 或 Until 关键字表示,只要表达式得到满足,后面的代码块会被重复执行:
Tommy was a dancer While Tommy ain't nothing, Knock Tommy down
使用 16 初始化 Tommy,然后循环,每次将 Tommy 减 1,直到 Tommy 等于零。
break 和 continue 语句的用法与其他大多数基于代码块的语言一样。Rockstar 将 Break it down 定义为 break 的别名,并将 Take it to the top 定义为 continue 的别名。
代码块
Rockstar 中的代码块以 If、Else、While 或 Until 作为开头,并以空行或 EOF 作为结尾。
Tommy was a dancer While Tommy ain't nothing Shout it Knock it down
函数
函数使用变量名和后面的 take 关键字以及由 and 关键字分隔的参数列表进行声明。
Multiply takes X and Y
Search takes Needle and Haystack
函数体是一个没有空行的语句列表。空行表示函数体的结束。Rockstar 中的函数总是有返回值,使用 Give back 关键字表示。
使用 taking 关键字调用函数:
Multiply taking 3, 5 相当于 returning (presumably) 15
Search taking "hands", "lay your hands on me"
示 例
使用极简的 Rockstar 表达 FizzBuzz,为了清晰起见,使用了缩进:
惯用的 Rockstar,使用诗意字面量,没有缩进:
一些想法
如果有可能,尝试改进这门语言。我并不热衷于连续块语法——对于初学者来说,还无法实现嵌套块。
想办法实现图灵完备的摇滚民谣编译器。或许是基于 BF 的东西,我们使用单词长度或首字母或其他东西将歌词编译成 BF,或者其他一些极简但图灵完整的语言。
制作”认证 Rockstar 开发者“贴纸,并将它们发给任何可以写 Rockstar 代码的人。
使用 composer 为代码生成乐谱。
相关实现
rockstar-js——Rockstar-to-JavaScript 编译器
rockstar-lexer——使用 Haskell 编写的 Rockstar 词法分析器
rockstar-java——Rockstar 的 Java 解释器
rockstar-py——Rockstar-to-Python 编译器
英文原文
今日荐文
点击下方图片即可阅读
独家丨对话亚麻徐 CTO Werner Vogels
技术是没有边界的,保持技术敏感性和快速学习能力程序员进阶的重要因素,《程序员进阶攻略》相信会给予正在成长阶段的你很多启发与指引。识别下图二维码,即刻订阅!