はじめに
この記事は、2024年7月に投稿した記事 SQLをmruby、mruby/c、Arduinoのソースコードに変換 の完全版です。
RubyでSQLをmruby、mruby/c、Arduinoのソースコードに変換するツールを作りました。
最終的なソースコードは GitHub にあります。
このツールは RubyGems に公開しています。以下のコマンドでインストールできます。
gem install rossoc
使い方
例えば、SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9) のようなSQLは以下のようなコードに変換されます。mruby、mruby/cのCommon I/O APIに対応しています。
# SELECT `din11` FROM `mruby` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9)
GPIO.setmode(11, GPIO::IN)
GPIO.setmode(1, GPIO::IN)
GPIO.setmode(2, GPIO::IN)
GPIO.setmode(3, GPIO::IN)
uart1 = UART.new(1)
while 1 do
din11 = GPIO.read(11)
din1 = GPIO.read(1)
din2 = GPIO.read(2)
din3 = GPIO.read(3)
if ((din1 == 0 && din2 <= 1) || din3 != 9)
uart1.puts("din11=#{din11}")
end
end
この mruby コードは次のコマンドで出力できます。
rossoc query -i 'SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9)' -o test.rb
SELECTステートメントをサポートしています。
カラムには din1 から din20 と ain1 から ain20 を指定できます。dinはデジタルピン、ainはアナログピンです。
テーブル名には mruby と arduino を指定できます。
独自キーワード
独自キーワード RSLEEP を実装しています。RSLEEPの単位は秒で、指定した秒数分、処理を停止します。
rossoc query -i 'SELECT din11 FROM mruby WHERE ((din1 = 0 AND din2 <= 1) OR din3 <> 9) RSLEEP 100' -o test.rb
この mruby のコードを以下のようになります。
# SELECT `din11` FROM `mruby` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9) RSLEEP 100
GPIO.setmode(11, GPIO::IN)
GPIO.setmode(1, GPIO::IN)
GPIO.setmode(2, GPIO::IN)
GPIO.setmode(3, GPIO::IN)
uart1 = UART.new(1)
while 1 do
din11 = GPIO.read(11)
din1 = GPIO.read(1)
din2 = GPIO.read(2)
din3 = GPIO.read(3)
if ((din1 == 0 && din2 <= 1) || din3 != 9)
uart1.puts("din11=#{din11}")
end
sleep(100)
end
同じく、 Arduino のコードは以下のようになります。
// SELECT `din11` FROM `arduino` WHERE ((`din1` = 0 AND `din2` <= 1) OR `din3` <> 9) RSLEEP 100
void setup() {
Serial.begin(9600);
pinMode(11, INPUT);
pinMode(1, INPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
}
void loop() {
int din11 = digitalRead(11);
int din1 = digitalRead(1);
int din2 = digitalRead(2);
int din3 = digitalRead(3);
if((din1 == 0 && din2 <= 1) || din3 != 9) {
Serial.print("din11=");
Serial.println(din11);
}
delay(100000);
}
生成されたソースコードをみると sleep
というコードが追加されています。
仕組み
このツールはフロントエンドとバックエンドから構成されています。 独自のIR(中間表現)を介してフロントエンドとバックエンドを接続しています。フロントエンドは、字句、構文、意味解析を実行します。 バックエンドは、ターゲットのコードを生成します。
さいごに
実験的なツールのため予告なしに仕様変更することがあります。