はじめに
Qiitaに参加して、6ヶ月となります。2023年も半ばを超えてまいりました。参加して6ヶ月後くらいに記事にしました日本語トランスコンパイラ言語 Re:Mind(リマインド)2022 Lv1の後も、いくつかの他言語の構文比較で追記されていました。(といってもターゲット言語が持っている仕様に比べると微々たるものですが。)この時点で2023 Lv1.1のドラフト仕様として、まだ仕様に含めていない構文比較検討結果はこの記事の追記改定にしていきたいと思います。
自作言語 Re:Mind(リマインド)の企画趣旨はQiita内の記事でご説明させてきてはおりますので、興味をもたれた方、言語仕様を気に入っていただいた方で腕に覚えのあるなしにかかわらず、こんなの実装しましたよとまた記事にしていただければ幸いです。
この記事内容の作業目的
自作言語Re:Mindの構文仕様策定の節目として、今年(2023年末)中に考案する予定の内容を2023 Lv1.1ドラフトとしてまとめます。
この記事内容の保証
※この記事には仕様的な情報が含まれます。自作言語はまだ設計開発中のため、発案者による実装は存在しません。本記事に開示された仕様は次バージョンの仕様においては予告なく変更される場合があります。また、このバージョンの仕様内で補足や追加がなされる場合があります。
概要
日本語トランスコンパイラ言語 Re:Mind(リマインド)はオープンな実装言語仕様で、どなたでもコンパイラ・トランスコンパイラを実装することができます。
オリジナルのランタイムコード、既存の中間コードなどへのコンパイラとしての実装を退けるものではありませんが、今日のシステム開発言語の多様化に鑑みて、それらの言語環境との相互運用性を容易としプログレッシブな導入を実現するため、他のプログラミング言語をターゲット言語とするトランスコンパイラとして実装することを推奨しています。
日本語トランスコンパイラ言語 Re:Mindは、リスペクトしてやまない第1世代日本語プログラミング言語 Mind(マインド)や後の日本語プログラミング言語と同じく、日本語を基調とした構文を採用し、英語のプログラミング言語にありがちな「;」や「{ }」などの特殊な文字を区切りとして使用しない点を共有しつつ、半角かっこ内や一部の構文はターゲット言語のシンタックスを許容するとします。
また、日本語トランスコンパイラ言語 Re:Mindは、制御構文の開始シンボルとして、◇、〇、・、□などの全角記号を用い、箇条書きされた日本文としての体裁を日本語ロジック記述言語 Re:Mindの構文とも共有しています。◇は分岐構文、〇はループ構文の開始と終了を表し、冗長な日本語表記がなくてもフロー図の表現に慣れている方が直感的に認識できることを考慮しています。
推奨・想定されるターゲット言語
C言語のシンタックスを共有・継承する以下の静的型付け言語
・Java
・C#
・TypeScript
・Go
英語を基調とした以下のBASIC言語
・Visual Basic for Application (Excel)
・Visual Basic.NET
より自然な日本語構文を特徴とする以下の日本語プログラミング言語
・Mind
・プロデル
・なでしこ
推奨・想定される実装言語
・とくにありません。好きな言語、得意とする言語で実装してください。
言語仕様
変数
/** nenrei */
・int 年齢 = 34
/** namae */
・string 名前 = "花子"
/** tokutaiKubun */
・bool 特待区分 = true
□全角文字の中点に続いて、ターゲット言語の物理型名を半角文字で記述し、半角空白に続いて変数名を記述します。
・直前の行はjava doc形式のコメントで、ターゲット言語上の変数名を半角文字で記述します。書かない場合は、日本字のまま変数名となります。
・半角等号で初期値を代入できます。
/** nenrei */
・変数int 年齢
/** namae */
・public string 名前
/** tokutaiKubun */
・変数private bool 特待区分 = true
□全角中点に続いて「変数」と書くこともできます。後述の定数と並んだ時の見栄え、わかりやすさのため、変数宣言であることを明示。
・ターゲット言語のスコープを型名の前に書くことも可能。全角中点または「変数」とはくっついていて可。
定数
/** nenrei */
・定数int 年齢 = 34
/** namae */
・定数string 名前 = "花子"
/** tokutaiKubun */
・定数public bool 特待区分 = true
□全角文字の中点に続いて「定数」と書き、続いてターゲット言語の物理型名を半角文字で記述し、半角空白に続いて定数名を記述します。
・直前の行はjava doc形式のコメントで、ターゲット言語上の定数名を半角文字で記述します。書かない場合は、日本字のまま変数名となります。
・半角等号で初期値を必ず代入します。
・ターゲット言語のスコープを型名の前に書くことも可能。全角中点または「定数」とはくっついていて可。
関数
関数の実行
□年齢 = メンバーの年齢を取得する(名前,特待区分)
□(名前,特待区分)で メンバーの年齢を設定する
◇値を返す関数の場合、全角記号の四角□に続いて、戻り値を受け取る変数名を記述し、半角等号に続いて関数名を記述します。
・続いて半角かっこを設け、ターゲット言語の物理型名と変数名を半角空白を挟んで、カンマ区切りで記述し、半角かっこで閉じます。
・半角かっこ内はターゲット言語の記法を可とします。参照渡しの明示や、既定値設定など、ターゲット言語の構文記述ができるとします。
◇値を返さない関数の場合、全角記号の四角□に続いて、半角かっこを設け、ターゲット言語の物理型名と変数名を半角空白を挟んで、カンマ区切りで記述し、半角かっこで閉じます。
・半角かっこ内はターゲット言語の記法を可とします。参照渡しの明示や、既定値設定など、ターゲット言語の構文記述ができるとします。
・半角かっこで閉じた後、続けて関数名を書くことができます。
半角かっこで閉じた後、続けて「で」や「を」を付加し、半角空白を挟んで関数名を書くこともできます。このひらがなは無視します。
値を返す関数の宣言
/**
* getMembersAge
* @param 名前 name
* @param 特待区分 kubun
* @return 年齢
*/
▽public int メンバーの年齢を取得する(string 名前,bool 区分)
//todo
□(齢)を 返す
△
□全角記号の下三角▽が関数宣言の開始となります。
・続いてターゲット言語のスコープを書きます。省略も可。
・続いて半角空白をおいて、ターゲット言語の戻り値型を書きます。戻り値あり関数としては省略不可。
・続いて半角空白をおいて、関数名を書きます。
・続いて半角かっこを設け、ターゲット言語の物理型名と変数名を半角空白を挟んで、カンマ区切りで記述し、半角かっこで閉じます。
・半角かっこ内はターゲット言語の記法を可とします。参照渡しの明示や、既定値設定など、ターゲット言語の構文記述ができるとします。
・全角記号の上三角△で定義を終了します。
・かならず、定義終了前に全角四角に続き、変数名に空白を挟んで「返す」と記述するとします。
・全角四角に続き、「return」と書いて、半角空白ののちに変数名を記述でも可とします。
・全角記号の下三角▽直前の行はjava doc形式のコメントで、ターゲット言語上の関数名を半角文字で記述します。書かない場合は、日本字のまま関数名となります。
・コメントの終端までの間、@paramに続いて変数名を書き、続いてターゲット言語上の変数名を半角文字で記述します。書かない場合は、日本字のまま変数名となります。
値を返さない関数の宣言
/**
* memberNenreiSettei
* @param 名前 name
* @param 特待区分 kubu
*/
▽private メンバーの年齢を設定する(string 名前,bool 区分)
//todo
△
□全角記号の下三角▽が関数宣言の開始となります。
・続いてターゲット言語のスコープを書きます。省略も可。
・続いて半角空白をおいて、関数名を書きます。
・続いて半角かっこを設け、ターゲット言語の物理型名と変数名を半角空白を挟んで、カンマ区切りで記述し、半角かっこで閉じます。
・半角かっこ内はターゲット言語の記法を可とします。参照渡しの明示や、既定値設定など、ターゲット言語の構文記述ができるとします。
・全角記号の上三角△で定義を終了します。
・全角記号の下三角▽直前の行はjava doc形式のコメントで、ターゲット言語上の関数名を半角文字で記述します。書かない場合は、日本字のまま関数名となります。
・コメントの終端までの間、@paramに続いて変数名を書き、続いてターゲット言語上の変数名を半角文字で記述します。書かない場合は、日本字のまま変数名となります。
クラス
クラスの宣言
/**
* MembersLogic : AbstractLogic
*/
▽public class メンバーの取り扱い方 : 取り扱い方
・変数int 年齢
・変数public string 名前
・変数private bool 特待区分
▽public int メンバーの年齢を取得する(string 名前,bool 区分)
//todo
□(齢)を 返す
△
▽private メンバーの年齢を設定する(string 名前,bool 区分)
//todo
△
△
□全角記号の下三角▽がクラス宣言の開始となります。
・続いてターゲット言語のスコープを書きます。省略も可。
・続いて半角空白をおいて、ターゲット言語のクラス表記を書きます。ここは全角カタカナで「クラス」と書いても可。
・続いて半角空白をおいて、クラス名を書きます。
・続いて半角空白をおいて、ターゲット言語のクラス継承表記を書きます。その後は半角空白をおいて、継承元のクラス名を書きます。継承しない場合はこれらの記述は省略可です。
・クラスのメンバの書き方は変数宣言、関数宣言に準じます。上記の記述例では個々の変数宣言、java docコメントの記述を割愛しています。
・全角記号の上三角△で定義を終了します。
・全角記号の下三角▽直前の行はjava doc形式のコメントで、ターゲット言語上のクラス名を半角文字で記述します。書かない場合は、日本字のままクラス名となります。
・継承元クラスがある場合は、半角空白の後にコロン:、続けて半角空白の後にターゲット言語上の継承元クラス名を半角文字で記述します。継承があるのに書かない場合は、日本字のまま継承元のクラス名となります。
クラスのインスタンス宣言
/** membersLogic */
・メンバーの取り扱い方 メンバー取り扱い方法 = new()
□クラスのインスタンス名は同じ主旨の別名としてください。
・コンストラクタにオーバーロードがある場合は、かっこ内にターゲット言語の記法で記述します。
クラスのインスタンスの変数操作
□年齢 = メンバー取り扱い方法.年齢
□メンバー取り扱い方法.年齢 = 年齢
□クラスのインスタンス名の装飾子は半角ドットです。
□年齢 = メンバー取り扱い方法?.年齢
□メンバー取り扱い方法.年齢 = 年齢 ?? 0
・Null条件演算子はターゲット言語が対応している場合は使用可とします。
・Null合体演算子はターゲット言語が対応している場合は使用可とします。
対応していない言語の場合は同等構文を展開するのが望ましい
クラスのインスタンスの関数実行
□年齢 = メンバー取り扱い方法.メンバーの年齢を取得する(名前,特待区分)
□(名前,特待区分)で メンバー取り扱い方法.メンバーの年齢を設定する
□クラスのインスタンス名の装飾子は半角ドットです。
・Null条件演算子はターゲット言語が対応している場合は使用可とします。
◇値を返す関数の場合、全角記号の四角□に続いて、戻り値を受け取る変数名を記述し、半角等号に続いてクラスのインスタンス名と関数名を半角ドットを挟んで記述します。
・続いて半角かっこを設け、ターゲット言語の物理型名と変数名を半角空白を挟んで、カンマ区切りで記述し、半角かっこで閉じます。
・半角かっこ内はターゲット言語の記法を可とします。参照渡しの明示や、既定値設定など、ターゲット言語の構文記述ができるとします。
◇値を返さない関数の場合、全角記号の四角□に続いて、半角かっこを設け、ターゲット言語の物理型名と変数名を半角空白を挟んで、カンマ区切りで記述し、半角かっこで閉じます。
・半角かっこ内はターゲット言語の記法を可とします。参照渡しの明示や、既定値設定など、ターゲット言語の構文記述ができるとします。
・半角かっこで閉じた後、続けてクラスのインスタンス名と関数名を半角ドットを挟んで書くことができます。
半角かっこで閉じた後、続けて「で」や「を」を付加し、半角空白を挟んで関数名を書くこともできます。このひらがなは無視します。
四則演算、論理演算
・ターゲット言語のシンタックスに準じます。中置記法
・ただし、ターゲット言語がjavaの場合でもBigDecimal同士のメソッドによる四則演算は通常の四則演算子で表記できるとします。
制御構文
分岐
2分岐(if文)
◇i > 0 の場合
//todo
◇ここまで
□全角記号のひし形◇が条件分岐の開始となります。
・続いてターゲット言語の論理式を書きます。半角かっこは不要。
・続いて「の場合」と書きます。半角で書かれた論理式とはくっついていても可。
・全角記号のひし形◇が条件分岐の終了となります。
・つづいて「ここまで」と書くことができます。省略も可。
◇i > 0 の場合
//todo
◇他に i < 0 の場合
//todo
◇他に
//todo
◇ここまで
◇途中で最初の論理式とは排他的な条件をつづける場合は、全角ひし形◇に続いて「他に」と書いて、論理式を書いて、「の場合」と書きます。
・論理式の前後の空白は、論理式を半角で書いている場合は省略できます。
◇最後に例外条件を明示する場合は、全角ひし形◇に続いて「他に」と書きます。
◇i > 0 の場合
◇j == 0 の場合
//todo
◇他に
//todo
◇ここまで
//todo
◇他に i < 0 の場合
//todo
◇他に
//todo
◇ここまで
□おなじ分岐構文を使って、入れ子で記述することができます。
多分岐(switch文)
switch文の構文です。条件構文自体に分岐を抜けさせる働きがないことをフォークスルーといいます。言語によってはこのフォールスルーがあったり、なかったりする場合だったりしますので、トランスコンパイラ言語としてはこのあたりをターゲット言語の動作に依存するところです。
- Re:Mind
◇値 で分岐する
◇定数1
//todo1
□処理する1
□脱出する
◇定数2
//todo2
□処理する2
□脱出する
◇既定
//todo3
□処理する3
□脱出する
◇ここまで
◇定数1 がCase文に相当する構文で、ここでは実行文を書く場合改行必須です。「◇既定」がdefalut文相当です。
□脱出するがbreak文に相当します。
ターゲット言語がフォークスルー動作が仕様としてない言語の場合(break文を書かなくても脱出する)は書いてもターゲット言語のソースコードには出力しないという動作とします。
値は半角かっこ()で囲っても囲わなくても可です。
繰り返し
カウンタ変数の初期化を行なう(for文)
〇int i=0,i<10,i++ 繰り返す
//todo
〇ここまで
□全角記号の丸印〇が繰り返しの開始となります。
・続いてターゲット言語のカウンタ論理式をカンマ区切りで書きます。半角かっこは不要。セミコロン区切りも可。
・続いて「繰り返す」と書きます。半角で書かれた論理式とはくっついていても可。
・全角記号の丸印〇が繰り返しの終了となります。
・つづいて「ここまで」と書くことができます。省略も可。
〇繰り返す
//todo
〇ここまで
□全角記号の丸印〇に続いて「繰り返す」と書いた場合は無限ループになります。
〇繰り返す
//todo
◇j==0 の場合 やめる
//todo
〇ここまで
・繰り返し構文内で条件分岐文を書いて「やめる」と書くと、直接のループを脱出します。
/** index */
〇int インデックス=0,インデックス<10,インデックス++ 繰り返す
//todo
〇ここまで
□繰り返し構文のカウンタ変数をインラインで日本字で宣言した場合、java docでターゲット言語上の表記を半角英字で書いておきます。
前判定繰り返し構文(while文)
- Re:Mind
・int i=0
〇(i<10) の間は繰り返す
//todo
□反復処理
□i++
〇ここまで
□while(i<10) のような構文の表記です。
・int i=0
〇(i<10) の間は繰り返す
◇i<2 の場合
□ループ先頭へ
//todo
〇ここまで
□条件分岐と合わせて、ループ先頭に制御を移す場合は「ループ先頭へ」を使います。
・int i=0
・int j=0
・int k=0
〇(i<10) の間は繰り返す
//todo
□反復処理
□k++
□j++
◇j>8 の場合
□脱出する
◇ここまで
◇k<4 の場合
□ループ先頭へ
◇ここまで
□i++
〇ここまで
ループ本体内に条件分岐式を記述して、ループ続行の判定が成立する前にループを脱出したり(□脱出する)、ループの先頭に復帰して(□ループ先頭へ)ループ本体の処理をスキップさせることができます。
後判定繰り返し構文(do-while文)
後判定繰り返し構文の場合、最初の〇の後に「ここから」を記述し、末尾の〇に判定文「(条件式) の間は繰り返す」を記述します。
・int i=0
〇ここから
//todo
□反復処理
□i++
〇(i<10) の間は繰り返す
コメント
通常コメント
//todo
□ダブルスラッシュ//で行末までコメントアウトします。
/*
todo
todo
*/
□スラッシュとアスタリスク/でコメント行開始、アスタリスクとスラッシュ/でコメント行の終了。
ターゲット言語上での半角英字名の指定
/** nenrei */
・int 年齢 = 34
/**
* namae
*/
・string 名前 = "花子"
/**
* memberNenreiSettei
*/
▽private メンバーの年齢を設定する(string 名前,bool 区分)
△
/**
* MembersLogic : AbstractLogic
*/
▽public class メンバーの取り扱い方 : 取り扱い方
△
□javadocと同じ/** */で半角英字を囲って、変数宣言文、関数宣言文、クラス宣言の直前に記述することで、ターゲット言語上の英字名を指定できます。
/**
* memberNenreiSettei
* @param 名前 name
* @param 特待区分 kubu
*/
▽private メンバーの年齢を設定する(string 名前,bool 区分)
//todo
△
@paramに続いて、日本字の引数名、半角空白に続いて英字名を記述することで、引数名のターゲット言語上の英字名を指定できます。
ターゲット言語のライブラリの引用の仕方
□今日のシステム開発に使われる有力言語は巨大なライブラリを保持しておりますが、利用の際には名前空間を指定したり、パッケージを指定したりして、予め利用する範囲を指定するが一般的です。
・また言語によっては、利用する関数、変数単位でインポートするものもあります。
□そこでRe:Mindはあらかじめタ-ゲット言語の全方位のライブラリをサポートすることはせず、一定のルールで利用可とできる構文を提供します。
◇開発ユーザーがターゲット言語を理解している場合は、ターゲット言語で直接記述することも可とし、ターゲット言語との相互運用に有利な環境を提供します。
■using System
▼public static class コンソール Console
▼public static System.Text.Encoding 入力エンコード
InputEncoding { get; set; }
▲
▼public static string? 次の1行を読み取る()
ReadLine ()
▲
▼public static 改行表示する(string? value)
WriteLine (string? value)
▲
▲
□全角黒四角■に続いてターゲット言語のインポート文を記述します。セミコロンは書かなくても可。
・全角下三角▼に続いてターゲット言語のターゲットクラスを宣言し、クラス名の直前に日本字のクラス名を記述します。
・通常のクラス定義と同様に全角上三角▲が定義の終了となります。
・この間に、ターゲット言語の利用対象のターゲット関数・変数を全角下三角▼と全角上三角▲挟んで宣言します。
・全角下三角▼に続いてターゲット言語の構文で関数、変数を宣言しますが、関数名・変数名は日本字を記述します。
・関数の引数仕様はターゲット言語の仕様情報の記述のままとします。引数名は日本字にしない。
・戻り値のない関数はvoidは省略可。
・C#の変数の { get; set; }は英字側に記述。省略可。
・改行してターゲット言語の関数・変数を英字オリジナルで宣言します。
・関数の引数仕様はターゲット言語の仕様情報の記述のままとします。
おわりに
不明な点はコメントで質問していただけるとうれしいです
わたしも、このバージョン(2023 Lv1.1)確定にむけて不足要件を追記して参ります。
構造化例外処理のサポートも2023 Lv1.1の想定です。
また、試作品の内部設計を進めています。
参考リンク
日本語トランスコンパイラ言語 Re:Mind (自作言語)と他言語との構文比較(IF文)
日本語トランスコンパイラ言語 Re:Mind (自作言語)と他言語との構文比較(FOR文)
Java C# Ts GoのC系言語 Mind DNCLの日本語系言語の制御構文を比較して自作言語Re:Mindの構文を定める(if..else if..else文)
Java C# Ts GoのC系言語 Mind DNCLの日本語系言語の制御構文を比較して自作言語Re:Mindの構文を定める(for..if文)
C言語系(Java C# Ts Go) 日本語系(Mind DNCL)各言語構文を比較して自作言語Re:Mindの構文を定める(変数宣言・実行文・関数宣言)
↑ここまでは2022 Lv1
↓ここからは2023 Lv1.1ドラフト
C言語系(Java C# Ts Go) 日本語系(Mind DNCL プロデル なでしこ)各言語構文を比較して自作言語Re:Mindの構文を定める(switch文)
C言語系(Java C# Ts Go) 日本語系(Mind DNCL プロデル なでしこ)各言語構文を比較して自作言語Re:Mindの構文を定める(while文)
C言語系(Java C# Ts Go) 日本語系(Mind DNCL プロデル なでしこ)各言語構文を比較して自作言語Re:Mindの構文を定める(try~catch文)
C言語系(Java C# Ts Go) 日本語系(Mind DNCL プロデル なでしこ)各言語構文を比較して自作言語Re:Mindの構文を定める(import文))