processingでevalをするjasminライブラリ

# はじめに
　電卓のようなものを作りたいとき、数式をプログラムに認識させる必要があります。数式をコードとして書く場合、いちいち、止めて、再実行する必要があり面倒です。しかし、実行中に、数式を認識させるには、数字や演算記号やカッコを認識させる必要があり、これも面倒。
　で、evalという便利な関数を見つけましたが、javascriptやpythonでは実装されているものの、java,Processingにはありません。ですが、いいライブラリがあったので、メモします。

# 環境
Mac OSX 11.6
Processing 3.5.4

ライブラリ（Processingの管理ツールからインストール）
ControlP5 2.2.6
Jasmine 1.1

jasmine開発者サイト
http://www.lagers.org.uk/jasmine/index.html

# 実装例
　テキストボックスに数式を書いてエンターで、その式の結果を表示します。基本的な算術関数も全て網羅されているので、困ることはないでしょう。変数表記も使えます。
　驚いたことに、このControlP5のテキストボックスは履歴が遡れます。カーソルキーの上を押すと履歴が出るので、Unixのコマンドラインのような使い方ができて、自前実装する手間が省けました。
![evil.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/6b87e803-79e6-6988-c8ad-d705a6ce1711.png)



```java:eval.pde
import controlP5.*;
import org.quark.jasmine.*;

ControlP5 cp5;
PFont font;

void setup() {
  background(0);
  size(400, 300);
  font = createFont("Arial", 24);

  cp5 = new ControlP5(this);
  cp5.addTextfield("input")
    .setFont(font)
    .setSize(200, 24);

  textFont(font);
}

void draw() {
}

void keyPressed() {
  if (key == ENTER) {
    background(0);
    String s = cp5.get(Textfield.class, "input").getText();
    text(s, 20, 100);

    //eval
    Expression e = Compile.expression(s, false);
    float f = e.eval().answer().toFloat();
    text(f, 20, 150);
  }
}
```
# 変数ありの方程式
x,yの２変数がある式の場合、eval(2,3)のように値を受け渡す。
```java:processing
import org.quark.jasmine.*;

String s = "x^2+y^2";
Expression e = Compile.expression(s, false);
float f = e.eval(2, 3).answer().toFloat();
print(f); //13.0
```
# おまけ
　このライブラリで「1/3*3」を計算したところ、0.999ではなく、1と出ました。優秀です。

# 愚かな自分へのメモ
また、同じ調べ物をしてしまった。
2021年10月28日にこれを投稿したのを忘れて、再度、evalについて調べ直していた。そして、自分の記事にたどり着いた。2023年9月19日


追加で得た情報をメモする
javaからjavascriptを呼び出す方法がある。
```java:se.pde
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");

try {
  double ans = (Double)engine.eval("1.1*1.1");
  print(ans);
}
catch (ScriptException e) {
  e.printStackTrace();
}
```
ただし、processing4では動かず、processing3では動く。
processing3はjava8
processing4はjava17
であることが原因。
jsの部分をNashorn,Graal.js,v8,ChakraCoreに変えてみてもp4では全部ダメ。
コードの互換性として、不安が残る。
また、sqrtとかpowとか^は使えない。

「jasmineライブラリはsqrtとかpowとか^とか使える」
素晴らしい。


同じ作者が作る別のライブラリ「QScript」を見つけた。
こちらは、VBのようなスクリプトを書いておき、processingプログラム実行中に、スクリプトを編集できるようなシロモノ。

その他、python modeでevalを使い、コマンドラインで引数を渡そうと思ったけど、コンパイルできそうにないので、却下。


# jasminで複素数は扱えない
log(-1)はNan(非数)になる。
```java
print(log(-1));  //NaN
```

jasminでlog(-1)を計算すると、やはりNaNになる。

```java
import org.quark.jasmine.*;

String s = "log(-1)";
Expression e = Compile.expression(s, false);
println(e.eval().answer().toFloat());  //NaN
```
複素数を使いたいときは、complexnumberライブラリを使う
```java
import complexnumbers.*;

Complex z = new Complex(-1,0);
z=z.ln();
println(z);  //3.141592653589793i
double r = z.re;  //0.0
double i = z.im;  //3.141592653589793
println(r,i);

import java.io.*;

// write
try{
  OutputStream os = createOutput("out.dat");
  DataOutputStream dos = new DataOutputStream(os);
  dos.writeDouble(r);
  dos.writeDouble(i);
  dos.flush();
  dos.close();
}catch(IOException e){
  e.printStackTrace();
}

// load
try{
  InputStream is = createInput("out.dat");
  DataInputStream dis = new DataInputStream(is);
  double r2 = dis.readDouble();
  double i2 = dis.readDouble();
  dis.close();
  println(r2,i2);
}catch(IOException e){
  e.printStackTrace();
}
```