tinkaは西暦2019年の1月ごろに、大幅な仕様変更がされました。
このページは、仕様変更以前のtinkaについて書いています。
プログラミング言語 tinka は、phil.2021年(?)にskarsna.haltxeafisによって開発された、2003f向けのプログラミング言語です。
2003lkに比べて、より簡単にプログラムが書けるように設計されています。
本書では、ある程度2003fでのプログラミングが分かっている人向けに、tinkaの解説をします。
tinkaの本家実装はNobuyuki-Tokuchi/old_tinkaにありますが、使うためにはJDK、Kotlin、別途2003lkを実行できるものが必要になります。
WebIDEでは、エディタの下でtinkaを選択することで手軽に実行できるので、こちらをお勧めします。
まず、プログラムの全体を、下で示すように囲っておきましょう。これらの意味は、また後で説明します。
cersva _fasal rinyv (ここにプログラム) situv
最後の行の後には、必ず改行を入れるように気を付けましょう。
変数(anaxkaidzern)は、値を入れることのできる場所です。
anax p
と書くことで、pという名前の変数を作ることができます。
変数には、0から4294967295までの数を入れることができます。
また、数字の解釈を変えることで、-2147483648から2147483647までの数だと考えることもできます。
前者を符号無し(ny snakxaz)、後者を符号付き(snakxazasyk)といいます。
では早速、変数を1つ作って、そこに数を入れてみましょう
cersva _fasal rinyv anax p krz 10 p situv
これで、pという変数に10を入れることができます。
krz
(またはkRz
)というのは、数をコピー(krantairzarth)する命令です。
krz q h
と書くことで、qの数をhにコピーすることができます。
さらに変数を増やしてみましょう。
cersva _fasal rinyv anax p -- 変数pを作る anax F -- 変数Fを作る krz 10 p -- pに10を入れる krz p F -- pの数をコピーしてFに入れる situv
--
より後の部分は、行の終わりまでコメントになります。
コメントはプログラムには影響しません。説明や補足などを自由に書くことができます。
このプログラムを実行すると、最終的に変数pも変数Fも、中身は10になります。
変数を使うときの注意点がいくつかあります。
まず、変数を作るanax
は、プログラムの最初の方にまとめて書くこと。
次のようなプログラムは、よくありません。
cersva _fasal rinyv anax p krz 10 p anax F krz p F situv
変数を作ったときには、まだ中にどんな数が入っているのか分かりません。
必ず、変数の中の数を使うより前に、そこには数を入れておきましょう。
cersva _fasal rinyv anax p anax F krz p F -- 中身の分からない変数pの数をコピーしてFに入れる situv
2003fは計算機です。まずは足し算からやってみましょう
cersva _fasal rinyv anax p krz 1 p ata 2 p -- pに2を足す situv
まず、変数pを作り、そこに1を入れます。そしてそこに、2を足しています。
これを実行すると、変数pの中身は3になります。
ata
は足し算をする命令です。
ata q h
と書くことで、qの数をhに足します。その結果、hの中身は書き換えられます。
1+2を計算する時、ata 1 2
と書くことはできません。
ata
は、計算の結果を、右側に指定した変数に入れます。
この場合、右側には2がありますが、2は変数ではないので、その中に数を入れることはできません。
ata
と同じような書き方をする命令をまとめて紹介します。
ata | 足す(atakeses) |
nta | 引く(ny atakeses) |
ada | ビット積(adales) |
ekc | ビット和(ekcan) |
dal | ビットxnor(daliuales) |
dto | 論理右シフト(dusnij tesnokonj) |
dro(またはdRo) | 左シフト(dusnij restutonj) |
dtosna | 算術右シフト(dto (snakxazasyk)) |
次は掛け算です。0〜4294967295の数同士を掛けると、簡単に4294967295を超えてしまい、変数に入りません。
cersva _fasal rinyv anax p anax F krz 100 p lat 200 p F situv
これで100に200を掛けることができます。
lat
は掛け算をする命令です。
lat q h R
と書くことで、qをhに掛け(latvaves)ます。その結果を、4294967296で割ったものがRに、その余りがhに入ります。
今回のプログラムを実行すると、100*200は20000なので、変数pには20000、Fには0が入ります。
このように、それほど大きくない数の場合は、結果を入れる変数が1つで十分な場合が多いものです。
そんな場合は、lat q h h
と書くことで、結果を4294967296で割った余りだけを、hに入れることができます。
掛け算の命令には、数を符号無しとして計算するlat
と、符号付きとして計算するlatsna
の2種類があります。
もう1つ、計算をする命令があります。ビット反転(nacises)をするnac
です。
nac q
と書くことで、qのビットをそれぞれ反転し、その結果をまたqに入れます
変数の数によって、違った計算をすることができます。
cersva _fasal rinyv anax p anax F krz 3 p fi p xtlo 5 -- pが5以下なら rinyv krz 2 F situv fi p llo 5 -- pが5より大きいなら rinyv krz 0 F situv situv
fi
は条件分岐をする命令です。
fi 条件 rinyv 〜 situv
と書くことで、条件に一致するときだけ、rinyv
からsituv
の内容を実行します。
条件には以下のものが指定できます。
q xtlo h | qがh以下(xut loler) |
q xylo h | qがh未満(xy loler) |
q clo h | qがhと同じ(ce loler) |
q xolo h | qがhと以上(xolo loler) |
q llo h | qがhより大きい(le loler) |
q niv h | qがhと異なる(niv) |
q xtlonys h | qがh以下(xut loler) 符号無し(ny snakxaz) |
q xylonys h | qがh未満(xy loler) 符号無し(ny snakxaz) |
q xolonys h | qがhと以上(xolo loler) 符号無し(ny snakxaz) |
q llonys h | qがhより大きい(le loler) 符号無し(ny snakxaz) |
nysが付いているものは、数を符号無しとして比較します。
一方、nysが付いていないものは、数を符号付きとして比較します。
clo
とniv
は、符号付きでも符号なしでも同じ計算になりますので、それぞれ1種類だけ用意されています。
上のプログラムは、変数pが5以下ならFに2を入れ、変数pが5より大きければFに0を入れます。
その前にpには3を入れてあるので、実行するとFには2が入ります。
rinyv
とsituv
の間には、いくらでも命令を入れることができます。
条件分岐の中で、さらにまた条件分岐をすることも可能です。
rinyv
とsituv
の対応関係と範囲を分かりやすくするために、その中では字下げをすることをお勧めします。
条件を満す間、同じ処理を何度も繰り返すこと。繰り返しができると、2003fはとても強力な道具になります。
cersva _fasal rinyv anax p anax F krz 1 p krz 0 F fal p xtlo 10 rinyv ata p F ata 1 p situv situv
これは1から10までの数を全て足し合わせるプログラムです。
fal 条件 rinyv 〜 situv
と書くことで、条件を満たす間、rinyv
からsituv
の内容を繰り返します。
条件にはfi
と同じものが使えます。
上のプログラムを詳しく見ていきましょう。最初に、変数pに1を、変数Fに0を入れています。
pは10以下なので1回目の繰り返しに入ります。Fにp(1)を加えるとFが1になった後、pに1を加えてpが2になります。
pはまだ10以下なので2回目の繰り返しに入ります。今度はFにp(2)を加えて3になり、pはさらに1増えて3になります。
少し飛ばして、10回目の繰り返しでは、Fにp(10)を加えて、55になります。pは1増えて11になります。
ここで、pが10以下ではなくなりました。繰り返しをやめます。
結果として、Fに、1から10までの数を全て足し合わせた、55が入りました。
ちなみに、繰り返しを始める前から条件が満たされていない場合、繰り返しは1度も実行されずに終わります。
プログラムを書いていると、同じ処理を何度も書くことがあります。
関数(cersva)を利用することで、同じ処理を1つにまとめ、他の場所から呼び出す(fenxe)ことができます。
cersva _fasal rinyv fenxeo ppp el niv situv cersva ppp rinyv anax p krz 0 p situv
cersva p rinyv 〜 situv
と書くことで、pという名前の関数を作ることができます。
今まで全体を囲っていたcersva _fasal rinyv 〜 situv
は、_fasalという名前の関数を作るという意味でした。
_fasalというのは特別な名前で、実行する時に自動的に呼び出される関数を表します。
関数の中で関数を作ることはできません。なのでこのプログラムでは、_fasalの外側で関数pppを作っています。
fenxeo p el niv
と書くことで、pという名前の関数を呼び出すことができます。
ある関数の中で、読み書きすることのできる変数は、その関数の中で作られた変数だけです。
他の関数の中で作られた変数を操作すること(例えばこのプログラムでは、関数_fasalの中で、関数pppの変数pを操作すること)はできません。
関数を呼び出す時に、数を追加で渡すことができます。
例えば、与えた数を2倍にする関数を作ってみます。
cersva _fasal rinyv fenxeo qatvaves 10 el niv situv cersva qatvaves q rinyv anax p krz q p ata q p situv
関数に数を与えるときは、fenxeo
の関数名の後に数を書きます。
その数を受け取るためには、cersva
での関数名の後に、受け取るための変数名を書きます。
そうすることで、その名前の変数が作られ、そこには受け取った数が入っています。
このプログラムのqatvaves関数では、qという変数で数を受け取ります。
qの内容を変数pにコピーし、さらにqをpに足すことで、pにはqの2倍の数が入ります。
_fasal関数で、qatvaves関数に10を渡しているので、この場合qには10が入っていて、pには20が入ります。
cersva _fasal rinyv fenxeo atakes 10 20 el niv situv cersva atakes q h rinyv anax p krz q p ata h p situv
関数に渡す数のことを、引数といいます。
引数は、2個でも3個でも、もっとたくさんでも渡すことができます。
fenxeo
で関数名の後に値を並べると、それと同じ順番で、cersva
の関数名の後に並べた名前で受け取ることができます。
このプログラムでは、関数atakesのqとhには、それぞれ10と20が入ります。
fenxeo
とcersva
では、同じ数の引数を書くようにしましょう。
与えた数を2倍にする関数を作りましたが、このままでは_fasal関数の中でその結果を知ることかできません。
関数から数を返して(dosnud)もらいましょう
cersva _fasal rinyv anax qatvaveserl fenxeo qatvaves 10 el qatvaveserl situv cersva qatvaves q rinyv anax p krz q p ata q p dosnud p situv
関数から値を返すには、dosnud
命令を使います。
dosnud q
とすることで、qの数を呼び出し元に返すことができます。
関数から返してもらった数を受け取るには、fenxeo
のel
の後に、変数名を書きます。
今まではniv
と書いていた部分です。
関数qatvavesで、2倍にした数は変数pに入っていました。それを返しています。
関数_fasalでは、返してもらった数を変数qatvaveserlに入れています。
つまりここでは、10を2倍にした20が、qatvaveserlに入ります。
沢山の数を扱うプログラムを書くとき、ひとつひとつ変数を作るのは大変です。
そこで、複数の数を並べて入れることのできる、配列を使うことができます。
cersva _fasal rinyv anax p@10 anax F krz 1 p@0 krz 2 p@1 krz p@1 p@2 krz 5 F krz 100 p@F situv
配列は、変数と同じようにanax
で作ります。
anax p@10
と書くことで、10個の数を入れられる、pという配列を作ることができます。
10個の数それぞれを操作する時は、p@0
, p@1
, ... p@9
のようにします。
番号は0から数えるため、10個目の数はp@9
となることに気を付けてください。
配列を操作する時、p@F
のように書くこともできます。
このプログラムの場合、変数Fには5が入っているので、配列pの6番目(0から数えて5番目)に100を入れています。
これと、繰り返し処理を組み合わせることで、配列の数それぞれに同じ処理を繰り返すことなどが可能になります。
例えばp@F@0
のように書くと、どういう意味になるでしょうか。
これは右側から読んでいきます。まず配列Fの最初(0番目)の数を読み取ります。そして配列pの「さっき読み取った数」番目を読み取ります。
一方でanax
で配列を作る時、配列に並べる数の個数は、数字で直接書かなければなりません。
つまり、anax p@F
のようなことはできません。
cersva _fasal rinyv anax p@10 anax F@10 krz p F -- できない situv
配列は普通の変数とは違い、そのまま操作することはできません。
プログラムが大きくなってくると、複数のファイルに分けたくなるときがあります。
tinkaでは、他のファイルで作られた関数を使うことができます。
xok qatvaves cersva _fasal rinyv anax qatvaveserl fenxeo qatvaves 10 el qatvaveserl situv
kue qatvaves cersva qatvaves q rinyv anax p krz q p ata q p dosnud p situv
他のファイル(xokison)にある関数を使うには、xok 関数名
と書きます。
kue 関数名
と書くと、関数を他のファイルで使えるように公開(kinunsares)することができます。
xok
では、tinkaで書かれた関数だけでなく、2003lkなどで書かれた関数も、使うことができます。
一方tinkaでkue
された関数は、2003lkなどでも使用することができます。