オレオレ言語を作っている

# 動機

* JSで素のWebGLをいじってゲームを作ろうとしていた。
* GLSLで静的型付け言語の良さを再認識する。
* JSからWebGLをいじってると、型変換のオーバーヘッドがちょっと気になってくる。
* JSでのベクトルと行列の演算処理を書くのは面倒くさい。しかしGLSLのベクトルと行列の演算機能はよくできてて、JSもこんな感じでベクトル演算を書ければ楽なのになあと思う。
* WebAssemblyができてメジャーブラウザで使えるようになる。これはまあLLVMのWeb版とも言える仕様。つまり言語が作れる！
* 調べるともうすでに[emscripten](http://kripken.github.io/emscripten-site/)がサポート、[AssemblyScript](https://github.com/AssemblyScript/assemblyscript)ができていた！
* これ使えばいいかなと思うが、emscriptenはサポートコードがでかい。さらに[AssemblyScript](https://github.com/AssemblyScript/assemblyscript)も試したが、ちょっと私のニーズには合わなさそう。
* でまあGLSLチックなベクトル・行列演算機能を持つC風の言語を作ることにした。

# 何で作っているか

* node.jsと[pratt parser](https://crockford.com/javascript/tdop/tdop.html)のコードをベースに実装している。
* wasm出力は[binaryen.js](https://github.com/sfpgmr/binaryen.js)（emscriptenでwasmにコンパイルして）を使用している。
* とりあえずなにがしかのコンパイルはWebページ上でできるようになっている。
* [検証用ウェブページ](https://github.sfpgmr.net/sgl2/)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/28815/a4bf9e10-6ce2-63dc-d8c5-176870ec1234.png)

# リポジトリ

https://github.com/sfpgmr/sgl2

# 仕様の概要（現時点で考えてること）

* 静的型付け
* 自由文脈形式 
* C風かつwasmを強く意識した構文
  * そのままwasmにコンパイルされ、余計なサポートコードを極力吐かない
* ユーザー定義型（カスタム型）が定義・使用可能
  * classなどは持たないかもしれない
* ガベージコレクションは行わない
* wasmの線形メモリに破壊的にアクセスできる
    * ヒープ/フリーストアのようなメモリ管理機構は持たない。ただしライブラリで書けるレベルの構文は用意する。
* ベクトル・行列演算機能をGLSLのようにビルトインで持つ
* コルーチンを言語機能として持つ

# 仕様詳細（まとめ中）
   
# 進捗状況

* 2018年3月ころから実装し始めたが、まだまだ道半ばといった感じ。。

# 実装状況のレポーティング

* まだまだ実装中
* 実装状況はTwitterでつぶやき、それをTogetterでまとめている

https://togetter.com/li/1266927

# コンパイルのサンプル

* まだまだこの程度しかコンパイルできません。。

## その１

### ソース
```
// 関数 日本語使用可能
i32 𩸽(i32 a,i32 b){
    return a * b;
};

// メイン 
export i32 main(){
  i32 b = 0;

  for(i32 c = 0;c < 4;++c) {
    b = b + 1;
  }
  return 𩸽(b,b);// 4
};

```
### 動くサンプル

[動くサンプル](https://github.sfpgmr.net/sgl2/?Ly8g6Zai5pWwIOaXpeacrOiqnuS9v+eUqOWPr+iDvQppMzIg8Km4vShpMzIgYSxpMzIgYil7CiAgICByZXR1cm4gYSAqIGI7Cn07CgovLyDjg6HjgqTjg7MgCmV4cG9ydCBpMzIgbWFpbigpewogIGkzMiBiID0gMDsKCiAgZm9yKGkzMiBjID0gMDtjIDwgNDsrK2MpIHsKICAgIGIgPSBiICsgMTsKICB9CiAgcmV0dXJuIPCpuL0oYixiKTsvLyA0Cn07Cg==)


### コンパイル結果
```
(module
 (type $𩸽 (func (param i32 i32) (result i32)))
 (type $main (func (result i32)))
 (memory $0 1 1)
 (export "main" (func $main))
 (func $𩸽 (; 0 ;) (type $𩸽) (param $0 i32) (param $1 i32) (result i32)
  (return
   (i32.mul
    (get_local $0)
    (get_local $1)
   )
  )
 )
 (func $main (; 1 ;) (type $main) (result i32)
  (local $0 i32)
  (local $1 i32)
  (set_local $0
   (i32.const 0)
  )
  (block
   (block $for0
    (set_local $1
     (i32.const 0)
    )
    (loop $loop1
     (br_if $for0
      (i32.eqz
       (i32.lt_s
        (get_local $1)
        (i32.const 4)
       )
      )
     )
     (block
      (set_local $0
       (i32.add
        (get_local $0)
        (i32.const 1)
       )
      )
     )
     (set_local $1
      (i32.add
       (get_local $1)
       (i32.const 1)
      )
     )
     (br $loop1)
    )
   )
  )
  (return
   (call $𩸽
    (get_local $0)
    (get_local $0)
   )
  )
 )
)
```

## その２：ユーザー定義型（カスタム型） 

### ソース

```
  type Bar {
  public:
    i32 barA = 3;
    i32 barB = 4;
  };
  
  type Foo {
  public:
    i32 a = 1;
    i32 b = 2;
    Bar c;
  };
  
  export i32 main(){
    Foo foo,foo1;
    foo.a = 2;
    foo1 = foo;  
    foo.a = 10;
    return foo.a * foo1.a;
  };
```
### 動くサンプル（コンパイル結果）

[動くサンプル（コンパイル結果）](https://github.sfpgmr.net/sgl2/?ICB0eXBlIEJhciB7CiAgcHVibGljOgogICAgaTMyIGJhckEgPSAzOwogICAgaTMyIGJhckIgPSA0OwogIH07CiAgCiAgdHlwZSBGb28gewogIHB1YmxpYzoKICAgIGkzMiBhID0gMTsKICAgIGkzMiBiID0gMjsKICAgIEJhciBjOwogIH07CiAgCiAgZXhwb3J0IGkzMiBtYWluKCl7CiAgICBGb28gZm9vLGZvbzE7CiAgICBmb28uYSA9IDI7CiAgICBmb28xID0gZm9vOyAgCiAgICBmb28uYSA9IDEwOwogICAgcmV0dXJuIGZvby5hICogZm9vMS5hOwogIH07)

## その３：ポインタ

### ソースコード

```
export i32 main(){
  i32 p = 0;// メモリオフセット0をポインタにセット
  *p = 32.0f;// floatの値を保存
  u32 a = *p;// float値をu32値として取り出し
  return a;
};
```

### 動くサンプル（コンパイル結果）

[動くサンプル（コンパイル結果）](https://github.sfpgmr.net/sgl2/?ZXhwb3J0IGkzMiBtYWluKCl7CiAgaTMyIHAgPSAwOy8vIOODoeODouODquOCquODleOCu+ODg+ODiDDjgpLjg53jgqTjg7Pjgr/jgavjgrvjg4Pjg4gKICAqcCA9IDMyLjBmOy8vIGZsb2F044Gu5YCk44KS5L+d5a2YCiAgdTMyIGEgPSAqcDsvLyBmbG9hdOWApOOCknUzMuWApOOBqOOBl+OBpuWPluOCiuWHuuOBlwogIHJldHVybiBhOwp9OwogICAgICA=)

## その４：型エイリアス

### ソースコード

```
export i32 main(){
  // type エイリアス
  type& T = i32;        
  type& T1 = T;
  
  T a = 1; 
  T1& b = a; 
  ++a;
  b += 2;
  return a;// 4
};
```

### 動くサンプル（コンパイル結果）

[動くサンプル（コンパイル結果）](https://github.sfpgmr.net/sgl2/?ZXhwb3J0IGkzMiBtYWluKCl7CiAgLy8gdHlwZSDjgqjjgqTjg6rjgqLjgrkKICB0eXBlJiBUID0gaTMyOyAgICAgICAgCiAgdHlwZSYgVDEgPSBUOwogIAogIFQgYSA9IDE7IAogIFQxJiBiID0gYTsgCiAgKythOwogIGIgKz0gMjsKICByZXR1cm4gYTsvLyA0Cn07Cg==)

## その５：const変数

### ソースコード

```
const WIDTH = 320;
const HEIGHT = 240;

export i32 main(){
  i32 a = WIDTH * HEIGHT;
  return a;// 76800
};

```

### 動くサンプル（コンパイル結果）

[動くサンプル（コンパイル結果）](https://github.sfpgmr.net/sgl2/?Y29uc3QgV0lEVEggPSAzMjA7CmNvbnN0IEhFSUdIVCA9IDI0MDsKCmV4cG9ydCBpMzIgbWFpbigpewogIGkzMiBhID0gV0lEVEggKiBIRUlHSFQ7CiAgcmV0dXJuIGE7Ly8gNzY4MDAKfTsK)

## その６：reinterpret cast

### ソースコード

```
export f64 main(){
  i64 a = 0x3fc4 0000 0000 0000xl;// f64を整数値として代入
  f64 b = (^f64)a;// reinterpret cast

  return b;// 0.15625
};

```

### 動くサンプル（コンパイル結果）

[動くサンプル（コンパイル結果）](https://github.sfpgmr.net/sgl2/?ZXhwb3J0IGY2NCBtYWluKCl7CiAgaTY0IGEgPSAweDNmYzQgMDAwMCAwMDAwIDAwMDB4bDsvLyBmNjTjgpLmlbTmlbDlgKTjgajjgZfjgabku6PlhaUKICBmNjQgYiA9ICheZjY0KWE7Ly8gcmVpbnRlcnByZXQgY2FzdAoKICByZXR1cm4gYjsvLyAwLjE1NjI1Cn07Cg==)

## その７：キャスト

### ソースコード

```
// キャストの実装（ネイティブ型同士のみ）
export i32 main(){
  i32 b = 10;
  f64 c = (f64)b + 10.0lf;
  return (i32)c;
};


```

### 動くサンプル（コンパイル結果）

[動くサンプル（コンパイル結果）](https://github.sfpgmr.net/sgl2/?Ly8g44Kt44Oj44K544OI44Gu5a6f6KOF77yI44ON44Kk44OG44Kj44OW5Z6L5ZCM5aOr44Gu44G/77yJCmV4cG9ydCBpMzIgbWFpbigpewogIGkzMiBiID0gMTA7CiAgZjY0IGMgPSAoZjY0KWIgKyAxMC4wbGY7CiAgcmV0dXJuIChpMzIpYzsKfTsK)

## その８：数値リテラル

### ソースコード

```
export i32 main(){
  i32 a = 0x1 00x;// 16進リテラル（スペースで値が区切れる）
  ,b = 0b1 0000 0000 b;// 2進数リテラル
  if( a == b){
    return 1;
  } 

  return 0;
};



```

### 動くサンプル（コンパイル結果）

[動くサンプル（コンパイル結果）](https://github.sfpgmr.net/sgl2/?CmV4cG9ydCBpMzIgbWFpbigpewogIGkzMiBhID0gMHgxIDAweAogICxiID0gMGIxIDAwMDAgMDAwMCBiOy8vIDI1NgogIGlmKCBhID09IGIpewogICAgcmV0dXJuIDE7CiAgfSAKCiAgcmV0dXJuIDA7Cn07Cg==)