23
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FortranAdvent Calendar 2019

Day 1

Fortranの面倒なことはユーザスニペットにやらせよう

Last updated at Posted at 2019-11-30

概要

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が作られます.

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する必要があるなど,雪だるま式に記述量が増えていきます.

これらのような,言ってしまえば数値計算の本質に関わらない所は,スニペットに登録して簡略化してしまいましょう.
以下のような項目を登録しておくと便利です.

  1. implicit none
  2. Fortranの組み込みモジュールのuse
  3. 型宣言
  4. 名前付きの構文

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_bindingieee_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)等は,個別にスニペットに登録しておくと,入力効率が劇的に改善します.
i4r4などとして登録しておき,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拡張によって,programdoの入力を簡略化できています.しかし,intrinsicが入力候補に出てこなかったり,real64のように,入力候補に出てはくるが,結局残り1文字まで入力しなければならないなど,今一な感じがします.また,名前付きdo構文には対応していません.

ユーザスニペット設定後

ユーザスニペット設定後は,useの記述,型名,名前付きdo構文が簡単に入力できていることが確認できます.

まとめ

FortranはOS以前に誕生したプログラミング言語の後継であり,モダンな言語と比較して,後方互換のために様々な制約があります.そういった面倒くさいところは,ツールを使って解決しましょう.

23
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?