Skip to main content

A demo packae, forked from https://github.com/zhanyong-wan/dongbei

Project description

dongbei - 东北方言编程语言

体格咋地

体格咋地

扫码关注原作者微信公众号“老万故事会”

引言

dongbei是啥?它是一门以东北方言词汇为基本关键字的以人为本的编程语言。

这玩意儿可是填补了世界方言编程地图上的一大片儿空地啊! 这么说吧,谁要是看了 dongbei 程序能憋住了不笑,我敬他是纯爷们儿!

那它有啥特点咧?多了去了:

  • 简单啊!小学文化程度就行。您能看懂春晚不?能?那就没问题。
  • 好读啊!看着看着包您不由自主地念出声儿来。
  • 开心啊!呃,做人嘛,最重要的是要开心。
  • 开源啊!不但不要钱,而且不要脸 -- 随时随地欢迎东北话高手打脸指正。

总而言之,dongbei 语言具有极高的娱技比(娱乐精神-技术含量比例)。

dongbei 编程语言的开发采用了业界领先的 TDD(TreeNewBee-Driven Development) 方式。 具体地说,就是每个功能都是先把文案写好,八字没一撇牛皮就吹起来了,然后根据牛皮写测试案例,最后再实现功能让牛皮不被吹破。 这样做有两大好处:第一每个功能都是有的放矢,不值得 tree new bee 的功能一概没有。 第二确保了每个功能都有文案负责吹嘘,开发者绝对不会养在深闺无人识。

不扯犊子了。翠花,上酸菜~~~

系统要求

dongbei 语言是基于 Python 3 二次开发的。 只要能跑 Python 3 的旮旯儿都能跑。 像 Mac OS 啦、Windows 啦、Linux 啦,等等等等,都成!

安装

甭麻烦了!直接跑 src/dongbei.py 就成。

不过,要是你的系统没有python3呢,那得先装一个,免费!

比如,你要是用 Mac 的话,就按 https://docs.python-guide.org/starting/install3/osx/ 做。

测试

没事跑跑

test/dongbei_test.py

身体更健康。

你好,世界

创建一个名字叫 hello-world.dongbei 的文本文件,内容如下:

唠唠:“唉呀,这嘎哒真他妈那啥!”。

用 utf-8 编码保存。 要是编辑器因为编码错误埋汰你,那就把文件内容改成

# -*- coding: utf-8 -*-

唠唠:“唉呀,这嘎哒真他妈那啥!”。

再试,应该就成了。

然后在命令行窗口运行:

src/dongbei.py hello-world.dongbei

你应该看到执行结果:

唉呀,这嘎哒真他妈那啥!

考试小抄

要是你以前有 dongbei 语言基础,或者不耐烦看文档,可以直扑 dongbei 语言考试小抄

语言定义

学习一门语言,先得了解它的词法(怎么从一串串的字符组成词),然后是语法(怎么把词组成句子)和语义(这些句子都啥意思啊?)。 所以,咱们先讲讲 dongbei 语言词汇的构成。

词法

字符串常量

一行代码当中,要是出现配对的中文全角双引号,比如

...“我是一个字符串”...

那么引号当中的内容(我是一个字符串)会被当成一个字符串常量。

注释

一行代码当中,如果在字符串常量外面出现 # 字符,所有从 # 开始的字符都会被当成注释被忽略掉。 比如

唠唠:  # 我是一个注释。
    “嘎哈#?”。  # 我还是一个注释。

唠唠:“嘎哈#?”。

是一样一样的。

分词

大部分的西方语言在书写的时候要用空白字符或者标点把单词隔开,要不就会产生歧义。 比如 therapist(理疗师)和 the rapist(强X犯)就有很大的不同!

所以,西人开发的编程语言也一样啰嗦,动不动就要加空格,忒麻烦了。

dongbei 语言以人为本,适应华人的书写习惯,加不加空格换行都无所谓。 反正加了也白加(除非加在一个字符串常量的内部)。 所以对 dongbei 来说,

唠
  唠
    :
      “嘎哈?”
        。

唠唠:“嘎哈?”。

是一样一样的。

名字

代码里面除了各种有特俗意义的关键词(keyword),还会有各种用户定义的名字(变量名、函数名、类型名,等等)。 在 dongbei 语言里面,除了关键词、标点符号和常数,剩下的都是名字。 比如,在“张三乘李四”这个 dongbei 语言表达式里,“乘”是一个关键词,“张三”和“李四”是两个不同的名字,

那么问题来了:dongbei 语言是不尿空格的,名字和关键词之间没有明显的隔离。 要是名字里包含关键词怎么办? 比如,我们知道“乘”是一个关键词,那还能用“阶乘”做套路名吗? 系统会不会把它理解成名字“阶”和关键词“乘”?

不要方! dongbei 语言允许你用中文全角方括号【】把一串字符标注为名字。 比方说,“【阶乘】”就明明白白地是一个叫“阶乘”的名字,绝对不会被当成是名字“阶”加关键词“乘”。

常数

除了用阿拉伯数字表示的十进制整数(比如 2、42、250,等等),0 到 10 的常数也可以用中文表达:

零一二三四五六七八九十

也可以写成或者也可以写成

比如,

五加二

的意思就是 5 + 2。

语句

一个 dongbei 程序是由一串语句组成的。 每个语句以句号(。)结束。 为了表达程序员炽热的感情,也可以用感叹号(!)结束,意思和句号是一样一样的。 请大家根据自己的心情任选使用。

变量

dongbei 语言允许使用任何字符串做变量名。只要记住两点:

  1. 变量名里所有的空白字符都会被忽略。
  2. 有歧义的时候要把变量名用【】括起来。

定义变量

dongbei 是一门以人为本的语言。 我们知道东北人都是活雷锋。 所以,要定义一个叫 XX 的变量,我们要写......

XX是活雷锋。

比如:

老王是活雷锋。

当然,热情洋溢的

老王是活雷锋!

也是可以的。

给变量赋值

dongbei 语言不整“赋值”这种文绉绉的词儿。 咱们叫“装”。 比如:

老王装二。

可以理解为 C 语言的

lao_wang = 2;

要把一个活雷锋的值清空回到原始状态,可以用

削老王。

过后老王就啥也不是了。

增减变量

活雷锋除了会装,加加减减也是常见的操作。 按没病走两步的规矩,这些操作的名字叫做:走走稍稍走X步稍X步。 比如:

老张装二。  # 现在老张等于2
老张走走。  # 现在老张等于3
老张走两步。  # 现在老张等于5
老张稍稍。  # 现在老张等于4
老张稍五步。  # 现在老张等于-1

注:稍(shào)稍这个词的意思是“退退”。 它具有十分浓厚的地方风味,尤其在东北大老哥向社会小老弟传授人生的经验时,出现得尤为频繁,体现了东北人民的儒雅随和,平易近人。 近年来随着各种视频、社交平台的发展,这个东北词汇也受到了来自社会各界人士的喜爱。

引用变量

变量,呃,活雷锋定义以后就可以引用了。 引用的方法很简单:把活雷锋的名字写出来就成。 比如:

老张是活雷锋。
老王是活雷锋。
老张装250。
老王装老张加13。

定义了两个活雷锋:老张和老王。 老张值250。 老王值263。

输出

要输出信息,咱们得说“唠唠”。假定要说的信息是 YY,就得写

唠唠:YY。

比如说,活雷锋老王的当前值是263,那么

唠唠:老王。

的结果就是打印

263

唠的内容也可以是中文全角双引号括起来的字符串常量,像

唠唠:“诶呀妈呀!”。

的结果就是打印出

诶呀妈呀!

字符串运算

顿号(、) 操作符可以把两个值当成字符串拼接起来。 假定活雷锋老王的当前值是字符串“NB”,那么表达式

老王、“A”

的值就是字符串 NBA。而

“老王”、665加一

的值是 老王666

算术运算

基本的四则运算 dongbei 都是支持的。举例说明:

表达式 含义
老王加老张 老王 + 老张
老王减老张 老王 - 老张
老王乘老张 老王 * 老张
老王除以老张 老王 / 老张
老王齐整整地除以老张 老王 / 老张,只保留整数部分

注意除法运算叫“除以”,不叫“除”。 问问你小学数学老师就知道,“A除B”的意思其实是“B除以A”,也就是说“B/A“。 所以,要是你说“6除2”,数学老师会以为你在说3分之1,而不是3。 你要是跟他讲“6除2得3”,信不信他削你?

跟小学学过的一样,乘除的优先级比加减高。 相同优先级的情况下,运算从左到右。比如说:

3加2乘5

的结果是13,不是25。

括号也是可以的:

唠唠:(五减(四减三))乘二。

8

比大小

dongbei 人讲究分寸,长幼有序。

假定老王装的是5,老张装的是6。 那么

唠唠:老王 比 老张 大。
唠唠:老王 比 老张 小。
唠唠:老王 跟 老张 一样一样的。
唠唠:老王 跟 老张 不是一样一样的。

的结果就是

错
对
错
对

除此之外,一个刚刚创建的活雷锋还没有值。 我们就说他啥也不是

老王是活雷锋。
唠唠:老王。
唠唠:老王啥也不是。

会打印

啥也不是
对

发动群众

单只单只的活雷锋有的时候略显捉襟见肘。 dongbei 支持“群众”的概念。 就是一个变量里放一群活雷锋。 有学习好的同学可能发觉了:这不就是数组吗!

比如:

张家庄都是活雷锋。  # 张家庄是个群众变量。初始值是[]。

完了吧就可以往里边儿加人了:

张家庄来了个二加三。  # 张家庄现在 = [5]。
张家庄来了个“大”。   # 张家庄现在 = [5, '大']
张家庄来了个四减一。  # 张家庄现在 = [5, '大', 3]
张家庄来了个“粗”。   # 张家庄现在 = [5, '大', 3, '粗']

加完人就可以点名了:

唠唠:张家庄的老大。  # 第一个人(5)。
唠唠:张家庄的老二。  # 第二个人('大')。
唠唠:张家庄的老(四减一)。  # 第三个人(3)。
唠唠:张家庄的老四。  # 第四个人('粗')。
唠唠:张家庄的老一。  # 跟老大一回事。
唠唠:张家庄的老幺。  # 最后一个人('粗')。

既然数组里头可以套数组,那么群众当中也可以套群众:

李家村都是活雷锋。  # 李家村也是个群众变量。初始值是[]。
李家村来了个三。  # 李家村现在 = [3]。
李家村来了个张家庄。  # 李家村现在 = [3, [5, '大', 3, '粗']]。
唠唠:李家村的老幺的老大。  # 5。

要数数一个数组里有几个元素,用XX有几个坑

唠唠:张家庄有几个坑。  # 4
唠唠:李家村有几个坑。  # 2

注意这李家村有两个坑,第一个装的是3,第二个装的是[5, '大', 3, '粗']

要想团灭群众,只需要削他:

削张家庄。  # 张家庄现在啥也不是。

磨叽

所谓磨叽,就是一遍一遍循环。 所以,在 dongbei 语言里循环的写法是:

变量名 从 X 到 Y 磨叽:
  ...  # 需要重复做的事
磨叽完了。

举例说明:

老王从一到五磨叽:  # 老王从1走到5。
  唠唠:老王!  # 打印老王的当前值。
磨叽完了!  # 循环结束。

运行的结果是:

1
2
3
4
5

磨叽的范围也可以是群众。比如,要是张家庄装的是[3,1,5,2],那么

老王在张家庄磨叽:
  唠唠:老王。
磨叽完了。

的结果就是

3
1
5
2

磨叽是可以嵌套的。比如:

老张从一到二磨叽:
  唠唠:“老张:”、老张。
  老王从老张到四磨叽:  # 内层磨叽可以引用外层磨叽变量
    唠唠:“老王:”、老王。
  磨叽完了。  # 内层磨叽结束。
磨叽完了。  # 外层磨叽结束。

运行出来是这样的:

老张:1
老王:1
老王:2
老王:3
老王:4
老张:2
老王:2
老王:3
老王:4

要是磨叽到半拉儿就不想再磨叽了咋办咧?那就 尥蹶子。 要是想跳过从当前到 磨叽完了 中间的所有操作,就说 接着磨叽。 比如这个:

老张从一到十磨叽:
  寻思:老张跟二一样一样的?
  要行咧就接着磨叽。
  唠唠:“老张是”、老张。
  寻思:老张比五大?
  要行咧就尥蹶子。
磨叽完了。

结果就是

老张是1
老张是3
老张是4
老张是5
老张是6

要是想 死磨叽,可以 从一而终

老王装一。
老张从一而终磨叽:  # 磨叽无穷次,每次的值都是一。
唠唠:老张、“和”、老王。
老王装老王加一。
寻思:老王比三大?
要行咧就尥蹶子。
磨叽完了。

结果就是

1和1
1和2
1和3

讲条件

虽然 dongbei 人都是活雷锋,干活的时候该讲条件还是要讲条件的。 寻思 是一项很有用的技能!

一般来讲,要是俺们有件事情(不妨叫做 XXX)只想在某个条件(不妨叫 CCC)成立的时候再做,就写:

寻思: CCC ?
要行咧就 XXX

要是 CCC 不成立的时候俺们有另外一件事情 YYY 要做,那就写:

寻思: CCC ?
要行咧就 XXX
要不行咧就 YYY

比如说吧,要是俺们瞅着老王比老张大就想夸夸老王,那就这么写:

寻思:老王比老张大?
要行咧就唠唠:“老王比较牛叉!”。

再复杂一点的:

寻思:老王比老张大?
要行咧就唠唠:“老王比较牛叉!”。
要不行咧就寻思:老张比老王大?
要行咧就唠唠:“老张比较牛叉!”。
要不行咧就唠唠:“老王老张共同牛叉。”。

看懂了?要是老王是3老张是2,那么这段代码就会打印

老王比较牛叉!

要是老王2老张3咧,就会打印

老张比较牛叉!

要是老王老张都2咧,打印的就是

老王老张共同牛叉。

很多的时候,要是一个前提条件不成立,咱们就想立马尥蹶子退出整个程序,因为它意味着上游提了个不合理的要求。 虽然理论上说寻思可以处理这种情况,实际用起来相当啰嗦。 这时候咱们就可以用保准CCC,非常精炼。 比如:

保准老王比五大。

要是老王的值比五大咧,这句话没毛病,程序接着往下跑。 如若不然,程序立马退出,而且打印出一条错误:

整叉劈了:该着 【老王】比5大,咋错了咧?

还有的时候咧,咱们要保准某个条件不成立。跟保准相对的是辟谣

老王装二。
辟谣老王比五大。  # 没毛病
辟谣五比老王大。  # 整叉劈了:5比【老王】大不应该啊,咋错了咧?

严格来说“辟谣”并不是东北特有的词汇,但是东北人民对它可以说是相当的熟悉了。 所以把它收入 dongbei 编程语言是相当和谐的。 你明白了吗?

善用保准辟谣,保准臭虫在你代码里藏不住。

组合拳

你有没有想过:要是俺们在某个条件成立的时候想做两件事而不是一件事,该咋办咧? 要是写

寻思:CCC ?
要行咧就
   XXX。
   YYY。

成嘛?

不成。

前面俺们说过咧,dongbei 语言里面字符串常量外边儿的空白是不作数的。 写了也瞎掰活。 所以,按上面这种写法,XXX 倒是只有 CCC 成立的时候才会做,可 YYY 是无论如何都会做的。 相当于:

# 先讲条件:
寻思:CCC ?
要行咧就XXX。

# 这个不讲条件。
YYY。

要解决这个问题,咱得上 组合拳:把一串操作整合成一个操作。 组合拳的写法是:

开整:
  XXX。
  YYY。
  ...
  ZZZ。
整完了。

尽管整了一串,在 dongbei 语言看来这是一个操作。 所以,

寻思:CCC ?
要行咧就开整:
   XXX。
   YYY。
整完了。

就能达到俺们的目的了!

套路

“套路”这名字听着吓人,其实就是给一串常用的组合拳取一个名字,然后吧需要做这些操作的时候提一下这个名字就OK了。

定义套路

要定义一个套路,用这个格式:

套路名字 咋整:
  ...  # 爱做的事儿
整完了。

还是举例说明:

写九九表咋整:  # 定义套路 写九九表。
  老王从1到9磨叽:
    老张从老王到9磨叽:
      唠唠:老王、“*”、老张、“=”、老王乘老张。  # 打印 X*Y=Z
    磨叽完了。
    唠唠:“”。  # 空一行。
  磨叽完了。
整完了。  # 结束套路定义。

定义了一个叫“写九九表”的套路。 注意定义套路本身不会让这个套路真的跑起来。 所以上面这段程序跑的结果是啥也不做。

使用套路

要把一个套路代表的操作跑一遍,得写:

整 套路名。

比如说,上面这个“写九九表”的套路定义好了过后,你只要写:

整写九九表。

就可以打印出一份浓眉大眼的九九表了:

1*1=1
1*2=2
1*3=3
...

8*8=64
8*9=72

9*9=81

带参数的套路

有的时候,我们希望通过一个参数去控制一个套路的行为。 比如,我们要教会电脑算一个数的阶乘(就是123*... 一直乘到这个数)。 在定义这个“阶乘”套路的时候,我们并不知道以后会用它来算哪个数的阶乘。 所以,我们要把这个数定义成这个套路的一个参数。

那就要这样写:

套路名(参数名)咋整:
  ...  # 爱做的事
整完了。

具体到这个“阶乘”套路,就是这样的:

【阶乘】(那啥)咋整:  # 定义套路 阶乘,有一个参数 那啥
  ...  # 阶乘的操作步骤
整完了。  # 定义结束。

注意这里我们把套路名“阶乘”用方括号【】括起来,因为“乘”本身是个关键词,不括起来容易引起误会。

这个套路有一个参数,名字叫“那啥”。 “【阶乘】(那啥)”就是算那啥的阶乘。

要是一个套路有多个参数,那就得把它们一个一个列出来,中间用逗号隔开:

求和(甲,乙)咋整:
  滚犊子吧 甲加乙。
整完了。

调用这种套路的时候咧,相应地要把参数的值一个一个列出来:

唠唠:整求和(五,七)。

会打印出 12。

从套路返回值

在“写九九表”这个例子里,套路本身是不返回任何值的。 它要做的事都通过“唠唠”打印出来了。

而对于“阶乘”来说,我们并不想打印这个阶乘的结果。 我们只想把结果返回给整这个套路的人,爱咋用咋用。

在 dongbei 里边儿,从套路里返回一个值X,得说“滚犊子吧X。”

这个阶乘的完整定义,可以是这样的:

【阶乘】(那啥)咋整:  # 定义套路 阶乘,有一个参数 那啥
  老王是活雷锋。
  老王装一。
  老李从一到那啥磨叽:
    老王装老王乘老李。
  磨叽完了。
  滚犊子吧老王!  # 返回值。
整完了。  # 定义结束。

写完这个,再来一句

唠唠:整【阶乘】(五)。

就可以看到打印结果

120

了!

套路套套路

一个套路里面可以定义别的套路。 这个内层的套路只在外层套路的范围内看得见。 内层套路可以引用外层套路的活雷锋。

比如,这是九九表的另一种写法:

写九九表咋整:
  老王从一到九磨叽:
    王九表咋整:  # 定义一个套在“写九九表”套路里的套路。
      老张从老王到九磨叽:  # 内层套路可以引用外层套路的活雷锋。
        唠唠:老王、“*”、老张、“=”、老王乘老张。
      磨叽完了。
    整完了。  # 内层套路定义结束。
    整王九表。  # 使用内层套路。
    唠唠:“”。
  磨叽完了。
整完了。

自推

每个程序员在学习编程的时候都要翻一个坎儿,这就是 递归

在 dongbei 语言里面,咱不整这些虚头八脑的概念。 咱就叫“自推”。

啥意思? 就是说在做一个操作的时候调用这个操作自己。 有点循环定义的意思。

其实这就是俺们中学老师讲过的数学归纳法:欲求 f(n),先求 f(n-1)。 然后如果从 f(n-1) 的值可以推算出 f(n) 的值,不就搞定了吗? 当然,前提是这个自推不能无穷无尽地整下去,到某一步得停下来。

举个例子。 求 n 的阶乘 f(n) 可以这么搞: 要是 n 是 0 的话,结果就是 1。 要是 n 比 0 大的话,就给就是 n * f(n-1)。

这里,在算 f(n) 的时候,我们先算 f(n-1),再从 f(n-1) 算出 f(n)。 这就是自推大法的精髓。

把上面的思路用 dongbei 语言写出来,就是:

【阶乘】(那啥)咋整:  # 定义套路 阶乘,有一个参数 那啥。
  寻思:那啥比一小? # 需要自推吗?
  要行咧就 滚犊子吧 一。  # 不需要。
  要不行咧就 滚犊子吧 那啥乘整【阶乘】(那啥减一)。  # 需要。自推吧。
整完了。  # 定义结束。

帮衬

在家啃父母,出门靠姐妹儿。 甭管你多大能耐,没人帮衬也不成。 所以咱们写 dongbei 程序得借力,憋啥玩意儿都自己从头整。 比如翠花蛇家宝贝不少,咱就借来用用呗。

举例说明,

翠花,上 re。  # 导入 python 的正则表达式 re 模块。
老王装“abd”。
寻思:整re.match(“a.*”,老王)?  # 调用 re.match()。
要行咧就唠唠:“OK!”。
要不行咧就唠唠:“砸了!”。

跑出来结果

OK!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for dongbei, version 0.0.2
Filename, size File type Python version Upload date Hashes
Filename, size dongbei-0.0.2-py3-none-any.whl (19.9 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size dongbei-0.0.2.tar.gz (25.8 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page