概要
VSCodeのユーザースニペットの機能を利用して,Fortranの変数宣言等を簡略化しました.
使用環境
- Visual Studio Code 1.40.1
- Modern Fortran Extension 2.1.1
VSCodeのユーザースニペット
VSCodeには,コードの断片とそれに対応する記述子を登録しておき,記述子を入力するだけで対応するコード断片を呼び出すことができます.
VSCodeでは,VSCodeが認識しているファイル形式ごとに,ユーザースニペットの設定を記述します.まずは,Fortranのソースファイルを認識させるために,Modern Fortran拡張をインストールしておきましょう.
VSCodeのメニューバーから,ファイル→基本設定→ユーザースニペットと辿ると,VSCodeが認識しているファイル形式の一覧が出てきます.
その中から,FortranFreeFormを選択すると,FortranFreeForm.jsonが作られます.
{
// Place your snippets for FortranFreeForm here. Each snippet is defined under a snippet name and has a prefix, body and
// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
// same ids are connected.
// Example:
// "Print to console": {
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
}
FortranFreeForm.json(というか新規のユーザースニペットファイル)にはコメントが書かれており,それによると,記述するのは以下の4項目です.
- スニペットの識別名
- 記述子
- 変換されるコード断片
- スニペットの説明文
識別名は,他のスニペットと重複していなければよいだけなので,識別名はスニペットの説明文と同じとしておくと楽でしょう.
Fortranで登録しておいた方がよいスニペット
Fortranは,配列の取扱いが柔軟であるため,プログラムの実行部分は比較的楽に記述できます.
一方で,型宣言などの宣言部は,非常に長々と書く必要があり,肝心の数値計算のアルゴリズムを記述する前に疲れてしまいます.
手続きの名前と仮引数を書いた後,絶対に欠かすことのできないimplicit none
を書き,仮引数の型宣言を書きます.Fortranは,属性を付与することで変数の特徴(静的変数である,動的割付である,手続き内で読込専用である,など)を指定します.また,Fortranの型名にも,安全でない方言(real*4, real(4)
など)が蔓延しています.Fortran2008からは標準で型名が定められましたが,それがreal(real32)
と長く,さらにreal32
というパラメータを使うにはiso_fortran_env
モジュールをuse
する必要があるなど,雪だるま式に記述量が増えていきます.
これらのような,言ってしまえば数値計算の本質に関わらない所は,スニペットに登録して簡略化してしまいましょう.
以下のような項目を登録しておくと便利です.
implicit none
- Fortranの組み込みモジュールの
use
- 型宣言
- 名前付きの構文
implicit none
implicit none
は,FortranをFortranたらしめている,最も重要な記述です.本来は標準でimplicit none
が有効になっているべきですが,FORTRANとの後方互換維持のために,そうはなっていません.そのため,数ストロークで入力できるように,スニペットとして登録しておきます.
"Disable implicit typing": {
"prefix": "imp",
"body": [
"implicit none"
],
"description": "Disable implicit typing"
}
Fortranの組み込みモジュールのuse
Fortranでは,モジュールをuse
する際,組み込みのモジュールに対しては,intrinsic
を付けることで,ユーザ定義のモジュールと区別をしています.また,モジュール名もiso_c_binding
やieee_arithmetic
等,それほど長くはないですが,打ちにくい名前になっています.
これらもスニペットに登録することで,入力の簡略化が測れます.use
あるいはus
+1文字くらいが適切でしょう.
"Using iso_fortran_env module": {
"prefix": "usf",
"body": [
"use,intrinsic :: iso_fortran_env"
],
"description": "Using iso_fortran_env module"
},
"Using iso_c_binding module": {
"prefix": "usc",
"body": [
"use,intrinsic :: iso_c_binding"
],
"description": "Using iso_c_binding module"
}
型宣言
integer(int32)
やreal(real32)
等は,個別にスニペットに登録しておくと,入力効率が劇的に改善します.
i4
やr4
などとして登録しておき,allocatable
属性付きの宣言は,記述子にa
を足す,などと独自のルールを決めるとよいでしょう.
"Declaration of binary32": {
"prefix": "r4",
"body": [
"real(real32)"
],
"description": "Declaration of binary32"
},
"Declaration of binary64": {
"prefix": "r8",
"body": [
"real(real64)"
],
"description": "Declaration of binary64"
},
"Declaration of 4-bytes-integer": {
"prefix": "i4",
"body": [
"integer(int32)"
],
"description": "Declaration of 4-bytes-integer"
}
名前付きの構文
Fortranでは,do
構文やif
構文,block
構文などに名前を付けることができます.Fortran拡張をインストールすると,各構文に対するスニペットが利用できるようになりますが,名前付きの構文に関しては用意されていません.特に名前付きblock
構文に関しては,スニペットを用意して簡単に利用できるようにすることで,コードの可読性が劇的に向上します.
このとき,$
から始まる特殊な記述を用いると,簡単に記述できます.$1,$2,...
をコード断片に記述しておくと,記述子がコード断片に変換された後,$1
が書かれた場所にカーソルキーが移動します.tabキーで$2, $3...
と移動していきます.$0
は最後にカーソルが来ます.
ラベル付きの記述(${1:ラベル}
)も可能です.
"named do constructor": {
"prefix": "ndo",
"body": [
"${1:name} : do $2 = $3, $4",
" $0",
"end do ${1:name}"
],
"description": "named do constructor"
},
"named block constructor": {
"prefix": "nblock",
"body": [
"${1:blockname} : block",
" $2",
"end block ${1:blockname}"
],
"description": "named block constructor"
}
ユーザスニペットを使った効果
ユーザスニペットを設定したことで,記述がどれくらい簡略化できるか,簡単なプログラムで確認してみます.
ユーザスニペット設定前
ユーザスニペットを設定する前は,Modern Fortran拡張によって,program
やdo
の入力を簡略化できています.しかし,intrinsic
が入力候補に出てこなかったり,real64
のように,入力候補に出てはくるが,結局残り1文字まで入力しなければならないなど,今一な感じがします.また,名前付きdo
構文には対応していません.
ユーザスニペット設定後
ユーザスニペット設定後は,use
の記述,型名,名前付きdo
構文が簡単に入力できていることが確認できます.
まとめ
FortranはOS以前に誕生したプログラミング言語の後継であり,モダンな言語と比較して,後方互換のために様々な制約があります.そういった面倒くさいところは,ツールを使って解決しましょう.