Kuina-chan

くいなちゃん2018年10月19日


プログラミング言語Kuin」の逆引き辞典6、文とブロックの扱い方についてです。

目次

基本的な処理を行う

式を実行する

式を単に実行するには「do 」と書きます(式の実行)。
func main()
  var n: int
  do n :: 1
end func
式の実行

変数にアクセスできるスコープを分ける

ある特定の範囲でしか使わない変数は、予期しないアクセスを防ぐために、ブロックの中で定義します(変数のスコープ)。
func main()
  var a: int
  
  block
    var b: int
    do a :: 1
    do b :: 1
  end block
  
  do a :: 2
end func
変数のスコープ
5行目のようにブロックの中で定義された変数bは、7行目のようにブロックの中でのみアクセスできます。
2行目のようにブロックの外で定義された変数aは、6行目のようにブロックの中でも、10行目のようにブロックの外でもアクセスできます。
ここでいうブロックとは「block」だけでなく、「if」「while」などのすべてのブロックを指します。

ブロックを抜ける

「block」「if」「while」などすべてのブロックは、名前を付けることで「break」文で抜けることができます(break文)。
func main()
  block b
    var x: int :: 3
    break b
    var y: int :: 5
  end block
end func
変数のスコープ
2行目のように「ブロックの種類 ブロック名」と書いて、4行目のように「break ブロック名」と書くと、そのブロックを抜けることができます。 この場合5行目の処理は行われません。
例えばifブロックの場合ではブロック名は、「if ブロック名(条件式)」と書きます(ifブロックのbreak文)。
func main()
  if a(3 < 5)
    var x: int :: 3
    break a
    var y: int :: 5
  end if
end func
ifブロックのbreak文

条件分岐を行う

条件や値に応じて処理を分けるには、「if」ブロックや「switch」ブロックを使います。

条件によって処理を分ける

条件式が真か偽かによって処理を分けるには「if」ブロックを使います(ifブロック)。
func main()
  var n: int :: 3
  var s: []char
  if(n < 2)
    do s :: "n < 2"
  end if
end func
ifブロック
4行目のように「if(条件式)」としてbool型の条件式を書くと、式がtrueなら「end if」までの命令を実行し、falseなら「end if」までの命令を飛ばしてから、その後のプログラムを実行します。
条件式がfalseだったときにも、さらに「elif」を書いて条件式と処理を追加することができます(elif節とelse節)。
func main()
  var n: int :: 3
  var s: []char
  if(n < 2)
    do s :: "n < 2"
  elif(n < 5)
    do s :: "2 <= n & n < 5"
  else
    do s :: "5 <= n"
  end if
end func
elif節とelse節
この例の場合、「n<2」の条件式がtrueなら中身の5行目を処理し、条件式がfalseで次の「n<5」の条件式がtrueなら中身の7行目を処理し、どの条件式もtrueにならなければ「else」の中身の9行目を処理します。
1つのifブロックに対し「elif」はいくつでも追加でき、「else」はそれらの最後に追加できます。
式の中で、条件式に応じて値を変えたい場合には、条件演算子「?(,)」が便利です。 「条件式 ?(trueのときの値, falseのときの値)」と書きます(条件演算子)。
func main()
  var n: int :: 3
  var s: []char
  do s :: n < 2 ?("n < 2", "n >= 2") {"n >= 2"}
end func
条件演算子

値によって処理を分ける

値によって処理を分けるには「switch」ブロックを使います(switchブロック)。
func main()
  var n: int :: 3
  var s: []char
  switch(n)
  case 1
    do s :: "n = 1"
  case 3
    do s :: "n = 3"
  default
    do s :: "n <> 1 & n <> 3"
  end switch
end func
switchブロック
4行目のように「switch()」と書くと、式の値と合致する最初のcaseを探して、その中身を実行してからswitchブロックを抜けます。
このプログラムではn=3なので、7行目の「case 3」に合致し、中身の8行目が実行されます。 どのcaseにも合致しない場合には「default」の中身が実行されます。
defaultは省略可能で、省略したときはどのcaseにも合致しない場合には何もせずにswitchブロックを抜けます。
caseには、カンマ区切りで複数の値を指定したり、「to」を使って範囲を示すこともできます(case節)。
func main()
  var n: int :: 3
  var s: []char
  switch(n)
  case 1, 2
    do s :: "n = 1 | n = 2"
  case 3 to 6
    do s :: "3 <= n & n <= 6"
  case 10, 13 to 15
    do s :: "n = 10 | 13 <= n & n <= 15"
  end switch
end func
case節
switchブロックに名前を付けると、switchブロックに渡された値を得ることができます(switchブロックのブロック名)。
func main()
  switch x(1 + 2)
  default
    var n: int :: x {3}
  end switch
end func
switchブロックのブロック名

繰り返し処理を行う

繰り返し処理を行うには、「while」ブロックや「for」ブロックを使います。

条件によって繰り返す

条件式が真である限り処理を繰り返すには「while」ブロックを使います(whileブロック)。
func main()
  var n: int :: 4
  while(n <> 1)
    do n :/ 2
  end while
end func
whileブロック
whileブロックは「while(条件式)」と書くと、条件式が真の場合には「end while」までの中身を実行して再度「while(条件式)」の行までジャンプして戻ります。 条件式が偽の場合には「end while」の次の行へジャンプします。
最初に3行目に来たとき、nは4なので条件を満たすため4行目の処理(nの値を半分にする)を行います。 5行目にさしかかると3行目へジャンプし、再度3行目で条件の判定を行います。
2回目に3行目に来たとき、nは2なので条件を満たして4行目の処理を行い、5行目でまた3行目へジャンプします。
3回目に3行目に来たとき、nは1なので「n<>1」の条件を満たさないため、whileブロックを抜けて6行目へジャンプします。
また、最初の1回目は無条件にwhileブロックの中を実行させたい場合には、条件式の後に「, skip」と書きます(whileブロックの条件のskip)。
func main()
  var n: int :: 0
  while(n = 1, skip)
    do n :+ 1
  end while
end func
whileブロックの条件のskip
通常なら最初に3行目に来たとき、nは0で条件を満たさないため即座にwhileブロックを抜けて6行目へジャンプするはずですが、「, skip」があるため、無条件に4行目の処理を行ってから5行目で3行目へジャンプし、2回目以降で3行目に来たときに条件判断を行います。

指定回数だけ繰り返す

指定した回数だけ処理を繰り返すには「for」ブロックを使います(forブロック)。
func main()
  var n: int :: 0
  for i(1, 5)
    do n :+ i
  end for
end func
forブロック
forブロックは「for(初期値, 終値)」と書くと、初期値から終値まで1ずつ増やしながら数えて「end for」までの処理を繰り返します。
forブロックに名前を付けると、数えている最中の値が取得できます。 このプログラムでは4行目の「i」で数えている最中の値を取得していて、変数nは最終的に「1+2+3+4+5」つまり「15」の値になります。
1ずつ減らしながら数えるには、forブロックの括弧の最後に「, -1」と書きます(forブロックの増減値)。
func main()
  var n: int :: 0
  for i(5, 1, -1)
    do n :+ i
  end for
end func
forブロックの増減値
このように「, 増減値」と書くことで、数えるときの増減値が指定できます。 例えば「, 3」と書くと3ずつ増やしながら数えます。
増減値が正なら、数えている値が終値より大きくなるとforブロックを抜け、増減値が負なら、終値より小さくなるとforブロックを抜けます。 数えている値が実際に増減するタイミングは「end for」の行です。

繰り返し処理を1回飛ばす

whileブロックやforブロックの繰り返し処理を1回飛ばすには「skip ブロック名」と書きます(skip文)。
func main()
  var n: int :: 0
  for i(1, 5)
    if(i = 2)
      skip i
    end if
    do n :+ i
  end for
end func
skip文
skip文は、「end ブロックの種類」の直前にジャンプする命令です。 このプログラムでは、iが2のときにforブロックの中のそれ以降の処理を飛ばして「end for」の直前にジャンプするため、最終的なnは「1+3+4+5」つまり「13」の値になります。

例外を扱う

(この記事は執筆中です!)
1539955450jaf