HSPでオブジェクト指向風

目次

HSPの仕様

基本的にHSPは初心者向けで、上から下へと実行されていくスクリプト言語です。

ラベル機能があり、goto命令やgosub命令でラベルにジャンプすることで実行順序を制御できます。

Windows用の実行ファイルを手軽に作るのに向いていて、標準の命令で簡単にGUIを作成できます。(Androidなどその他プラットフォーム向けの作成機能もあります。)

 

型を意識せずに変数を扱うことができ、基本的にはすべての変数がグローバルでスコープの概念がありません。

初心者が悩まずに扱えるように考慮されていますが、大規模なものを作成しようとするとこのままでは仕様上難しくなってきます。

そのため、上級者向けにモジュール機能が用意されています。

 

モジュール機能

#module~#globalまでの間がモージュル空間になります。

モジュール内では変数は独立しているため、グローバル空間の変数と名前を重複させることもできます。

 

	a = "hello"
	greet2
	greet
	mes a

#module
	#deffunc greet
		a = "こんにちは"
		mes a
		return

#global

#module
	#deffunc greet2
		a = "こんばんは"
		mes a
		return

#global
	mes a
	stop

//	実行結果:
//	こんばんは
//	こんにちは
//	hello
//	hello

この例では、グローバル空間の変数aとモジュール内の変数aの値が独立して保持されているのがわかると思います。

また、モジュールが2つありますがそれぞれの内容も独立しています。

今回の例ではモジュール名を与えていませんが、moduleごとに個別のIDで管理されています。

deffuncについては後述します

 

deffuncとdefcfunc

hspにはユーザ定義命令(deffunc)とユーザ定義関数(defcfunc)が用意されていて、他の言語の関数のような書き方が可能です。

先ほどの例で既にふれていますが、一応サンプル

	//下で定義した命令の呼び出し
	文字列を結合 "hello", "everyone"
	stop

	//文字列を結合という名前の命令を定義
	#deffunc 文字列を結合 str p1, str p2
		mes p1 + " " + p2
		return
//実行結果:
//hello everyone

命令と関数の違いは戻り値の有無です。

命令は戻り値無し(returnの後に何も書かない)、関数は戻り値あり(returnの後ろに戻り値を書く)

 

modfuncとmodcfunc

命令、関数の区別はdeffunc、defcfuncと一緒です。

modfuncのdeffuncとの違いはインスタンスを生成して呼び出す点です。

Javaのクラスの概念と似通った点が多いので、Javaのソースコードと併記します。

 

まずはjava

class Person {

	private String name;
	public static int count;

	Person(String p1) {
		name = p1;
		count++;
	}

	public void printName() {
		System.out.println(name);
	}
	
	public static int getCount() {
	    return count;
	}
	
	public String getName() {
	    return name;
	}
}

public class Main {

	public static void main(String[] args) {
		Person per = new Person("山田");
		per.printName();
		System.out.println(per.getName() + "は" + Person.getCount() + "人目です。");

		Person per2 = new Person("田中");
		per2.printName();
		System.out.println(per2.getName() + "は" + Person.count + "人目です。");
	}
}
//実行結果:
//山田
//山田は1人目です。
//田中
//田中は2人目です。

実行結果をみればわかると思いますが、インスタンスフィールドであるname(static無し)はそれぞれのインスタンスで別々の名前が代入されています。

一方で、クラスフィールドであるcount(staticあり)はインスタンス間で共有されているのがわかります。

また、nameはprivateなため、ゲッター(getNameメソッド)経由で取得しています。

 

続いてhspのソースコードです。

//nameはここに書かないとコンストラクタで引数を受け取れないっぽい
//ここで定義した奴は非staticかつprivateになっている?
#module Person name

	#modinit str p1
		name = p1
		count++ //ここで定義するとstaticかつpublic?
		return

	#modfunc printName //modfuncは非static
		mes name
		return

	#defcfunc getCount //defcfuncはstatic(勿論deffuncも)
		return count 

	#modcfunc getName //modcfuncも非static
		return name
 
#global

	main //javaに形式を合わせてmainを作って呼び出した
	stop

	#deffunc main
		newmod per, Person, "山田" //インスタンスの生成
		printName per
		//nameはprivateなのでゲッターを使わないと取得不可
		mes getName(per) + "は" + getCount() + "人目です。"
	
		newmod per2, Person, "田中"
		printName per2
		//countはstaticかつpublicなので@モジュール名を末尾につければ呼び出せる
		mes getName(per2) + "は" + count@Person + "人目です。"
		return
//実行結果:
//山田
//山田は1人目です。
//田中
//田中は2人目です。

実行結果はJavaと同じです。(というかなるべく同じ構造で作りました)

変数名などは同じにしているため、比較しやすいと思います。

注意点として、HSPは大文字/小文字を区別しません。Javaに合わせて書いているだけです。

こう見ると文法は違いますが同じような概念で書けていることがわかるはずです。

 

まとめ

前置きが長くなりました。

HSPをJavaの概念に当てはめると、おおよそこんな感じだと思います。

  • module → class
  • ユーザ定義命令(deffunc) → クラスメソッド(public static void)
  • ユーザ定義関数(defcfunc) → クラスメソッド(public static 戻り値の型)
  • module命令(modfunc) → インスタンスメソッド(public void)
  • module関数(modcfunc) → インスタンスメソッド(public 戻り値の型)

 

HSPはGUIが簡単に作成できるので、ちょっとしたツールを作るのには重宝します。

普段からオブジェクト指向型の言語を使っている人も、一度はトライしてみるとよいと思います。