GlueLangのwhere句の実装

Pocket
LINEで送る

 GlueLangは、その場で使うファイルを次のような書き方で作れます。Haskellから拝借しました。bashの$()がコマンドの引数にあると綺麗に見えないので、whereの中にそういう細かい処理は押し込んでしまおうという意図です。

import PATH

#passwdファイルの一番下のユーザの名前でpasswdファイルをgrepする
grep re '/etc/passwd'
  where
    str re = tail -n 1 '/etc/passwd' >>= awk '-F:' '{print $1}'

bashだとこうなります。

grep $( tail -n 1 '/etc/passwd' | awk '-F:' '{print $1}' ) '/etc/passwd'

 これの実装をするにはスコープを真面目に設計・実装する必要がありますが、GlueLangはシェルなので、基本「スコープはforkしたときに持っていた情報の範囲」で良く、whereのためだけにスコープを作ることになります。これがこれまでグダグダだったので、昨夜遅くコソコソと直してました。具体的には、

  • 変数に、どのジョブに属するのかIDをつける
  • 各要素が解釈されたときに、要素のインスタンスにこれまで分岐してきたジョブのリストを渡す
  • 変数を探すときに、そのリストの逆向きたどる

という処理を加えました。リストを解釈された要素全部に渡すので無駄なのと、ジョブが消えても変数が残ったままになっているという状況ですが、あとから改善します。

Pocket
LINEで送る

GlueLangにループを実装

Pocket
LINEで送る

 帰省中に少し時間があったので、GlueLangにループを実装しました。次のように使います。この例は、dateにUnix時刻を吐かせて、5で割り切れる数になったらループを抜ける処理です。testコマンドが0でない終了ステータスを返したのを受けてループが終わって最終行のechoが実行されます。

$ cat hoge.glue 
import PATH

loop
  str t = date '+%s' >>= awk '{print $1%5}'
  echo t
  test t -ne 0
  sleep 1

echo 'end'

 実行すると、ちゃんと動きます。これはMacで動かしましたが同じコードでLinuxでも動きます。

$ glue ./hoge.glue 
1
2
3
4
0
end

shのwhileのように書くには

 shやbashのように、 while <コマンド> ; do <処理> ; done と書く場合、つまりコマンドの終了ステータスで処理を実行するかしないかを決めるときは、1段ネストが深くなりますが、次のように記述できます。

$ cat hoge2.glue 
import PATH

loop
  str t = date '+%s' >>= awk '{print $1%5}' #この行と
  test t -ne 0 >> do                        #この行のdoの前までが条件
    echo t                                  #doのあとが繰り返したい処理
    sleep 1

echo 'end'

 ネストが2段になりますが、shやbashのwhileよりも長く条件となるコマンドが書けます。だいたい、while hogehoge ; do …という書き方が、hogehogeという部分をコマンドだと気づかない初心者を量産しており悪い影響を与えているので、踏襲するわけにはいけません。

文法エラーの時に止める

で、シェルでループを作るとCtrl+Cやスクリプトにエラーが思うように止まらない場合がありますが、GlueLangでは止められるように工夫をしました。次の例は、コマンドが見つからない時にすぐにループを止めて、最終行の echo ‘end’ が実行されないことを確かめる例です。

$ cat hoge3.glue 
import PATH

loop
  str t = date '+%s' >>= awk '{print $1%5}'
  eho t     #ここでエラーが起こって処理全体が止まる
  sleep 1
  test t -ne 0

echo 'end'  #これは実行されない

 GlueLangでは(まだ実装が中途半端ですが)「コマンドが実行されて返ってくる終了ステータス」と「コマンドが見つからない、あるいはGlueLangのスクリプト自体が出すエラー」を区別することにしました。技術的には可能ですし、これは普通のシェルよりもエラーへの対応がかなりスマートになるのではないかと考えています。

$ glue ./hoge3.glue 

Parse error at line 2, char 1
	line2: eho t
	       ^

	Command eho not exist
	
	process_level 1
	exit_status 2
	pid 30839

	glue exit_status: 2

Execution error at line 3, char 1
	line3: loop
	       ^
	line4:   str t = date '+%s' >>= awk '{print $1%5}'
	line5:   eho t
	line6:   sleep 1
	line7:   test t -ne 0
	line8: 

	Command error
	
	process_level 0
	exit_status 2
	pid 30837
###echo 'end'が実行されずに終わる###

 ただ、現状で先ほどのように2段にネストした場合、止まらないのでまた来週末あたり改良します。また、readも実装しないといけません・・・。

Pocket
LINEで送る

GlueLangの仕切り直しメモ

Pocket
LINEで送る

突然情報の学科からロボットの学科に戻ることになって止まっていたGlueLangの開発をちょぼちょぼと再会することにしました。

ただ、ドキュメントがないと開発の指針も立たないし、何やってるか外から分からないので、ドキュメントを作っていくことにしました。

ドキュメントはこちらです。このドキュメントのソースはこっちです。

GlueLangのリポジトリはこちらです。

Pocket
LINEで送る

GlueLangのif文相当の処理をまたいじったがこれで最後にしたい

Pocket
LINEで送る

眠いです。

GlueLangのif文及びその周辺、またいじりました。

やっぱり波括弧やめた

前回、複合コマンドをこんなふうに書くようにしましたが・・・

uedambp:SRC ueda$ cat hoge 
#!/usr/local/bin/glue
import PATH

{
	echo 'abc'
	echo 'def'
} >>= rev
uedambp:SRC ueda$ ./hoge 
cba
fed

こうしました。やっぱりHaskell, Python系の書き方にしようとしているのに波括弧はあまり合わんという判断。波括弧が最終行の最後にあったら認識しないようになってましたし・・・(アカン)。doの次の行からがサブシェル扱いされます。最初の行のインデントがオフサイドラインになります。

uedambp:GlueLang ueda$ cat huge.glue 
#!/usr/local/bin/glue
import PATH

do
	echo 'abc'
	echo 'def'
>>= rev
uedambp:GlueLang ueda$ ./huge.glue 
cba
fed

procにもdoが必要に

これに伴い、procで2行以上書くときにもdoが必要ということにしました。イコールの後に一行で書くときは不要です。

uedambp:GlueLang ueda$ cat hoge.glue 
#!/usr/local/bin/glue
import PATH

proc hoge = do
	echo 'abc'
	echo 'def'

hoge >>= rev
uedambp:GlueLang ueda$ ./hoge.glue 
cba
fed

if文の表現

んで、最終的にif文に相当する表現は次のようになりました。前回の

#!/usr/local/bin/glue
import PATH

{
	false
	echo 'hoge'
} !> {
	echo 'foo'
} !> {
	echo 'bar'
}

は、

uedambp:GlueLang ueda$ cat hoge.glue 
#!/usr/local/bin/glue
import PATH

do
	false
	echo 'hoge'
!> do
	echo 'foo'
!> do
	echo 'bar'

となりました。

ただ、この書き方だと前回言ったようにサブシェル内のコマンドが全て条件文になってしまう(if文というよりもtryみたいになる)ので、ちゃんと条件と条件が満たされたときに実行される部分を分けたいときは、

uedambp:GlueLang ueda$ cat if1.glue 
#!/usr/local/bin/glue
import PATH

test 1 -eq 2 ? do
	echo 'first subshell'
	echo '1 = 2'
!> test 1 -eq 1 ? do
	echo 'second subshell'
	echo '1 = 1'
!> echo 'third command'
###実行###
uedambp:GlueLang ueda$ ./if1.glue 
second subshell
1 = 1

と書いてもらうことにしました。?の左側に条件、右側に条件がtrueのときに実行される部分を書きます。別にサブシェルを使う必要のないときは、

uedambp:GlueLang ueda$ cat if2.glue 
#!/usr/local/bin/glue
import PATH

test 1 -eq 2    ?  echo '1 = 2'
!> test 1 -eq 1 ?  echo '1 = 1'
!> echo 'third command'

となります。ちょっとスッキリしませんが、if文自体あんまり使うことは無いはずなので、これでよしとしたいです。

実は「?」は、「!>, >>, >>=」と同じグループの演算子なので基本的にこれはif文でなくコマンドを接続しているだけです。ですので、

uedambp:GlueLang ueda$ cat if3.glue 
#!/usr/local/bin/glue
import PATH

test 1 -eq 2 ? echo '1 = 2' !> test 1 -eq 1 ? echo '1 = 1' !> echo 'third command'

と書いても動きますが、さすがにインデント入れないと可読性皆無になりますね。

ところで、だれかGlueLangの開発についてこれてますかね???

あかん。孤立気味だ。

寝る。

Pocket
LINEで送る

GlueLangのif文相当の処理をガラッと変えてみた

Pocket
LINEで送る

今日は息抜きにGlueLangをいじっておりました。といっても言語の開発なので、処理系のバグと、スクリプトのバグの両方に気をつけなければならず、なかなかイライラするものですが・・・

機能追加1: 複合コマンド

続きを読む GlueLangのif文相当の処理をガラッと変えてみた

Pocket
LINEで送る

OSCでのGlueLangの発表無事終了

Pocket
LINEで送る

金曜日にもかかわらず30人くらいに話を聞いていただきました。質問もたくさんありがとうございました。

取り急ぎ。

Pocket
LINEで送る

日記(実験データ解析にGlueLang投入から慌ててwhileを実装)

Pocket
LINEで送る

昨日から実験データの解析をしており、締め切りが遠いことからGlueLangを投入してみました。これが記念すべき最初のコードです。書きなぐりなので意味を追って読まないでください。

続きを読む 日記(実験データ解析にGlueLang投入から慌ててwhileを実装)

Pocket
LINEで送る

GlueLangが変態言語になるかどうかの瀬戸際である

Pocket
LINEで送る

本日は久々にGlueLangを作りこんでいました。読んでてもほとんどの人が分からんと思いますが作業日誌です。いや、読んでも分からんとか言ってたら絶対普及しないので、この前LTやったスライドを貼り付けときます。

ファイルや変数に直接文字列を指定可能に

今まではechoを書かないとファイルや文字列に文字が入って行きませんでしたが、要らなくなりました。

uedambp:GlueLang ueda$ cat fuge.glue 
import PATH

file f = 'abc'
str s = 'cde'

cat f
echo s

続きを読む GlueLangが変態言語になるかどうかの瀬戸際である

Pocket
LINEで送る

GlueLangのLTやった(シェル書いてますが何か?)

Pocket
LINEで送る

とりいそぎ。シェル芸勉強会については問題をアップしました。後日まとめます。皆様ありがとうございました。

Pocket
LINEで送る

今日のGlueLang開発日誌(シグナル処理、whereでの条件指定等)

Pocket
LINEで送る

今週末も時間をやりくりしながらGlueLangの開発を進めました。昨日の作業に加え、今日はシグナル処理を改善して、中間ファイルと作業ディレクトリが残らないようにしました。ただ、何でちゃんと動くのか分からないという有様なので、dashのコードを読んでちゃんと勉強せんといかんなあと思います。

あと、2月末にとうとうお披露目のプレゼンをするかもしれないので、次のような機能をデモ程度に実装しました。

続きを読む 今日のGlueLang開発日誌(シグナル処理、whereでの条件指定等)

Pocket
LINEで送る