Diksam基礎文法最速マスター

Diksamの文法一覧です。Java, C++, C#等の言語をある程度知っている人はこれを読めばDiksamの基礎をマスターしてDiksamを書くことができるようになっています。

――はい、便乗です。なにやらはてダのトップの人気記事が基礎文法最速マスターだらけになっていたので。まあ、需要があるとも思えませんが。
Diksamって何だ、って? 私が作った自作言語です。

言語が似ているだけに、下記はJava基礎文法最速マスター - いろいろ解析日記をベースとさせていただきました。

言語仕様はこちら:
http://kmaebashi.com/programmer/devlang/dls_0_4_01.html

この本の後半で扱っている言語でもあります。

1.基礎

プログラムの構成
プログラムは宣言部、トップレベル、関数定義または宣言、型定義、定数定義から構成されます。実行は、起動時に指定されたソースファイルの、トップレベルに記述された文が順に実行されます。よって、"hello, world."と表示するプログラムは単に書きます。

println("hello, world.");

Javaにおけるimportに相当するものとしてrequire宣言があります。これは宣言部(プログラムの冒頭)に記述します。

requre diksam.lang;
requre diksam.math;

ただし、diksam.langはデフォルトでrequireされているので、ユーザが陽にrequireする必要はありません。

文字列を描画する関数

改行なしのprint()関数、改行ありのprintln()関数が使用できます。

print("hello, ");
println("world.");

コメント
コメントです。

// 一行コメント
/*
   複数行コメント
 */

変数の宣言
変数の宣言です。変数の宣言時にはデータ型を指定します。

// 変数
int num;

データ型
Diksamのデータ型には基本型と派生型、クラス/インタフェース、列挙型、delegate型があります。以下は基本型のデータ型です。

// int(整数)型
int num;
// double(倍精度浮動小数点)型
double value;
// boolean(論理)型
boolean flag;
// string(文字列)型
string str;

クラス、配列は参照型のデータ型です。

// File型
File f;
// 配列型
int[] array;

プログラムの実行
Diksamはコンパイルは不要です。プログラムを実行するには、コマンドラインで以下のようにします。

diksam hoge.dkm

2. 数値

数値の表現
int、double型の変数に数値を代入できます(floatはありません)。Javaとは異なり、intに小数を代入することもできます(もちろん値は切り捨てられます。Cと同じ)。

int i = 2;
int i = 100000000;

double num = 1.234;

四則演算
四則演算です。

num = 1 + 1;
num = 1 - 1;
num = 1 * 2;
num = 1 / 2;

商の求め方です。割る数と割られる数が両方とも整数の場合、計算結果の小数点以下が切り捨てられます。

num = 1 / 2;  // 0

割る数と割られる数のどちらかが小数の場合、計算結果の小数点以下が切り捨てられません。

num = 1.0 / 2;    // 0.5
num = 1 / 2.0;    // 0.5
num = 1.0 / 2.0;  // 0.5

余りの求め方です。

// 余り
mod = 4 % 2

インクリメントとデクリメント

インクリメントとデクリメントです。

// インクリメント
 i++;

// デクリメント
 i--;

前置のインクリメント、デクリメント演算子はありません。

3. 文字列

文字列の表現
文字列はダブルクォートで囲みます。

string str = "abc";

文字列操作
各種文字列操作です。

// 結合
  string join = "aaa" + "bbb";

// 長さ
  int length = "abcdef".length();

// 切り出し
  "abcd".substr(0, 2);  // ab

4. 配列

配列変数の宣言
配列です。

// 配列の宣言
int[] array;

配列の生成
配列の生成です。配列の生成時には要素数を指定するか、配列リテラルを指定します。

int [] array;

// 要素数を指定して配列を生成
array = new int[5];

// 初期データを指定して配列を生成。
// 配列リテラルの型は、最初の要素の型の配列になる。
array = {1, 2, 3};

配列の操作
配列の操作です。

// 要素の参照
array[0]
array[1]

// 要素の代入
array[0] = 1;
array[1] = 2;

size = array.size(); // サイズの取得
array.resize(10);    // サイズの変更
array.insert(3, 5);  // 挿入(array[3]の前に5を挿入)
array.remove(3);     // 削除(array[3]を削除し、詰める)
array.add(5);        // 末尾への要素追加

5. 制御文

if文
if文です。Java等とは異なり、波括弧は省略できません。

if ( 条件 ) {

}

if 〜 else文
if 〜 else文です。

if ( 条件 ) {

} else {

}

if 〜 else if 文
波括弧が省略できないので、Javaのようにelseの後に単文のifを続けることができません。そのため、予約語elsifが導入されています。

if ( 条件 ) {

} elsif ( 条件 ) {

}

while文
while文です。

int i = 0;
while ( i < 5 ) {
    
    // 処理
    
    i++;
}

for文
for文です。

for (int i = 0; i < 5; i++) {

}

なお、foreachはまだありません。

switch case文
switch caseです。CやJavaのようなfall throughにはなっていません。

  switch (a)
  case 1 {
      // aが1の時に実行される。
  } case 2, 3 {
      // aが2または3の時に実行される。
  } default {
      // aが1でも2でも3でもない場合に実行される。
  }

6.定数/関数/クラス/列挙/delegate定義

関数定義
関数定義です。

// 引数としてふたつの整数を受け取り、その和を返す関数
int sum(int a, int b) {
    return a + b;
}

// 引数として配列とインデックスを受け取り、
// その個所の要素を返す関数。
int getAt(int[] array, int index)
  throws ArrayIndexOutOfBoundsException {
    return array[index];
}

定数定義
定数はキーワードconstで定義します。

const MINUTES_A_DAY = 24 * 60;

型の指定がいらないことに注意。

なお、以下のようにfinalを使って書くこともできますが、final指定の変数は、実際にそこが実行されないと代入されません。

final int MINUTES_A_DAY = 24 * 60;

クラス定義
クラスは、以下の形式で定義します。

クラス修飾子 class クラス名
  : スーパークラス, 実装するインターフェイスの並び {
    フィールド、メソッド、コンストラクタ定義の並び
}

クラス修飾子には以下のものがあります。

  • アクセス修飾子。publicを指定するか無指定のいずれか。public指定すると別パッケージ(別ソースファイル)から参照可能となる。
  • abstract修飾子。抽象クラスを意味する。指定するかしないかのいずれか。

Diksamはクラスについては単一継承のみ可能です。また、Diksamでは、抽象クラス以外は継承できません

インタフェース定義

アクセス修飾子 interface {
    // メソッド定義の並び
}

フィールド定義

アクセス修飾子 final修飾子 型 フィールド名 初期化子;

フィールドに対するアクセス修飾子は、public、 private、もしくは無指定です。 publicは別のパッケージから使用可能、無指定は同一パッケージ内から使用可能、 privateはクラス内のみで使用可能であることをそれぞれ意味します。
finalを指定することで、そのフィールドは代入不能となります。

Diksamにはstaticなフィールドはありません。

メソッド定義

メソッド修飾子 型 メソッド名 (パラメータの並び) throws節 {
    文の並び
}

関数定義と同様、throws節は省略可能です。また、abstract修飾子を付けた場合、
関数本体(文の並びを含むブロック)は記述できません。

メソッド修飾子には以下のものがあります。

  • アクセス修飾子。public、private、 無指定のいずれか。
  • abstract修飾子。 指定するかしないかのいずれか。
  • virtual修飾子、またはoverride修飾子。

Diksamのデフォルトはnon virtualです。virtual指定のないメソッドはオーバーライドできない。また、オーバーライドする場合は、必ずoverrideを指定しなければなりません。

Diksamにはstaticなメソッドもありません。

コンストラク
Diksamでは、コンストラクタの定義には、constructor修飾子を使用します。

public constructor initialize() {
    // コンストラクタの処理を記述する。
}

constructor修飾子は、型名と同じ場所に記述します。よってpublicやvirtual等のメソッド修飾子よりは後ろに記述しなければなりません。

constructor修飾子により、Java, C++, C#等とは異なり、コンストラクタに任意の名前を付けることができるようになっています。オーバーライドも可能です。インスタンスをnewする際に、以下の形式でコンストラクタを指定します。

  // myinit()はユーザが作成したコンストラクタ
  Point p = new Point.myinit(x, y);

メソッド名を指定せず、単にnew Point(x, y)のように記述した場合、 initializeという名前のコンストラクタが呼び出されます。

列挙型

列挙型は以下のように定義します。

enum Fruits {
  APPLE,
  BANANA,
  ORANGE,
};

使うときは以下のように参照します。

  Fruits f = Fruits.ORANGE

delegate
delegate型は関数を指す参照型です。予約語delegateの後ろに関数シグネチャ宣言と同じ形式で定義します。

  delegate boolean MouseButtonClicked(int x, int y, ButtonKind kind);

式の中に関数名を単に記述することで、関数型の値が生成されます。関数型の値は、代入互換性のある delegate型変数に代入可能できます。関数の引数として渡したり、戻り値として受けることもできます。

boolean mouseButtonHandler(int x, int y, ButtonKind kind) {
    ……
} 

// buttonオブジェクトのsetMouseButtonHandlerメソッドに、
// mouseButtonHandler関数を引数として渡す。
button.setMouseButtonHandler(mouseButtonHandler);

delegate型変数には、関数だけでなくメソッドも代入可能です。その場合、delegate型変数は、メソッドに対応するインスタンスを併せて保持します。