本文是對於 wenyan-lang 方向在的一些嘗試, 利用 Cirru 的工具鏈, 作簡化的方案.
代碼實現看 九章編程, 以及對應的 Demo 頁面.
基於九章編程的方案, 最終實現一個 Fibonacci 函數, 代碼是這樣的,html
術曰 菲氏數 (甲) 若 (少於 甲 三) 一 並 (菲氏數 (減 甲 一)) (菲氏數 (減 甲 二)) 得 (菲氏數 一)
對比一下文言編程的例子, 會顯得後者囉嗦不少.python
吾有一術。名之曰「斐波那契」。欲行是術。必先得一數。曰「甲」。乃行是術曰。 若「甲」等於零者乃得零也 若「甲」等於一者乃得一也 減「甲」以一。減「甲」以二。名之曰「乙」。曰「丙」。 施「斐波那契」於「乙」。名之曰「丁」。 施「斐波那契」於「丙」。名之曰「戊」。 加「丁」以「戊」。名之曰「己」。 乃得「己」。 是謂「斐波那契」之術也。 施「斐波那契」於十二。書之。
固然了, 九章編程方案只是取巧地把 Lisp 的寫法翻譯成中文而已, 少了不少.
首先這東西挺好玩的. 再就是本身仔細看下來也有很多本身的想法.git
翻了代碼裏的問題, 文言編程幾個做者古文詞彙和句式都比我豐富挺多的.
不過由於如今的人都不是經常使用古文, 其實也挺不正宗的.
大體能感覺到例子裏不少用法, 是混雜了不一樣朝代的措辭, 因此有點怪.
並且有些沒法解決的問題, 西方傳入的數學和計算機術語, 免不了要用現代的詞彙.github
固然, 按照個人偏好, 若是說有古文編程的話, 我首先想到用古代典籍做爲模板.
好比說九章算術, 至少漢代的著做了, 這應該能充分表明古人對於數學的表達習慣.編程
〔三七〕今有環田,中周九十二步,外週一百二十二步,徑五步。問為田幾何?
荅曰:二畝五十五步。〔三八〕又有環田,中週六十二步、四分步之三,外週一百一十三步、二分步之一,徑十二步、三分步之二。問為田幾何?
荅曰:四畝一百五十六步、四分步之一。
術曰:並中外周而半之,以徑乘之為積步。
密率術曰:置中外周步數,分母、子各居其下。母互乘子,通全步,內分子。以中周減外周,餘半之,以益中周。徑亦通分內子,以乘周為實。分母相乘為法,除之為積步,餘積步之分。以畝法除之,即畝數也。json
以及元代的四元玉鑑當中也有相似的表達習慣.(沒有句讀太難讀了..)
我以爲若是這些數學家當年發明編程語言的話, 怕是跟這差不了多少.
不過也還好如今的編程語言有各類標點符號, 否則真是有的受了.數組
另外比較明顯的一個麻煩是, 代碼當中必然會有較多的抽象, 或者說定義函數,
即使你們用的不是 Lisp 這樣的前綴表達式語言, 也少不了會遇到這樣的代碼,安全
(f1 p1 p2) (f2 q1 q2 q3 q4 (f3 a5 q6) (f4) q7 q8)
算了我仍是換個大家好接受一些的寫法:ruby
f1(p1, p2) f2(q1, q2, q3, q4, f3(a5, q6), f4(), q7, q8)
在文言編程當中, 能夠看到 wenyan 用了 名之曰「丁」
來定義操做,
而實際上對應這種枯燥的抽象, 基本上很難也古文天然得表達出來.
或者說代碼, 做爲給機器執行的語言, 自己就有着特殊性.babel
固然, wenyan 能定義出這麼一整套來, 仍是挺厲害的.
在九章編程當中, 我出於省事的考慮, 直接基於已有的 Lisp 風格直接作了.
也就是說, 九章編程基本上就是基於前綴表達式實現的. 不像天然語言.
可是具體的術語, 我基於九章算術的文本作了簡單的統計, 選取了一些詞彙,
總得來講只是借了一層九章算術花樣, 好比"對象", 九章算術裏壓根就沒這東西.
我看 wenyan 當中用的中文數字表示, 在源碼裏有本身去解析和蒐集.
翻了一下代碼, 大概是本身進行了解析吧, 先轉成阿拉伯數字表示, 就很快了.
九章編程裏面直接找了個模塊 nzh 進行轉化的, 作 Demo 也夠用.
另外一個是變量名的問題, 九章編程直接用中文字符串作的.
由於九章編程其實是 interpreter, 不是轉義 js 的, 沒這個限制.
wenyan 的實現當中我看到有轉成拼音的操做, 不肯定具體狀況.
按說中文, 甲
假
都是 jia3
, 雖然有字典, 但很容易會重名的.
wenyan 大體上提供了 js, py, ruby 的方案, 大體看了一下 js 的部分.
首先 tokenize, 再 parser 解析代碼, 而後用 compiler 拼接 js.
拼接 js 的部分是直接用的字符串拼接, 相對來講不那麼完善, 可是夠用.
另外手動拼接獲得的代碼, 通常格式都是亂的, 須要用 Prettier 或者 Babel 從新格式化.
另外比較省事並且可靠點的方案是用 babel/generator 去實現.
就是說用 Babel 來處理 JavaScript 代碼生成的具體實現,
這樣幾方的工做只要作到能生成 AST 就行了, 這就安全不少.
比較熟悉是由於個人 CirruScript 用的就是這套方案, Babel 工具鏈真挺豐富的.
九章編程用的方案是 Interpreter, 解釋執行, 沒有生成 js 代碼.
這也就意味着執行計算都是在 JavaScript 運行環境內部的,
單純 JavaScript 執行, 能夠有 V8 優化, 最終甚至可能以彙編的形式運行,
那樣來講性能就好不少了. 解釋執行的問題就是性能會不好.
不過另外一方面, 解釋執行不須要知足 js 語法, 也就沒七七八八的限制了. 直接跑.
雖然對於編譯器來講, 生成代碼的優化是最難的部分, 但玩具項目的話...
要寫個 Parser 把整個代碼結構解析出來也是至關要命的工做量.
wenyan 光是 parser.js
就八百多行了, 還不算各類工具函數和關鍵字定義的,
沒看明白 typechecker.js
具體邏輯, 校驗結構麼, 也快七百行了.
反而 compiler 生成 js 部分三百多行就搞定了...
我...畢竟是寫着玩的, 若是 Parser 也要這麼風風火火折騰一遍, 枯燥啊.
不過我有 Cirru 這邊的工具鏈, 加上語法, 直接用 Lisp 風格套上去了.
Cirru 大體是是一套把縮進語法(或者數據)生成一個樹結構的方案,
好比這樣一段代碼, 直接用 Cirru 的模塊進行解析,
得 (菲氏數 一)
就能直接獲得一個樹形的結構:
[ [ "得", [ "菲氏數", "一" ] ] ]
前面函數定義的部分, 代碼複雜一些, 有縮進, 也對應解析出來:
術曰 菲氏數 (甲) 若 (少於 甲 三) 一 並 (菲氏數 (減 甲 一)) (菲氏數 (減 甲 二))
獲得着要一個樹形的結構:
[ [ "術曰" "菲氏數" ["甲"] [ "若" ["少於" "甲" "三"] "一" [ "並" [ "菲氏數" ["減" "甲" "一"] ] [ "菲氏數" ["減" "甲" "二"] ] ] ] ] ]
有這樣一個結構, 後面的部分就相對容易了, 若是不校驗的話, 直接就能算, 好比:
["減" "甲" "一"]
通過簡單的變換就能獲得對應的 JavaScript 代碼:
(甲 - 1)
或者更加複雜一些的結構,
[ "並" [ "菲氏數" ["減" "甲" "一"] ] [ "菲氏數" ["減" "甲" "二"] ] ]
其實就是判斷一下, 對中間的數組進行遞歸計算, 也很容易完成求值.
固然, 具體到函數定義方面, 以及一些動態長度(或者複雜節夠)的語句, 會麻煩一些.
原理上能夠參考 http://norvig.com/lispy.html 提供的例子.
這套方案用了 Cirru 的 Parser, 同時也就繼承了 Cirru 語法的約束,
好比用 (
)
$
,
"
以及空格進行語法結構控制的事情.
放在九章編程裏面, 主要是在古文編程當中插入了大量的英文符號...
或者說這些如何其實除了空格換成中文筆畫符號.. 可能效果也是相似的, 總之有些奇怪的東西.
不過整體上講, 直接省去了大量工做量.
wenyan 高亮作得比較充分, 渲染圖挺漂亮的. 九章這邊沒有專門作.
不過倒也不是一點高亮都沒有, 能夠看到文檔裏直接用 Cirru 進行了基礎的高亮.
看源碼那邊, 好像 wenyan 用的是 SVG 渲染的圖, 效果確實不錯.
由於是個玩具項目, 九章編程試驗到能求 Fibonacci 而後, 有點玩不動了.
我知道後面的工做量挺多的, 比較我以前 Cirru 項目當中就在嘗試.
有興趣過來 watch 一下 CirruScript 跟 interpreter.nim 這邊的工做.
雖然暫時沒有經歷深刻開發, 可是斷斷續續會王中間追加功能的.
另外我在微博上也有提到, 中文的表達能力實際上是很是強的,
能夠想象, 同個含義, 在古文當中能夠獲得多個表述, 排列組合下來, 不比英文少...
以往看到的中蟒算是作的比較完整的一個範例吧.
徹底有不少可能, 能夠腦補一個少兒編程的場景, 寫一段代碼,
李雷的數 是 1 韓梅梅的數 是 2 (李雷的數 加上 韓梅梅的數) 是多少
這個代碼用 Cirru 能解析出來一個簡單的結構,
[ [ "李雷的數", "是", "1" ], [ "韓梅梅的數", "是", "2" ], [ [ "李雷的數", "加上", "韓梅梅的數" ], "是多少" ] ]
作一下語法轉換, 就獲得一串很熟悉的前綴表達式了,
[ [ "是", "李雷的數", "1" ], [ "是", "韓梅梅的數", "2" ], [ "是多少", [ "加上", "李雷的數", "韓梅梅的數" ] ] ]
而後求一下值, 拿去忽悠一零後有沒有效果...
換成中文門檻也低一些吧, 應該有很多能夠嘗試的.
九章編程的 Demo 是能夠執行的, 歡迎試玩 http://jiuzhang.cirru.org/