まえがき
プロデル Advent Calendar 2019 16日目 の記事です.
プロデルはWindowsデスクトップアプリを作ることに適した,GUIベースのリッチな開発環境が提供されていますが,コンソールアプリケーションの開発も可能です.
競プロをはじめとしたテキストベースのデータ処理に必要となるであろう処理を昨日の精選10問を解いてみた記事の経験を元にまとめていきたいと思います.
2019/12/18 更新:ブロック式・種類のアクセス修飾子について追記.公式マニュアルに従い表記を変更1.
2019/12/29 更新:複文について追記.
プログラムの実行
実行環境は公式サイトからインストーラーが配布されているため簡単にセットアップできます.
「プロデル デザイナ」によりコーディング,保存したのち,
$ pconsole source.rdr
でインタプリタ実行できます.
また,プロデルデザイナから ファイル>実行可能アプリを作成>"ファイルの種類"を「コンパイル済みコンソールアプリ」指定 して保存することで実行ファイル形式のMSIL中間コードへコンパイルすることが可能で,「通常のインタプリタ版の実行可能ファイルに比べて繰り返し処理や配列の処理の速度が高速になります。」とのこと.
しかし,前記事で実行してみたところ実行時エラーが発生してテストできませんでした.
これについては今後解決を試みたいと思います.
基本事項
以下,プロデルのテクニカルタームはほげのように太字で表すことがあります.
また挿入コード中の《ほげ》
はメタ言語的な説明に用い,それ以外の記号は基本的にプロデル中の記号です.
基本的には命令型のオブジェクト指向言語です.
命令文は動詞と目的語(引数)により構成されます.
Hello, worldは
「こんにちは,世界!」をコンソールに表示する
のように書きます2が,動詞が表示する
で,助詞に
に繋がるコンソール
と,を
に繋がる「こんにちは,世界!」
が引数になります.
引数の順序は可換で,
コンソールに「こんにちは,世界!」を表示する
とも書けます.
なお,動詞につく送り仮名・助動詞は無視されるため
「こんにちは,世界!」をコンソールに表示
「こんにちは,世界!」をコンソールに表示せよ
「こんにちは,世界!」をコンソールに表示してください
「こんにちは,世界!」をコンソールに表示しない
はいずれも同じ命令となります.(否定文は解釈されないことに注意)
変数の宣言・代入
変数への代入は
《変数名》は、《代入する値》
《変数名》を《代入する値》とする
《変数名》=《代入する値》
《変数名》へ《代入する値》を代入する
のように書きます(4つとも等価).
宣言されていない変数へ代入すると自動で型推論され宣言されますが,スコープを明示したいとき,型注釈をつけたいときは【《変数名》:《型名》】
のように書くことができます(型注釈は省略可).
出入力
入力
標準入力はコンソールから受け取る
によって1行,文字列として取得できます.
※ABSの解法を参照
コンソールから受け取ってXとする
Xは,コンソールから受け取ったもの
空白による分割
競プロでは1行に空白で分割されて複数の入力が与えられることがありますが,文字列の空白分割は《文字列》を《区切り文字》で区切る
でできます.
A_1 A_2 ... A_N
を配列として受け取る処理は
Aは,コンソールから受け取ったものを「 」で区切ったもの
のようになります.
出力
前述のように,標準出力は《文字列》をコンソールへ表示する
と書きます.
なお,コンソールへ
はオプション引数ですが,デフォルトではダイアログボックスへの表示となり,コンソールでは
----- 《ファイル名》 -----
《文字列》
のように表示されます.
埋め込み文字列
文字列に式を埋め込むことができます.
文字列は「ほげ」
のように「」
で囲んだものですが,この中に[]
で囲った式を埋め込むと式を評価した文字式が埋め込まれます.
ほげは,「世界」
「こんにちは,[ほげ]!」をコンソールに表示して改行
// => こんにちは,世界!
数値演算
数値の型には以下のものがあります.
- 固定小数
- 長整数
- 整数
- 浮動小数
- 倍浮動小数
また,これらをまとめて数値とも呼べ,型注釈で【ほげ:数値】
とするとこれらの中から型推論してくれます.(もちろん【ほげ:整数】
のように直接指定もできます.)
数値の演算は以下の演算子を使った数式の形で書けます.
記号 | 意味 |
---|---|
+ | 足し算 |
- | 引き算 |
*,× | かけ算 |
/,÷ | わり算 |
^ | 累乗 |
¥ | 整数除算(商を整数値に切り捨て) |
% | 剰余 |
また,動詞を使っても表せます.
ex.
(4+5×3)%2
(4と(5と3を掛ける)を足す)を2で剰余演算する
※剰余演算する
はIEEE754準拠の剰余演算で,前者と結果が異なる場合があります.
その他,数値計算手順は公式レファレンスを参照
比較演算
値の比較は《値》《比較演算子》《値》
または《値》は、《値》《比較述語》
と表されます.
比較演算子には以下のようなものがあります.
=
.<
,≦
,<=
,>
,≧
,>=
,≠
,!=
,<>
比較述語には否定のでない
が使えます.
例.
2≦11でない
3は-4より大きい
条件分岐
判断文
if文に相当する構文です.
もし《条件1》なら
《条件1が正しいときに実行する処理》
他でもし《条件2》なら
《条件2が正しいときに実行する処理》
そうでなければ
《条件が違うときに実行する処理》
もし終わり
真偽値演算
真偽値のリテラルは○
・×
と表されます.
真理値演算はかつ
,または
で論理積,論理和演算ができます.
例. もし(ほげ<0または100<ほげ)かつふが≠0ならばぴよする
分岐文
switch文などに相当する構文です.C言語等のように条件ごとにbreakする必要はありません.
《変数》について分岐
《分岐させる値》の場合
︙
分岐終わり
数値は、0から5までの乱数
数値について分岐
0の場合
「大吉」を表示する
1の場合
「凶」を表示する
2の場合
「小吉」を表示する
他の場合
「中吉」を表示する
分岐終わり
※ https://rdr.utopiat.net/docs/manual/basis/switch.htm より
繰り返し
繰り返しの構文は用途に応じて複数用意されています
指定回数の繰り返し
《繰り返す回数》回、繰り返す
《繰り返す処理》
繰り返し終わり
一行で
《繰り返す回数》回、《繰り返す処理》を繰り返す
と書くこともできます.
インデックス付きの指定回数繰り返し
《繰り返す回数》回、《変数名》にカウントしながら繰り返す
《繰り返す処理(《変数名》を用いる)》
繰り返し終わり
indexは1から始まるので注意が必要です.
変数が指定した値になるまで繰り返す
一般的なC言語風のfor(…, …, …)文の構文はこうなります
《変数名》を《初期値》から《増減数》ずつ増やしながら《最終値》まで 繰り返す
《繰り返す処理》
繰り返し終わり
条件に応じて繰り返す
while文はこちら
《条件式》の間、繰り返す
《繰り返す処理》
繰り返し終わり
条件がfalseの間繰り返す事もできます
《条件式》になるまで繰り返す
《繰り返す処理》
繰り返し終わり
無制限に繰り返す
無限ループはこちら
繰り返す
《繰り返す処理》
繰り返し終わり
神奈川県警に捕まらないよう条件に応じてループから抜けましょう.
break文は繰り返しから抜ける
となります.
配列の内容に応じて繰り返す
配列を舐める形のループ(foreach文)を書くこともできます
《配列》を《変数名》へそれぞれ繰り返す
《繰り返す処理》
繰り返し終わり
範囲(range等に相当)が《開始値》~《終了値》
と書けるので,これを用いてカウンタ付きの繰り返しを
(《開始値》~《終了値》)を《変数名》へそれぞれ繰り返す
《繰り返す処理》
繰り返し終わり
と書くこともできます.インデックスが1スタートでないときなどに便利です.
配列
既に何度か登場していますが,プロデルでも値のコレクションである配列が扱えます.
配列を明示的に宣言するには
【《変数名》:《内容物の型》の配列】
と書きます.(デフォルトでは可変長配列です.固定長配列を扱うこともできます)
また,初期化は
《変数》は、{《1番目の値》、《2番目の値》、…}
と書けます.
要素へのアクセスは
変数(《インデックス》)
のように()
で何番目かを指定します.1-indexedなので気をつけましょう.
さらに,{}
で囲われ,,
で区切られた文字列は配列化
手順で配列にすることができます.
「{1,3,2}」を配列化する
=>{1,3,2}
カンマ区切りの入力ではこの方法で配列として受け取ることができますね.
辞書
連想配列,dictionary,map,hashなどと呼ばれるコレクションです.
初期化は
《変数》は、{《見出し1》=《値1》、《見出し2》=《値2》、…}
と書けます.見出しには文字列のみ使うことができます.
要素へのアクセスは
変数(《見出し》)
と見出しを指定します.インデックスが文字列であること以外は配列と同様です.
さらに,初期化の形の文字列は辞書化
手順で辞書にすることができます.
「{ほげ=1,ふが=3,ぴよ=2}」を辞書化する
=>{ほげ=1,ふが=3,ぴよ=2}
カンマ区切りの入力ではこの方法で配列として受け取ることができますね.
手順 の定義
これまでは組み込みの手順を使ってきましたが,自分で手順を定義することも可能です.
《手順名》手順
《処理内容》
終わり
例:
挨拶する手順
「こんにちは、世界!」をコンソールに表示する
終わり
挨拶する //=>こんにちは、世界!
引数のある手順は助詞を指定します
[《変数名》]《助詞》……、《手順名》手順
《処理内容》
終わり
例:
[対象]に、挨拶する手順
「こんにちは、[対象]!」をコンソールに表示する
終わり
「地球」に挨拶する //=>こんにちは、地球!
※注:例の1行目の[]
は引数を表し,2行目は埋め込み文字列のエスケープとなっています.
ブロック式
『』
で囲い,ブロック式として扱うことが可能です.
このブロック式は無名手順オブジェクトとして扱われ,変数に代入したり手順の引数とすることが可能です.
//ブロック式の代入
甲=『「こんにちは」をコンソールに表示』
甲を実行
//=> こんにちは
甲をコンソールに表示
//=> 匿名手順 (オブジェクト@《オブジェクトのアドレス》)
3回,甲を繰り返す
//=> こんにちは
// こんにちは
// こんにちは
3回,乙にカウントしながら『乙をコンソールに表示』を繰り返す
//=> 1
// 2
// 3
ブロック式を上に挙げた繰り返す
文の補語とすることで簡潔に繰り返しを書くことができますね.
種類
プロデルはクラスベースオブジェクト指向なのでクラスを定義することができます.
プロデルのクラスは種類と呼ばれます.
《種類名》とは
《種類内の変数や手順》
《変数名》を持つ
《変数名》:《種類名》=《値》
[自分]を、《手順名》手順
《手順の内容》
終わり
終わり
種類中での変数の宣言は持つ
とします.
手順の定義は自分
への参照を持ちます.
また変数,手順にアクセス修飾子をつけることができます.宣言の冒頭に以下の記号を付加します.
識別子 | 意味 |
---|---|
+ ,(なし) |
公開(Public) |
- | 非公開(Private) |
# | 限定(Protected) |
※参照:https://rdr.utopiat.net/docs/onepage2019/syntax/construct.html#construct_modifier
その他,コンストラクタ・getter/setterの宣言,種類の継承などができます.
詳しくは公式マニュアルを参照.
複文(≒メソッドチェーン)
プロデルでは,特殊変数それ
の機能を利用してメソッドチェーンのように動詞を書き連ねることができます.
特殊変数それ
は最後に実行された手順の戻り値を格納しています.
例えば
1と2を足す
それと3を掛ける //1+2=3が格納されている
それを表示する //3×3=9が格納されている
//=> 9
のようになります.
さらに,特殊変数それ
の応用機能として補語の省略機能があります.
それ
に値が格納されている状態では次の手順で一つ補語(引数)を省略することができ,自動で引数にそれ
が補完されます.
上の例は
1と2を足す
3を掛ける //「~と」が省略されている
表示する //「~を」が省略されている
//=> 9
と記述できます.
さらにさらに,動詞を連用形にすることで複数の手順を連ねて書くことができます.
1と2を足して3を掛けて表示する
//=> 9
引数・戻り値が一つずつの手順を連ねて書けばメソッドチェーンのような記法が可能となります.
なお,戻り値を複数与えるときは,意味が一通りに定まるよう補語の順序に制限があります.(動詞が現れる時点でそれまでに出現したすべての補語を消費していること)
詳しくは プロデルで日本語らしくプログラミング「プログラム文」―プロデルブログ を参照.
あとがき
まだ十分使いこなせていないため不足等あるかと思いますが,今後もアップデートしていきたいと思います.