Skip to content

Commit

Permalink
Merge pull request #416 from LingDong-/master
Browse files Browse the repository at this point in the history
v0.1.2
  • Loading branch information
LingDong- authored Dec 29, 2019
2 parents a36f29d + f5907d4 commit d06c4eb
Show file tree
Hide file tree
Showing 28 changed files with 1,902 additions and 614 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ English | [简体中文](./README.zh-Hans.md) | [繁体中文](./README.zh-Hant.

##

> 夫[唐](https://en.wikipedia.org/wiki/Emperor_Yao)、[虞](https://en.wikipedia.org/wiki/Emperor_Shun)之世,[結繩而足治](https://ctext.org/book-of-changes/xi-ci-xia/zh),屈指而足算。是時豈料百代之後,計算機械之巧,精於[公輸](https://en.wikipedia.org/wiki/Lu_Ban)之[木鳶](https://en.wikipedia.org/wiki/Lu_Ban#Inventions),善於[武侯](https://en.wikipedia.org/wiki/Zhuge_Liang)之[流馬](https://en.wikipedia.org/wiki/Wooden_ox);程式語言之多,繁若[《天官》](https://ctext.org/shiji/tian-guan-shu/zh)之星宿,奇勝[《山經》](https://en.wikipedia.org/wiki/Classic_of_Mountains_and_Seas)之走獸。[鼠](https://golang.org/)、[蟹](https://www.rust-lang.org/)、[鑽](http://ruby-lang.org/)、[魚](https://fishshell.com/),或以速稱。[蛇](https://www.python.org/)、[象](https://www.php.net/)、[駱](https://www.perl.org/)、[犀](http://shop.oreilly.com/product/9780596805531.do),各爭文采。方知[鬼之所以夜哭,天之所以雨粟](https://ctext.org/huainanzi/ben-jing-xun/zh)。然以文言編程者 ,似所未有。此誠非文脈之所以傳,文心之所以保。[嗟予小子](https://zh.wikisource.org/zh-hant/%E6%A6%AE%E6%9C%A8_(%E9%99%B6%E6%B7%B5%E6%98%8E)),遂有斯志。然則數寸之烏絲猶覆於頭,[萬卷之素書未破於手](https://zh.wikisource.org/zh-hant/%E5%A5%89%E8%B4%88%E9%9F%8B%E5%B7%A6%E4%B8%9E%E4%B8%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E9%9F%BB);一身長羈於遠邦,兩耳久曠于[雅言](https://zh.wikipedia.org/wiki/%E9%9B%85%E9%9F%B3)。然夫文章者吾之所宿好,程式者偶承時人之謬譽。故[希孟](https://en.wikipedia.org/wiki/Wang_Ximeng)不慚年少,[莊生](https://en.wikipedia.org/wiki/Zhuang_Zhou)不望[無涯](https://ctext.org/zhuangzi/nourishing-the-lord-of-life/zh)。乃作斯言。誠未能嘔瀝[長吉](https://en.wikipedia.org/wiki/Li_He)之[心血](https://zh.wikisource.org/zh-hant/%E6%9D%8E%E8%B3%80%E5%B0%8F%E5%82%B3),亦庶幾免於[義山](https://en.wikipedia.org/wiki/Li_Shangyin)之[流沫](https://zh.wikisource.org/zh-hant/%E9%9F%93%E7%A2%91)。既成之後,復學[干將鑄劍](https://zh.wikisource.org/wiki/%E9%91%84%E5%8A%8D)而自飼,[越王嚐糞](https://ctext.org/wu-yue-chun-qiu/yue-wang-gou-jian-wu-nian/zh)而當先。自謂偶追[《十書》](https://en.wikipedia.org/wiki/Ten_Computational_Canons)之筆意,但恨少[八家](https://en.wikipedia.org/wiki/Eight_Masters_of_the_Tang_and_Song)之淋漓。此[子山](https://en.wikipedia.org/wiki/Yu_Xin)所謂[士衡抚掌而甘心,平子見陋而固宜](https://zh.wikisource.org/zh-hant/%E5%93%80%E6%B1%9F%E5%8D%97%E8%B3%A6)。然則雖實[覆甕](https://zh.wikisource.org/zh-hant/%E6%99%89%E6%9B%B8/%E5%8D%B7092#%E5%B7%A6%E6%80%9D)之質,尚存斧正之望;雖乏[呂相](https://en.wikipedia.org/wiki/L%C3%BC_Buwei)之金,[易字](https://zh.wikisource.org/zh/%E5%8F%B2%E8%A8%98/%E5%8D%B7085)之渴蓋同。此亦開源之大義,吾輩之所以勉勵也。一笑。
> 夫[唐](https://en.wikipedia.org/wiki/Emperor_Yao)、[虞](https://en.wikipedia.org/wiki/Emperor_Shun)之世,[結繩而足治](https://ctext.org/book-of-changes/xi-ci-xia/zh),屈指而足算。是時豈料百代之後,計算機械之巧,精於[公輸](https://en.wikipedia.org/wiki/Lu_Ban)之[木鳶](https://en.wikipedia.org/wiki/Lu_Ban#Inventions),善於[武侯](https://en.wikipedia.org/wiki/Zhuge_Liang)之[流馬](https://en.wikipedia.org/wiki/Wooden_ox);程式語言之多,繁若[《天官》](https://ctext.org/shiji/tian-guan-shu/zh)之星宿,奇勝[《山經》](https://en.wikipedia.org/wiki/Classic_of_Mountains_and_Seas)之走獸。[鼠](https://golang.org/)、[蟹](https://www.rust-lang.org/)、[鑽](http://ruby-lang.org/)、[魚](https://fishshell.com/),或以速稱。[蛇](https://www.python.org/)、[象](https://www.php.net/)、[駱](https://www.perl.org/)、[犀](http://shop.oreilly.com/product/9780596805531.do),各爭文采。方知[鬼之所以夜哭,天之所以雨粟](https://ctext.org/huainanzi/ben-jing-xun/zh)。然以文言編程者 ,似所未有。此誠非文脈之所以傳,文心之所以保。[嗟予小子](https://zh.wikisource.org/zh-hant/%E6%A6%AE%E6%9C%A8_(%E9%99%B6%E6%B7%B5%E6%98%8E)),遂有斯志。然則數寸之烏絲猶覆於頭,[萬卷之素書未破於手](https://zh.wikisource.org/zh-hant/%E5%A5%89%E8%B4%88%E9%9F%8B%E5%B7%A6%E4%B8%9E%E4%B8%88%E4%BA%8C%E5%8D%81%E4%BA%8C%E9%9F%BB);一身長羈於遠邦,兩耳久曠于[雅言](https://zh.wikipedia.org/wiki/%E9%9B%85%E9%9F%B3)。然夫文章者吾之所宿好,程式者偶承時人之謬譽。故[希孟](https://en.wikipedia.org/wiki/Wang_Ximeng)不慚年少,[莊生](https://en.wikipedia.org/wiki/Zhuang_Zhou)不望[無涯](https://ctext.org/zhuangzi/nourishing-the-lord-of-life/zh)。乃作斯言。誠未能嘔瀝[長吉](https://en.wikipedia.org/wiki/Li_He)之[心血](https://zh.wikisource.org/zh-hant/%E6%9D%8E%E8%B3%80%E5%B0%8F%E5%82%B3),亦庶幾免於[義山](https://en.wikipedia.org/wiki/Li_Shangyin)之[流沫](https://zh.wikisource.org/zh-hant/%E9%9F%93%E7%A2%91)。既成之後,復學[干將鑄劍](https://zh.wikisource.org/wiki/%E9%91%84%E5%8A%8D)而自飼,[越王嚐糞](https://ctext.org/wu-yue-chun-qiu/yue-wang-gou-jian-wu-nian/zh)而當先。自謂偶追[《十書》](https://en.wikipedia.org/wiki/Ten_Computational_Canons)之筆意,但恨少[八家](https://en.wikipedia.org/wiki/Eight_Masters_of_the_Tang_and_Song)之淋漓。此[子山](https://en.wikipedia.org/wiki/Yu_Xin)所謂[士衡撫掌而甘心,平子見陋而固宜](https://zh.wikisource.org/zh-hant/%E5%93%80%E6%B1%9F%E5%8D%97%E8%B3%A6)。然則雖實[覆甕](https://zh.wikisource.org/zh-hant/%E6%99%89%E6%9B%B8/%E5%8D%B7092#%E5%B7%A6%E6%80%9D)之質,尚存斧正之望;雖乏[呂相](https://en.wikipedia.org/wiki/L%C3%BC_Buwei)之金,[易字](https://zh.wikisource.org/zh/%E5%8F%B2%E8%A8%98/%E5%8D%B7085)之渴蓋同。此亦開源之大義,吾輩之所以勉勵也。一笑。


## Helloworld
Expand Down Expand Up @@ -82,6 +82,11 @@ wenyan examples/helloworld.wy

![](screenshots/screenshot02.png)


### [The Decompiler](https://zxch3n.github.io/wenyanizer/)

You can now translate JavaScript to wenyan-lang using the [wenyanizer](https://github.com/zxch3n/wenyanizer) by [zxch3n](https://github.com/zxch3n).

### Text Editor Plugins

- [Plugin for VSCode](https://github.com/antfu/wenyan-lang-vscode) by [antfu](https://github.com/antfu)
Expand All @@ -90,7 +95,7 @@ wenyan examples/helloworld.wy

### Advance Usage

[API Specification](./documentation/API.md)
[Compiler API Specification](./documentation/Compiler-API.md)

## Syntax Cheatsheet

Expand Down Expand Up @@ -192,11 +197,16 @@ Arrays are 1-indexed.
|`注曰。「「文言備矣」」。` | `/*文言備矣*/` |
|`疏曰。「「居第一之位故稱初。以其陽爻故稱九」」。` | `/*居第一之位故稱初。以其陽爻故稱九*/` |

### Advance Features

- [Try...Catch](./documentation/Try-Catch.md)
- [Nested Function Calls](./documentation/Nested-Function-Calls.md)
- [Importing and Standard Library](./documentation/Importing.md)

## Renderer

```bash
wenyan examples/turing.wy --render 圖靈機 --output .
wenyan examples/turing.wy --render --title 圖靈機
```

Render a wenyan script into an image that resembles pages from historical printed books.
Expand Down
4 changes: 2 additions & 2 deletions documentation/API.md → documentation/Compiler-API.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# API Specification

[Back to README](../README.md)

# Compiler API Specification

> 🚧 Please note this project is still under heavy development. The API might be changed frequently and this doc any not be always update to date. If you get any questions, feel free to raise an issue.

Expand Down
117 changes: 117 additions & 0 deletions documentation/Importing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
[Back to README](../README.md)

# Importing Scripts

## 1. Import statement (experimental)

Below is the new import syntax. Thanks everyone for the inspiration!

```
吾嘗觀「「算經」」之書。方悟「正弦」「餘弦」「圓周率」之義。
```

```
from math import sin, cos, pi
```

New usage of `今有`. `今有` is now used for exported/public variables, while `吾有` is private/scoped. Think of `今有` like `module.exports.x=`. Think of `吾有` like `var x=`

Example:

`易經.wy`(a.k.a. Random)

```
吾有一數。曰四十二。名之曰「運數」。
今有一術。名之曰「運」。欲行是術。必先得一數。曰「甲」。乃行是術曰。
注曰「「運者。隨機種子也」」
昔之「運數」者。今「甲」是矣。
是謂「運」之術也。
今有一術。名之曰「占」。是術曰。
注曰「「線性同餘方法所得隨機數也」」
有數四十二億九千四百九十六萬七千二百九十六。名之曰「模」。
有數二千二百六十九萬五千四百七十七。名之曰「倍」。
有數一。名之曰「增」。
乘「倍」以「運數」。加其以「增」。除其以「模」。所餘幾何。昔之「運數」者。今其是矣。
除「運數」以「模」。名之曰「卦」。
乃得「卦」。
是謂「占」之術也。
```

`some_example.wy`(where you import random)

```
吾嘗觀「「易經」」之書。方悟「占」之義。
施「占」。書之。
```

Notice that in `易經.wy` the random seed (運數) is not exported. while its setter (運) is exported, but not imported by `some_example.wy`. Only `` the generator is exported and imported, and can be used directly.


### JS implementation details

(Python, Ruby are not implemented yet)


JS Implementation uses `var MODULE_NAME = new function(){ ... }` trick to wrap imported modules. `今有` maps to `this.` So they can be accessed using `MOUDLE_NAME.identifier`. The import statements specifies which identifiers are actually required, and those that are are extracted from its scope using `var identifier = MODULE_NAME.identifier`. Therefore, `some_example.wy` compiles to this:

```
var 易經 = new function() {
var 運數 = 42;
this.運 = () => 0;
this.運 = function(甲) {
/*"運者。隨機種子也"*/
運數 = 甲;
};
this.占 = () => 0;
this.占 = function() {
/*"線性同餘方法所得隨機數也"*/
var 模 = 4294967296;
var 倍 = 22695477;
var 增 = 1;
var _ans49 = 倍 * 運數;
var _ans50 = _ans49 + 增;
var _ans51 = _ans50 % 模;
運數 = _ans51;
var _ans52 = 運數 / 模;
var 卦 = _ans52;
return 卦
};
};
var 占 = 易經.占;
var _ans48 = 占();
console.log(_ans48);
```

You can check out a more sophisticated example on the online IDE. In the IDE, you can import an example from another example, or the a module from standard lib.

`parser.compiler` has a new option called `reader`, which is a function you can provide to tell compiler how to read a module. The default for node.js is to look in current directory plus one directory down. For browser-side you might give it something fancy like AJAX calls or something.

When you build the CLI compiler, the source of the standard libraries are included, so you can still use it without having the `./lib` folder.

Please let me know if found any issue or have any suggestion!


## 2. Standard Library implementers needed!

You think you can write wenyan? Please join us!

Currently in the `./lib` folder there are a couple of "stubs" such as `算經`(math) `位經`(bit ops) `易經`(random).

They contain many functions to be implemented in wenyan. e.g. The `sin()` function currently contains this HACK:

```
今有一術。名之曰「正弦」。欲行是術。必先得一數。曰「甲」。乃行是術曰。
施「Math.sin」於「甲」。名之曰「乙」。乃得「乙」。
是謂「正弦」之術也。
```

What we need to do is to replace `Math.sin` hack to a proper implementation (Taylor series?).

Our goal is to implement the most commonly used library functions. If you are familiar with one or two of them, please submit a pull request!


## 3. Thanks!!

As you might have noticed, much of the syntax and many ideas are inspired by / borrowed from numerous posts and feature requests. Therefore, a thank you to everyone!
80 changes: 80 additions & 0 deletions documentation/Nested-Function-Calls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
[Back to README](../README.md)

# Nested Function Calls

## Stack-based way to nest function calls

Due to popular demand, nested function calls is now a feature. Here is a taste:

```
注曰「「辛 = 戊(甲,丁(乙,丙))」」
夫「甲」。夫「乙」。夫「丙」。取二以施「丁」。取二以施「戊」。名之曰「辛」。
```

More complex example for the courageous:

```
注曰「「壬 = 丁(己(戊(甲,丁(乙,丙))),甲,乙)」」
夫「甲」。夫「乙」。夫「丙」。取二以施「丁」。取二以施「戊」。取一以施「己」。夫「甲」。夫「乙」。取三以施「丁」。名之曰「壬」。
```

## How it works

The original syntax of wenyan already employs a stack-like behavior. You can use `` to refer to the previous unnamed variable, you can use `書之` to print all the unnamed variables, use `名之曰` to name them etc. Therefore, it is natural to use the same system for function calls.

Now I'll refer to the "list of unnamed variables" as the "stack" for convenience.

`` keyword pushes a variable in into the stack. `取n` marks the last `n` items on the stack as "usable". `以施f` takes all the items marked "usable" and apply function `f` that takes those items as arguments, and push the result onto the stack. Finally you can use `名之曰` to take stuff from back the stack and give them names for later use.

Recap on other features that already existed before this update:

- `` Clears the stack, discarding everything.
- `` Refers to the most recent item on the stack. It also clears the stack. The reason for this is not techincal, but is purely done from Classical Chinese readability standpoint: if you use multiple `` in a row, it can be very confusing: `加其以其。乘其以其。昔之其者。今其是矣。`. Hence.

More examples, showing that you can also push items of an Array, math results, and so on to stack:

```
注曰「「庚 = 丁(甲+乙,癸[3],癸.length)」」
加「甲」以「乙」。夫「癸」之三。夫「癸」之長。取三以施「丁」。名之曰「庚」。
```

You can find more examples in `./examples/nested_fun.wy`

A thank you to @Lotayou and everyone for the discussion in #285 and #301. More functional programming goodies are on their way!

## Automatically curried functions

functions in wenyan are now automatically curried, that is, partially applied to return a new function.

```
吾有一術。名之曰「丁」。欲行是術。必先得三數。曰「寅」曰「卯」曰「辰」乃行是術曰。
乘「寅」以「卯」。加其以「辰」。乃得其。
是謂「丁」之術也。
施「丁」於一於二。名之曰「半丁」。
施「半丁」於三。書之。
```

compiles to

```
var 丁 = () => 0;
丁 = function(寅) {
return function(卯) {
return function(辰) {
var _ans1 = 寅 * 卯;
var _ans2 = _ans1 + 辰;
return _ans2
};
};
};
var _ans3 = 丁(1)(2);
var 半丁 = _ans3;
var _ans4 = 半丁(3);
console.log(_ans4);
```

Again, more FP on its way.
10 changes: 9 additions & 1 deletion documentation/Testing.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
[Back to README](../README.md)

## Testing

This project uses [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/) for unit testing and snapshot testing.

You can run all the tests by
You will need to build first

```bash
npm run build
```

Then you can run all the tests by

```bash
npm test
Expand Down
77 changes: 77 additions & 0 deletions documentation/Try-Catch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
[Back to README](../README.md)

# Try-Catch

```
姑妄行此。
嗚呼。「「滅頂」」之禍。
如事不諧。豈「「ReferenceError」」之禍歟。
吾有一言。曰「「本無此物。奈何用之」」。書之。
豈「「SyntaxError」」之禍歟。
吾有一言。曰「「不合文法。不通之甚」」。書之。
豈「「TypeError」」之禍歟。
吾有一言。曰「「物各其類。豈可混同」」。書之。
豈「「滅頂」」之禍歟。
吾有一言。曰「「嗚呼哀哉。伏维尚飨」」。書之。
不知何禍歟。名之曰「奇禍」。
吾有一言。曰「「人坐家中。禍從天降」」。書之。
乃作罷。
```

Which is roughly equivalent to this JavaScript:

```JavaScript
try {
var e = new Error(); e.name = "滅頂"; throw e;
} catch(e) {
if (e.name == "ReferenceError") {console.log("本無此物。奈何用之")}
else if (e.name == "SyntaxError") {console.log("不合文法。不通之甚")}
else if (e.name == "TypeError") {console.log("物各其類。豈可混同")}
else if (e.name == "滅頂") {console.log("嗚呼哀哉。伏维尚飨")}
else {var err = e; console.log("人坐家中。禍從天降")}
}

```

If you do not need to catch the errors, you can do:

```
姑妄行此。
嗚呼。「「無足輕重」」之禍。
如事不諧乃作罷。
```

Which roughly equals to:

```JavaScript
try{
var e = new Error(); e.name = "無足輕重"; throw e;
}catch(_){}
```

You can also do this to catch any error:

```
姑妄行此。
嗚呼。「「事不關心」」之禍。
如事不諧。不知何禍歟。書之。乃作罷。
```

Which roughly equals to:

```JavaScript
try{
var e = new Error(); e.name = "事不關心"; throw e;
}catch(e){
console.log(e);
}
```

You can see details about the usage in `./examples/try.wy`.
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
| [sieve.wy][30] | 埃氏篩 |
| [sqrt_newton.wy][31] | 牛頓求根法 |
| [turing.wy][32] | 圖靈機 |
| [draw_heart.wy][33] | 畫心 |

[1]: https://en.wikipedia.org/wiki/Fizz_buzz "Fizz buzz"
[2]: https://zh.wikipedia.org/wiki/自產生程式 "自產生程式"
Expand Down Expand Up @@ -66,3 +67,4 @@
[30]: sieve.wy
[31]: sqrt_newton.wy
[32]: turing.wy
[33]: draw_heart.wy
Loading

0 comments on commit d06c4eb

Please sign in to comment.