# Volang 言語
Volang(Voldeno の独自プログラミング言語)のドキュメントへようこそ。スマートホームエコシステム全体の Blocks にわたるロジック実装の中核ツールです。
# はじめに
Volang は Voldeno が開発した専用プログラミング言語で、スマートホームエコシステム内の Blocks のロジックを実装するために設計されています。ハードウェアの能力と高レベルの自動化の間をつなぎ、開発者が高度な制御シナリオを効率的かつ安全に作成できるようにします。
Volang の主な目的は Blocks の振る舞いを定義することです。Voldeno システムでは、Block は自律的な機能単位(例: ローラーシャッター制御、サーモスタット、エネルギーメーター)を表します。Volang では、これらの Blocks が入力信号にどう反応し、内部状態を処理し、イベントに基づいてアクションを起こすかを定義できます。
# アーキテクチャ: コンパイルモデル
テキストから直接解釈される単純なスクリプト言語とは異なり、Volang は 仮想マシン(VM) アーキテクチャを採用しています。実行プロセスは次の 2 段階に分かれます。
- コンパイル: 開発者が書いたソースコードは Volang Compiler によって処理されます。この段階で構文、データ型、論理の整合性が検証され、コードは bytecode と呼ばれる最適化されたバイナリ形式に変換されます。
- 実行: 生成された bytecode は Volang Virtual Machine(Volang VM) に読み込まれます。これは Voldeno コントローラ上で動作する専用ランタイム環境です。VM は bytecode 命令を解釈し、物理ハードウェア上で安全に実行します。
# なぜ Volang VM か
仮想マシンアーキテクチャを採用すると、スマートホーム環境において大きな利点があり、開発ワークフローを統一し、ハードウェアの能力を拡張できます。
- 安全性(サンドボックス): ユーザーコードはコア OS から分離された独立環境で実行されます。実行時エラー(例: ゼロ除算)は VM 内の特定スクリプトだけを停止し、コントローラ全体の安定性は保たれます。
- パフォーマンス: コンパクトなバイナリ bytecode の実行は、実行時にテキストファイルを解析するよりもはるかに高速でリソース効率が高く、組み込みシステムやマイコンに重要です。
- 移植性: Volang で書いたロジックはハードウェア非依存です。基盤となるプロセッサアーキテクチャに関係なく、Volang VM を実行できる任意のデバイスで動かせます。
- 同一シミュレーション: Volang VM はプラットフォーム間で一貫して動作するため、同じ Block ロジックを Voldeno Studio 内で実行できます。デスクトップ環境でテスト・デバッグしても、本番システムと同一の振る舞いになることが保証されます。
- 分散実行: VM の効率により、中央の Voldeno Hub だけでなく、周辺拡張モジュール上でも実行できます。複雑な処理をデバイス上(エッジ)でローカルに行える真の分散ロジックが可能になり、基本的なイベント報告に限定されません。
# 字句規則
# キーワード
次の語は Volang で予約されており、変数名や関数名として使えません。言語の構造的基盤を形成します。
and break else
extern false fn
if or shl
shr return true
while xor
# リテラル
Volang では リテラル は、ソースコード内に固定値を直接表す記法です。変数に代入したり関数に渡したりする生のデータ値です。Volang は boolean、文字列、整数、浮動小数点リテラル向けに特定の形式をサポートしています。
# Boolean リテラル
論理状態を表すために使います。Boolean リテラルは次の 2 つのみです。
true: 肯定またはアクティブな状態(On)を表します。false: 否定または非アクティブな状態(Off)を表します。
# 整数リテラル
整数リテラルは整数を表します。Volang は 2 つの表記をサポートしています。
- 10 進(基数 10): 数字
0-9を使う標準的な数値表記です。負の数はマイナス記号-を前置します。 - 16 進(基数 16): カラーコード、ビットマスク、ハードウェアアドレスなどでよく使われます。接頭辞
0xの後に0-9とA-F(大文字小文字不問)が続きます。
# 浮動小数点リテラル
浮動小数点リテラルは小数部を持つ数を表します。
- 構文: 小数点
.を小数区切りとする 10 進表記で書きます。 - 要件: 有効な float リテラルは、通常、小数点の前後のいずれかに少なくとも 1 桁が必要です(例:
0.5、10.0、23.34)。
# 文字列リテラル(String)
文字列リテラルは文字の並びを表し、メッセージ、識別子、ラベルなどに使います。
- 構文: テキストは二重引用符
"で囲みます。 - 複数行対応: Volang の文字列リテラルは複数行にまたがれます。引用符内の改行は保持されるため、
\nのようなエスケープを使わずに表示パネルやログ向けテキストを整形できます。
# Raw String
Raw String は、コンパイラが解釈する可能性のある特殊文字や書式を無視し、書いたとおりのテキストを表すために使います。
- 構文: 三重の二重引用符
"""で囲みます。 - 用途: 三重引用符内のすべてがリテラルテキストとして扱われます。コードブロック、複雑な正規表現パターン、整形済みドキュメントの保存に特に有用です。
- 保持: 通常の複数行文字列と同様、
"""区切りの間に現れるインデントと改行はそのまま維持されます。
例:
// --- Boolean Literals ---
is_light_on = true
is_door_locked = false
// --- Integer Literals (Decimal) ---
counter = 10
negative_offset = -5
// --- Integer Literals (Hexadecimal) ---
status_mask = 0xFF // Decimal 255
color_red = 0xFF0000 // Color code
// --- Floating-Point Literals ---
temperature = 23.34
calibration_factor = 0.95
voltage = 12.0 // .0 indicates this is a Float, not an Integer
// --- String Literals ---
device_name = "Living Room Thermostat"
// Multi-line string (preserves formatting)
notification_msg = "
Warning: High Temperature!
Action: Cooling Activated
Time: 12:00
"
// --- Raw String Literal ---
configJson = """
{
"status": "success",
"directory": "C:\users\volang\app",
"pattern": "\b[A-Z0-9._%+-]+",
"description": "No need to escape backslashes or "quotes" here!"
}
"""
# 値と型
Volang は 動的型システム で動作し、柔軟なデータ管理を提供します。Volang では変数は厳密型のストレージではなく汎用コンテナとして機能します。そのため、コード内で int や float などの型を明示的に宣言する必要はありません。型情報は変数ではなく、値そのものに内在します。
# 第一級の値
Volang のすべての値は第一級の値です。型に関係なく、あらゆる値について次が可能です。
- 変数に格納する。
- 関数の引数として渡す。
- 関数から結果として返す。
# 型の一貫性(厳密な型)
Volang は型宣言を要求しませんが、型の安定性 を強制します。変数に特定型の値(例: Integer)を代入すると、その型に固定されます。同じ変数に別型の値(例: String)を後から代入することは できません。これにより一般的な実行時エラーを防ぎ、コントローラの予測可能な動作を保証します。
# 値のカテゴリ
Volang は主に 4 種類の値を区別します。
# 1. 数値(Integer と Float)
数学計算、センサー読み取り、カウンターに使います。
- Integer: 小数部のない整数(例:
0、42、-15)。 - Float: 小数を表す浮動小数点数(例:
3.14、21.5、-0.001)。
# 2. 文字列(String)
ステータスメッセージ、ログ、名前、テキスト処理に使います。String は二重引用符 " で囲んだ文字列です。
- 複数行対応: Volang は複数行文字列をサポートします。引用符内で Enter を押すと、複数行にわたるテキストブロックを作成できます。
# 3. 論理値(Boolean)
Boolean は真偽値を表し、分岐ロジック(if、while)に不可欠です。
- 値:
trueまたはfalse。
# 4. Opaque
Opaque 値は、内部実装が Volang VM によって管理される複雑なデータ構造を表します。ユーザーは直接の構文演算子ではなく、専用の Standard Library 関数を通じて操作します。Opaque 型の例:
- Array: 順序付きのインデックス付き値の集合。
- Map: 各キーが一意なキーと値のペアの集合。
これらは利用可能な Opaque 型の一部です。Standard Library が追加の型を提供する場合があります。Opaque 値も他の型と同様に第一級のルールに従い、変数に格納し、引数として渡し、関数から返せます。ただし、標準の算術演算子や論理演算子には使えません。
例:
// 1. Dynamic Typing
status = 25.5
// 2. Multi-line Strings
config_info = "Device: Thermostat
Location: Living Room
Firmware: v1.2"
// 3. Passing values
fn logStatus(message) {
print(message)
}
logStatus(config_info)
# 変数
Volang は簡潔な変数管理を採用しています。宣言キーワード(var、let、int など)はありません。名前に値を代入した時点で変数が作成されます。変数を定義する位置が、スクリプト全体でのスコープ(可視性)を決めます。
# 変数の作成
変数を定義するには、代入演算子 = を使います。変数のデータ型は代入された値から推論され、その変数の存続期間中は固定されます。
構文:
variable_name = value
# 変数のスコープ
スコープは、コード内のどこから変数にアクセスできるかを定義します。Volang は 2 種類のスコープを区別します。
# グローバル変数
スクリプトのトップレベル(関数や制御ブロックの外)で定義された変数は グローバル です。
- 可視性: スクリプト内のどこからでもアクセスできますが、関数内からはアクセスできません。関数内でグローバル値を使うには、引数として渡してください。
- 用途:
target_temperature、system_mode、alarm_statusなど、デバイス全体の状態を保持するのに適しています。
# ローカル変数
関数(fn)や制御ブロック内で定義された変数は ローカル です。
- 可視性: 作成されたブロック内にのみ存在します。そのブロックから実行が離れると破棄されます。
- 用途: 一時的な計算、ループカウンター、中間ロジックに使います。
例:
// --- Global Variables ---
system_status = "IDLE"
setpoint = 21.5
// Global variables are NOT accessible inside functions.
// Pass them as arguments instead:
fn checkTemperature(current_temp, target) {
// --- Local Variable ---
// 'diff' exists only inside this function
diff = current_temp - target
if diff > 1.0 {
return "Cooling Needed"
}
return "Stable"
}
// Pass the global 'setpoint' as an argument
result = checkTemperature(22.8, setpoint)
// 'diff' is not accessible here
# コメント
コメントは Volang コンパイラが無視するコードの断片です。ロジックの説明、他の開発者へのメモ、テスト中に特定部分を一時的に無効化するために使います。
# 1 行コメント
1 行コメントは 2 つのスラッシュ // で始まります。これらの文字以降、行末までがコメントとして扱われます。
# 複数行コメント
複数行(ブロック)コメントは /* で始まり */ で終わります。これらのマーカー間は行数に関係なくすべて無視されます。
例:
// This is a single-line comment
targetTemp = 21.5 // Comment at the end of a line
/*
This is a multi-line comment.
It is useful for describing complex logic
or block headers.
*/
/* oldLogic = 10
if (oldLogic > 5) {
// This code is disabled
}
*/
# 文
Volang は視覚的ノイズを減らし、可読性を高めるよう設計されています。C++ や Java のような言語とは異なり、Volang は文の終わりを示す セミコロン(;)を使いません。
改行(Enter)が文の終端として機能します。コンパイラは行末を現在の命令の完了と解釈します。
# 代入
代入演算子は変数に値を格納するために使います。Volang は基本的な代入演算子に加え、複合代入演算子をサポートしています。
# 基本代入
= 演算子は右辺の値を左辺の変数に代入します。
target_temp = 21.0
event_counter = 0
# 複合代入演算子
複合演算子は、変数の現在値に対して演算を行い、結果で変数を更新します。
| 演算子 | 説明 |
|---|---|
+= | 加算して代入 |
-= | 減算して代入 |
*= | 乗算して代入 |
/= | 除算して代入 |
主な動作:
- 初期化の要件: 複合演算子では、左辺の変数は すでに存在している必要があります。
- 型の昇格: 複合代入は、通常の算術演算と同じ型昇格ルールに従います。
例:
// Increment counter
event_counter += 1
// Decrease setpoint
target_temp -= 0.5
// Scale brightness to 80%
brightness = 100
brightness *= 0.8 // Result: 80.0
// Energy accumulation
total_energy_kwh = 0.0
current_usage = 1.5
total_energy_kwh += current_usage
# 制御フロー
if 文は Volang の基本的な分岐構造です。条件式は Boolean 値(true または false)に評価される必要があります。整数、浮動小数点、文字列など非 Boolean 値は暗黙に変換されません。条件として使うとコンパイルエラーになります。
# 基本的な if
if (condition) {
// Code to run if condition is true
}
# else 付き if
if (condition) {
// Code to run if condition is true
} else {
// Code to run if condition is false
}
# 連鎖条件(else if)
if (condition_1) {
// Runs if condition_1 is true
} else if (condition_2) {
// Runs if condition_1 is false AND condition_2 is true
} else {
// Runs if all above conditions are false
}
例: サーモスタットロジック
current_temp = 19.0
target_temp = 21.0
hysteresis = 0.5
if (current_temp < (target_temp - hysteresis)) {
// Too cold -> Start Heating
setHeating(true)
} else if (current_temp > (target_temp + hysteresis)) {
// Too hot -> Start Cooling
setCooling(true)
} else {
// Temperature is within the optimal range
setHeating(false)
setCooling(false)
}
# ループ
Volang がサポートするループ構文は while のみです。for や do-while はありません。if と同様、条件式は Boolean 値(true または false)に評価される必要があります。
構文:
while (condition) {
// Code to execute repeatedly
}
Volang はループ内で break キーワードをサポートしています。break に到達すると、ループは直ちに終了します。
注意: 組み込みシステムやスマートホームコントローラでは、無限ループは危険です。条件が
falseにならず、breakにも到達しないwhileループはスクリプト実行をブロックし、Block が以降のイベントに応答しなくなります。ループが終了することを保証するのはスクリプト作者の責任です。
例:
// Basic Counter
counter = 5
while (counter > 0) {
logValue(counter)
counter -= 1
}
// Waiting with Timeout (Using break)
attempts = 0
max_retries = 10
success = false
while (attempts < max_retries) {
if (checkConnection()) {
success = true
break
}
attempts += 1
}
if (success) {
startProcess()
}
# 関数
関数は特定のタスクを実行する再利用可能なコードブロックです。Volang では fn キーワードで関数を定義します。
構文:
fn functionName(argument1, argument2) {
// Code to be executed
}
主なルール:
- 引数: 関数は複数の引数(カンマ区切り)を受け取るか、引数なしでも構いません。
- 戻り値:
returnで値を返します。省略すると何も返しません(void)。 - 命名制約: 関数名は Standard Library の関数名と重複してはいけません。
- スコープ: 関数内で定義された変数はその関数のローカルです。
- グローバルへのアクセスなし: グローバル変数は関数内から アクセスできません。関数が必要とする外部データはすべて引数として渡してください。
例:
fn calculateAverage(a, b, c) {
total = a + b + c
return total / 3
}
avg = calculateAverage(20.5, 21.0, 19.5)
# 式
# 二項算術演算子
| 演算子 | 説明 |
|---|---|
+ | 加算 |
- | 減算 |
* | 乗算 |
/ | 除算 |
% | 剰余 |
優先順位: 乗算、除算、剰余は加算・減算より先に評価されます。
例:
// Sensor Calibration
raw_value = 50
scale_factor = 1.2
offset = 5.0
calibrated_value = raw_value * scale_factor + offset // 65.0
// Average with parentheses
average_temp = (temp_1 + temp_2 + temp_3) / 3
// Modulo for cyclical events
remainder = loop_counter % 10
# 二項論理演算子
| 演算子 | 説明 |
|---|---|
and | 論理 AND。両オペランドが true のときのみ true を返す |
or | 論理 OR。少なくとも一方が true なら true を返す。両オペランドは常に評価される(短絡評価なし) |
例:
// Conditional Lighting (AND)
if (motion_active and brightness_level < threshold) {
setLight(true)
}
// Redundant Triggering (OR)
if (door_open or window_vibration) {
triggerAlarm()
}
// Complex Logic (Grouping)
heating_on = manual_override or (is_weekend and user_home)
# 二項ビット演算
ビット演算は整数値内の個々のビットを直接操作します。
| 演算子 | 説明 |
|---|---|
& | ビット AND |
| | ビット OR |
xor | ビット XOR |
shl | 左シフト |
shr | 右シフト |
例: マスク用ビット AND
sensor_value = 0xA7 // Binary: 1010 0111
mask = 0x0F // Binary: 0000 1111
// Extract only the lower 4 bits
lower_nibble = sensor_value & mask
// Result: 0x07 (Binary: 0000 0111)
