Processingで式評価するQScriptライブラリの使い方

# はじめに

https://qiita.com/hextomino/items/1b172c9ab61c001f6d2a

JavaScriptやPythonには存在する式評価の関数「eval」をProcessingで実現するライブラリjasmine。本投稿は同作者のQScriptの使い方についてのメモ。両者は似ている。

# 環境
Processing 4.3
Windows 11
Mac 13.4.1
QScript 2.1.2

# インストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/7d4e8e5a-5282-7b31-da50-25c02595a2d5.png)

# 最初のプログラム

```math
\sqrt{5^2+12^2}=13
```
を求めるプログラム。Stringで式を書いて、評価。
```java:Processing
import org.qscript.*;

String f = "sqrt(5^2 + 12^2)";
Result res = Solver.evaluate(f);
print(res);
```

```:出力
13.0
```

# 変数が混ざった数式
```math
x=2
```
```math
x^3=8
```
※Ver2から変数の前に$をつける必要はなくなった。
;で文を分ける。
```java:Processing
import org.qscript.*;

String f = "x=2; x^3";
Result res = Solver.evaluate(f);
print(res);
```
```:出力
8.0
```

# 数式を複数行に分けて書く
複数行で書くためには、配列を使う。

```java:Processing
import org.qscript.*;

String[] f = {
  "x=2",
  "x^3"
};
Result res = Solver.evaluate(f);
print(res);
```
```:出力
8.0
```

# 数式にprint文をいれる

```java:Processing
import org.qscript.*;

String[] f = {
  "x=2",
  "r=x^3",
  "println(r)"
};
Solver.evaluate(f);
```

```:出力
8.0
```

# 数式内の変数の値を、別途指定する
```java:Processing
import org.qscript.*;

String f = "sqrt(x^2+y^2)";

Script s = new Script(f);
s.storeVariable("x", 5);
s.storeVariable("y", 12);
print(Solver.evaluate(s));
```
```:出力
13.0
```

# REPEAT文
```java:Processing
import org.qscript.*;

String[] f = {
  "i = 0",
  "REPEAT",
  "  println(i)",
  "  i = i + 1",
  "UNTIL(5 < i)"
};
Solver.evaluate(f);
```
```:出力
0
1
2
3
4
5
```

# WHILE文
```java:Processing
import org.qscript.*;

String[] f = {
  "i = 0",
  "WHILE(i < 5)",
  "  println(i)",
  "  i = i + 1",
  "WEND"
};
Solver.evaluate(f);
```
```:出力
0
1
2
3
4
```

# IF文
0から10まで数えて、
2乗して20未満ならTを表示、
20以上ならFを表示

```java:Processing
import org.qscript.*;

String[] f = {
  "x = 0",
  "REPEAT",
  "  IF(x^2 < 20)",
  "    print('T')",
  "  ELSE",
  "    print('F')",
  "  ENDIF",
  "  x = x + 1",
  "UNTIL(10 < x)"
};
Solver.evaluate(f);
```
```:出力
TTTTTFFFFFF
```

# エラー表示
エラーがあると、以下のように、何行目の何文字目が問題になっているか、指摘される。
```
TVariable ({0}) must be initialised before use in line: 8 : at char: 11
```

# 複素数
精度誤差があるが使える。
```java:Processing
import org.qscript.*;

String[] f = {
  "c = C(0,1)",
  "c^2"
};
Result res = Solver.evaluate(f);
print(res);
```
```:出力
{ -1.0 + 1.2246467991473532E-16i }
```

# 定数
PIとかEとか使える。
```java:Processing
import org.qscript.*;

String f = "cos(PI)";
Result res = Solver.evaluate(f);
println(res);
```
```:出力
-1.0
```

# ウィンドウ内に表示
計算結果を文字列に変換して表示する。
```java:Processing
import org.qscript.*;

public void setup() {
  String f = "cos(PI)";
  Result r = Solver.evaluate(f);
  fill(0);
  text(r.answer.toString(), 20, 20);
}
```

# 円の内外判定をして、塗りつぶし
```java:Processing
import org.qscript.*;

size(256, 256);

String f = "x^2+y^2-1";
Script s = new Script(f);

int xx=0, yy=0;
for (float y=-2; y<2; y+=4f/height) {
  for (float x=-2; x<2; x+=4f/width) {
    s.storeVariable("x", x);
    s.storeVariable("y", y);
    Result r = Solver.evaluate(s);
    if (0<r.answer.toFloat())
      set(xx, yy, color(255));
    else
      set(xx, yy, color(0));
    xx++;
    xx%=width;
  }
  yy++;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/366b28de-43a1-f5c7-db32-c795813e199d.png)




# ライブラリに添付のサンプル
・定数の追加
・イベントの追加
・演算子の追加
・２次元グラフ
・マンデルブロ
・素数
など。
場合によって、G4PやGraphicaライブラリが必要らしい。

# 関連リンク

QScriptサイト
リファレンスなど
http://www.lagers.org.uk/qscript/index.html