Aura 仕様書

最終更新: 2026-06-16 統合元: AURA_ARCHITECTURE.md / AURA_MANUAL.md


概要

Aura(アウラ)は AtmOS の組み込みスクリプト言語。S 式(Lisp ライク)の関数型スタイルで記述し、ターミナル(REPL)から直接実行できる。OS のコア機能(ファイルシステム・ネットワーク・グラフィック・オーディオ)へ組み込み関数としてアクセスする。ソースファイルの拡張子は .aura

注意(2026-06-15〜): ブラウザの <script> / onclickJavaScript エンジンos_lib/js/)が 実行する。Aura は .aura アプリと REPL 専用であり、Web ページのスクリプトには使われない。 JavaScript エンジンの設計は DESIGN.md の「JavaScript エンジン」節を参照。

設計思想


1. 基本構文

要素 記法
整数リテラル 数字の並び(符号付き可)。10進数のほか、2進数 (0b), 8進数 (0o), 16進数 (0x) 表記をサポート(プレフィックスは小文字のみ)。 42, -7, 0b101, 0o755, -0xFA
文字列リテラル " または ' で囲む "hello", 'world'
テンプレートリテラル ` で囲み、${式:書式} を埋め込む `hello ${name}`
シンボル(識別子) 英数字・記号の並び ping, +, my-var
関数呼び出し 関数名(引数, ...) ping("1.2.3.4"), +(1, 2)
プロパティアクセス オブジェクト:キー または オブジェクト.キー net:udp / net.udp
リスト (要素 要素 ...) (1 2 3)
辞書 {key: value, ...} {"name": "Alice", "age": 30}
コメント # / ## / #| ... |# / ##| ... |## # 1行コメント, #| ブロックコメント |#
区切り スペース・タブ・改行・カンマはすべて区切り扱い

関数呼び出し

関数型記法(唯一の形式)

関数名(arg1, arg2, arg3)
net.udp("send", "192.168.1.1", 5000, "hello")
+(1, 2, 3)

括弧 () は常にリストリテラルです。S式の関数呼び出し (func arg1 arg2) は使用できません。

引数を持たない関数呼び出し

括弧は省略可能:

net()  ≡  net
date() ≡  date

プロパティアクセス(辞書キーへのアクセス)

コロン記法(: - 推奨

net:udp    ; net オブジェクトの "udp" キーを取得
math:PI    ; math オブジェクトの "PI" キーを取得

ドット記法(. - JavaScriptライク

net.udp    ; コロン記法と同等
math.PI

関数呼び出しと組み合わせる場合

net.udp("send", "192.168.1.1", 5000, "msg")
net:udp("send" "192.168.1.1" 5000 "msg")

注意: net.udp は内部的に (get net "udp") に変換されます。net が辞書でない場合、“cannot call dict as function” エラーが出ます。

コメント構文 (Comment Syntax)

Aura は以下の 4 つのコメント形式をサポートします。これらは処理系(インタプリタ)の実行時にはすべて無視(スキップ)されますが、エディタでの自動インデントや整形ツールにおいてそれぞれ独自のインデント規則を持ちます。

  1. 1行コメント(インデント継承): # から始まり、そこから行末までの範囲をコメントとします。
  2. 1行コメント(インデント無視): ## から始まり、そこから行末までの範囲をコメントとします。
  3. ブロックコメント(インデント継承): #||# で囲まれた範囲を複数行コメントとします。
  4. ブロックコメント(インデント無視): ##||## で囲まれた範囲を複数行コメントとします。

文字列リテラルは " のほか ' も使用できる。JavaScriptやPythonと同様に、" で囲んだ文字列内では ' をそのまま記述でき、' で囲んだ文字列内では " をそのまま記述できる(エスケープ不要)。

テンプレートリテラルは ` で囲み、内部で ${式} または ${式:書式} の形式で値を埋め込むことができる。書式指定は Python の書式指定ミニ言語を参考にしており、2進数 (b)、16進数 (x/X)、カンマ区切り (,)、浮動小数点精度表示 (f, e/E)、幅、ゼロ埋め、# プレフィックスなどが指定可能(例: ${val:08b}, ${pi:.3f}, ${hex_val:#010x})。テンプレート内で文字 $ 自体を描画したい場合は $$ とエスケープする。

[!NOTE] 文字列リテラルの詳細な囲み・エスケープ制限、整数リテラルの進数表記ルール、テンプレート書式のパラメータ詳細、およびシンボル(識別子)の厳密な定義については、AURA_SYNTAX_DETAILS.md を参照してください。

特殊フォーム

フォーム 構文 説明
def / set / func def(name, expr) シンボルを環境にバインドする
if if(cond, then, else) condnil または 0 のとき else を評価
while while(cond, body, ...) cond が真の間 body を繰り返す
for for(var, list, body, ...) list の各要素に対して body を評価
condition condition((cond1 exp1) ...) 複数条件を順に評価し最初に真になった式を評価
case case(x (val1 exp1) ...) x の値に一致する条件を評価
lambda / fn lambda((args...), body) 無名関数を作成

値の種類

説明 リテラル例
Num(BigInt) 任意精度整数 10進数 (42, -7), 2進数 (0b101), 8進数 (0o755), 16進数 (0xFA) をサポート
Ratio 有理数(除算結果など) 1/3, 5/2
Str(String) 文字列 "hello", 'world'
Symbol シンボル(識別子・変数) foo, my-var, +
List リスト (1 2 3), () (空リスト)
Dict 辞書(オブジェクト) {"key": "value"}, {"a": 1, "b": 2}
Bool 真偽値 true, false, True, False
nil 空値・偽値 nil

型システム

型チェック関数 type()

任意の値の型を文字列で取得:

type(42)           ; => "Num"
type("hello")      ; => "Str"
type(true)         ; => "Bool"
type((1 2 3))      ; => "List"
type({"a": 1})     ; => "Dict"
type(nil)          ; => "Nil"
type(math.PI)      ; => "Num"
type(+)            ; => "BuiltinFunc"
type(lambda((x), +(x, 1))) ; => "Lambda"

型変換

文字列への変換:

+(10)              ; 数値を評価 => 10
str.length("hello") ; 文字列の長さ => 5

数値への変換: 利用可能な変換関数はありません。文字列から数値への変換は手作業で行う必要があります。


2. EBNF(構文定義)

program          = { expression } ;
expression       = property_access | function_call | list | dictionary
                 | identifier | number | string | template_string ;
property_access  = identifier , ":" , ( identifier | string ) ;
function_call    = identifier , "(" , [ expression_list ] , ")" ;
list             = "(" , [ expression_list ] , ")" ;
dictionary       = "{" , [ dictionary_pair_list ] , "}" ;
expression_list  = expression , { [ separator ] , expression } ;
dictionary_pair  = string , ":" , expression ;
identifier       = ( letter | symbol_char ) , { letter | digit | symbol_char } ;
number           = [ "+" | "-" ] , ( radix_number | decimal_number ) ;
radix_number     = ( "0b" , binary_digit , { binary_digit } )
                 | ( "0o" , octal_digit , { octal_digit } )
                 | ( "0x" , hex_digit , { hex_digit } ) ;
decimal_number   = digit , { digit } ;
binary_digit     = "0" | "1" ;
octal_digit      = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" ;
hex_digit        = digit | "a" | "b" | "c" | "d" | "e" | "f" | "A" | "B" | "C" | "D" | "E" | "F" ;
string           = ( '"' , { character_except_double_quote } , '"' )
                 | ( "'" , { character_except_single_quote } , "'" ) ;
template_string  = "`" , { character_except_backtick | placeholder } , "`" ;
placeholder      = "${" , expression , [ ":" , format_spec ] , "}" ;
format_spec      = [ "#" ] , [ "0" ] , [ width ] , [ "," ] , [ "." , precision ] , [ fmt_type ] ;
separator        = " " | "\t" | "\r" | "\n" | "," ;
symbol_char      = "+" | "-" | "*" | "/" | "<" | ">" | "=" | "!" | "?"
                 | "_" | "$" | "&" | "|" | "%" | "@" | "#" | "~" | "^" | "." ;

構文ダイアグラム(鉄道図)

以下は上記 EBNF を PlantUML のネイティブ EBNF 図としてレンダリングしたものです (GitHub Actions の pages.yml@startebnf ブロックを PNG 画像に変換します)。


3. 内部アーキテクチャ

AST(抽象構文木)

Expr 列挙型にすべてのデータとコードがマッピングされる。

Expr:
  Nil
  Num(BigInt)
  Ratio(BigInt, BigInt)
  Str(String)
  Symbol(String)
  List(Vec<Expr>)
  Dict(HashMap<String, Expr>)
  Func(CustomFunction)
  NativeFunc(NativePointer)

EnvironmentHashMap<String, Expr> と親環境への参照で構成される(レキシカルスコープ)。

評価フロー

eval(expr, env):
  Num / Str / Nil / Func  → 自己評価(そのまま返す)
  Symbol                  → env.lookup(name)
  List(空)              → Nil
  List(先頭が特殊フォーム)  → def / if / while / for / lambda を特別処理(引数を事前評価しない)
  List(先頭が関数)       → 全引数を eval → apply(fn, args)
  Dict                   → 各 value を eval した新 Dict

OS 統合

NativeFunc として OS コア機能を直接呼び出す(syscall 不要):

字句解析(Lexer)状態機械

Init:
  空白・カンマ → SkipWhitespace → Init
  数字・符号   → NumberState → Emit Token::Num
  "           → StringState → Emit Token::Str
  文字・記号   → IdentifierState → Emit Token::Symbol
  ( ) { } :   → Emit Token::Punctuation

実行シーケンス(REPL)

Shell/REPL
  → Lexer.tokenize(source) → Vec<Token>
  → Parser.parse(tokens)   → Expr (AST)
  → Evaluator.eval(expr, env)
       → env.lookup / apply_function
  → Expr (Result) → 表示

実装ファイル

ファイル 役割
src/os_lib/aura/lexer.rs トークナイザ
src/os_lib/aura/parser.rs パーサ(AST 生成)
src/os_lib/aura/eval.rs 評価器・環境管理
src/os_lib/aura/builtins.rs 組み込み関数の実装
src/os_lib/aura/number.rs 任意精度整数・有理数
src/apps/terminal/shell.rs REPL ループ

4. データ構造の詳細

辞書(Dictionary / Dict)

Auraの辞書はキーと値のペアを格納するオブジェクトです。JavaScriptのオブジェクトやPythonの辞書に相当します。

辞書の作成

リテラル形式:

{"name": "Alice", "age": 30, "city": "Tokyo"}
{"key": "value"}
{}  ; 空の辞書

プログラムで生成:

set(person, {"name": "Bob", "age": 25})

辞書へのアクセス

コロン記法(推奨):

set(user, {"name": "Alice", "age": 30})
user:name          ; => "Alice"
user:age           ; => 30
user:unknown       ; => nil (キーが存在しない場合)

ドット記法(JavaScriptライク):

user.name          ; => "Alice"
net.udp            ; net 辞書の "udp" キーを取得(関数)

プログラムによるアクセス(get 関数):

get(user, "name")  ; => "Alice"

辞書の更新

set 関数(3引数形式):

set(user, "age", 31)   ; user["age"] = 31

辞書内の関数呼び出し

多くのAura名前空間は辞書として実装されており、その中に関数が格納されています。

; net 辞書内の udp 関数を呼び出し
net.udp("send", "192.168.1.1", 5000, "hello")
net:udp("send", "192.168.1.1", 5000, "hello")

; math 辞書内の sqrt 関数を呼び出し
math.sqrt(16)      ; => 4
math:sqrt(16)

; fs 辞書内の ls 関数を呼び出し
fs.ls()
fs:ls()

リスト(List)

リストは順序付きの要素の集合です。

リストの作成

(1 2 3 4 5)        ; リストリテラル
("a" "b" "c")      ; 文字列のリスト
()                 ; 空リスト
range(0, 10)       ; 0 から 9 のストリームを生成(遅延評価)

リストへのアクセス

set(arr, (10 20 30))
arr(0)             ; => 10 (インデックス 0)
arr(1)             ; => 20 (インデックス 1)
arr(2)             ; => 30
arr(10)            ; => nil (範囲外)
arr(-1)            ; => nil (負のインデックスは未対応)

リストのスライス

set(arr, (10 20 30 40 50))
arr(1, 4)          ; => (20 30 40) (インデックス 1 から 3)
arr(0, 2)          ; => (10 20)

リスト操作関数

length((1 2 3))    ; => 3
cons(0, (1 2 3))   ; => (0 1 2 3) (先頭に追加)
car((1 2 3))       ; => 1 (最初の要素)
cdr((1 2 3))       ; => (2 3) (最初以外の部分)
map(lambda((x), *(x, 2)), (1 2 3))    ; => (2 4 6)
filter(lambda((x), >(x, 2)), (1 2 3)) ; => (3)
fold(lambda((acc, x), +(acc, x)), 0, (1 2 3)) ; => 6 (合計)

5. 組み込み関数リファレンス

関数は名前空間(辞書)に所属しているものと、グローバル(所属なし)で呼び出せるコア関数に分かれます。

グローバル(所属なし / コア関数)

これらは名前空間を指定せずに直接呼び出すことができます。

関数・演算子 構文 説明
+, -, *, / +(a, b, ...) 四則演算。/Ratio(有理数)を返す
=, eq eq(a, b) 等価判定
!=, neq neq(a, b) 不等価判定
<, lt lt(a, b) 未満
<=, le, lte le(a, b) 以下
>, gt gt(a, b) 超過
>=, ge, gte ge(a, b) 以上
and and(a, b, ...) 論理積
or or(a, b, ...) 論理和
not not(a) 論理否定
xor xor(a, b, ...) 排他的論理和
print print(expr, ...) 出力
type type(val) 型判定
list list(a, b, ...) リスト生成
cons cons(head, list) リストの先頭に要素を追加
car car(list) リストの先頭要素を取得
cdr cdr(list) リストの先頭以外の部分を取得
map map(fn, list) マップ処理
filter filter(fn, list) フィルタ処理
fold fold(fn, init, list) 左畳み込み
length length(x) リスト・文字列・辞書の長さを取得
get get(obj, key) リストや辞書の要素取得
range range(start, end, step) ストリーム(レンジ)生成
take take(n, stream) ストリームから要素を取得しリストにする
to-list to-list(stream) ストリームをリストに変換
show show("name") ファイル内容を表示
load load("path.aura") スクリプトファイルの評価実行
require require("path.aura") 重複ロード防止付きスクリプト実行
date date() 現在のシステム日時を取得
ntp ntp() NTPサーバーと時刻同期を行う

※ 利便性向上のため、ls, cd, pwd, mkdir, cp, mv, rm, cat, grep, head, tail, ping, apps はグローバルから直接呼び出せるエイリアスも定義されています。


math 名前空間 (数学・演算)

math オブジェクトに属する数学関数および定数です。

関数 構文 説明
math.PI math.PI 円周率定数 (3.14159…)
math.EULER math.EULER ネイピア数定数 (2.71828…)
math.abs math.abs(a) 絶対値
math.sign math.sign(a) 符号関数
math.sqrt math.sqrt(a) 平方根
math.exp math.exp(a) 指数関数
math.log2 math.log2(a) 底が2の対数
math.log10 math.log10(a) 底が10の対数
math.sin, math.cos, math.tan (a) 三角関数
math.arc-sin, math.arc-cos, math.arc-tan (a) 逆三角関数
math.hyp-sin, math.hyp-cos, math.hyp-tan (a) 双曲線関数
math.hyp-arc-sin, math.hyp-arc-cos, math.hyp-arc-tan (a) 逆双曲線関数
math.greatest-com-div math.greatest-com-div(a, b) 最大公約数 (GCD)
math.least-com-mul math.least-com-mul(a, b) 最小公倍数 (LCM)
math.random math.random() 乱数を取得
math.odd, math.even (a) 奇数/偶数判定
math.factorial math.factorial(n) 階乗
math.complex math.complex(real, imag) 複素数生成
math.real-part math.real-part(c) 複素数の実部
math.imag-part math.imag-part(c) 複素数の虚部
math.numerator math.numerator(r) 有理数の分子
math.denominator math.denominator(r) 有理数の分母

bit 名前空間 (ビット演算)

bit オブジェクトに属するビット演算関数です。

関数 構文 説明
bit.and bit.and(a, b, ...) ビット論理積 (AND)
bit.or bit.or(a, b, ...) ビット論理和 (OR)
bit.xor bit.xor(a, b, ...) ビット排他的論理和 (XOR)
bit.not bit.not(a) ビット否定 (NOT)
bit.l-shift bit.l-shift(a, b) 左ビットシフト
bit.r-shift bit.r-shift(a, b) 右ビットシフト

fs 名前空間 (ファイルシステム)

fs オブジェクトに属するファイルシステム操作関数です。

関数 構文 説明
fs.ls fs.ls([path]) ディレクトリ内のファイル一覧を表示
fs.cd fs.cd(path) カレントディレクトリを変更
fs.pwd fs.pwd() 現在のカレントディレクトリを取得
fs.mkdir fs.mkdir(path) 新しいディレクトリを作成
fs.cp fs.cp(src, dest) ファイルをコピー
fs.mv fs.mv(src, dest) ファイルを移動/リネーム
fs.rm fs.rm(path) ファイルまたはディレクトリを削除
fs.cat fs.cat(path) ファイルの中身を表示
fs.head fs.head(path, [n]) ファイルの先頭部分を表示
fs.tail fs.tail(path, [n]) ファイルの末尾部分を表示
fs.grep fs.grep(pattern, path) ファイル内をパターン検索
fs.save fs.save(name, data, [labels]) ファイルを新規保存 (ラベル指定可能)
fs.find fs.find(label) 指定ラベルを持つファイルを検索

net 名前空間 (ネットワーク)

net オブジェクトに属するネットワーク関連の関数です。

関数 構文 説明
net.info net.info() ネットワークインターフェース情報を表示
net.nic net.nic() NICのデバッグ情報を表示
net.dhcp net.dhcp(op) DHCPクライアント操作 (“show”/“start”/“renew”/“release”)
net.arp net.arp(op, ...) ARP操作 (“show”/“whohas”/“inject”)
net.dns net.dns(host) DNS Aレコードの解決
net.ping net.ping(ip_or_host) ICMP Echo Request送信(IPアドレス、またはホスト名指定可能)
net.udp net.udp(op, ...) UDPソケット操作 (“recv”/“send”)
net.tcp net.tcp(op, ...) TCPソケット操作 (“show”/“connect”/“close”)
net.http net.http("get", host, [path]) HTTP GETリクエスト送信
net.https net.https("get", host, [path]) HTTPS GETリクエスト送信 (TLS)
net.ntp net.ntp() NTPサーバーと時刻同期を行う

dom 名前空間 (Web/UI DOM操作)

dom オブジェクトに属する、ブラウザやアプリウィンドウ内のDOM要素を操作するための関数です。

関数 構文 説明
dom.get_value dom.get_value(id) 指定要素(テキストボックス等)の入力を取得
dom.set_value dom.set_value(id, val) 指定要素に入力値を設定
dom.get_content dom.get_content(id) 指定要素のテキストコンテンツを取得
dom.set_content dom.set_content(id, val) 指定要素にテキストコンテンツを設定

os 名前空間 (システム管理・アプリ起動)

os オブジェクトに属する、システム管理やアプリのライフサイクル制御のための関数です。

関数 構文 説明
os.settings os.settings() システム設定を表示
os.keymap os.keymap([layout]) キーボードレイアウトの確認・変更 (“us”/“js”)
os.keyrepeat os.keyrepeat(...) キーリピートパラメータの確認・変更
os.addlabel os.addlabel(file, label) ファイルにラベルを追加
os.corrupt os.corrupt(sector) 指定ディスクセクタを破壊 (デバッグ用)
os.apps os.apps() インストール済みアプリ一覧を表示
os.run os.run(app_name) アプリケーションの実行
os.launch_gui os.launch_gui(app_name, [args]) GUIアプリケーションを起動する(例: "browser", "drive")。起動オプションとしてウィンドウ状態("normal", "maximized", "minimized", "fullscreen", 未指定時は最大化)や、サイズ直接指定("800x600", 指定時は自動的に通常起動)の指定をサポート。
os.template-eval os.template-eval(template, values, formats) プレースホルダ ${} を含むテンプレート文字列に値を埋め込んで評価する
help / os.help help() / help("net") コマンド一覧を表示。カテゴリ指定で詳細("net" / "fs" / "math" / "script"
os.set_template_guard os.set_template_guard(lambda) テンプレート展開前の事前ガード関数を設定。ラムダは (template_str, values_list) を受け取り、真偽値を返す。nil で解除。
os.set_template_post_guard os.set_template_post_guard(lambda) テンプレート展開後の事後ガード関数を設定。ラムダは (result_str) を受け取り、真偽値(またはサニタイズ後の代替文字列)を返す。nil で解除。

sound 名前空間 (オーディオ)

sound オブジェクトに属するオーディオ操作関数です。

関数 構文 説明
sound.play sound.play(freq, duration_ms) 単音の非同期再生
sound.play_mml sound.play_mml(mml_string) MMLの非同期再生
sound.music sound.music() 音楽プレイヤー (Music Player) アプリを起動する

draw 名前空間 (グラフィック描画)

draw オブジェクトに属する画面描画のための関数です。

関数 構文 説明
draw.create_canvas draw.create_canvas([title]) キャンバスアプリのウィンドウを生成し、その canvas_id を返す
draw.boxfill draw.boxfill(canvas_id, x0, y0, x1, y1, color) 指定されたキャンバス内の矩形を指定色で塗りつぶす
draw.draw_string draw.draw_string(canvas_id, x, y, text, color, size) 指定されたキャンバスに文字列を描画する
draw.clear_screen draw.clear_screen(canvas_id, color) 指定されたキャンバス全体を指定色でクリアする

str 名前空間 (文字列操作)

str オブジェクトに属する文字列のユーティリティ関数です。

関数 構文 説明
str.split str.split(target, delimiter) 文字列の分割。リストを返す
str.join str.join(list, delimiter) 文字列リストの結合。文字列を返す
str.substring str.substring(target, start, [end]) 部分文字列の抽出 (文字数基準)
str.length str.length(target) 文字列の文字数を取得
str.replace str.replace(target, from, to) 文字列の置換

task 名前空間 (スレッド・並行処理)

task オブジェクトに属する、スレッドの生成と同期・通信のための関数です。

関数 構文 説明
task.parallel task.parallel(lambda) lambdaを別スレッドで非同期に実行する
task.fork_join task.fork_join(lambda_list) 複数のタスクを並行起動し、完了をスピン待機して結果リストを返す
task.queue task.queue() スレッド間通信用のスレッドセーフキューオブジェクトを生成
task.send task.send(q, val) キューにデータを送信
task.recv task.recv(q) キューからデータを受信 (値が空の場合は待機)
task.close task.close(q) キューを閉じる

9. アプリパッケージ仕様

macOS .app バンドルと同様に、/apps/ フォルダへのコピー=インストール、削除=アンインストール。インストーラ不要・依存関係なし。

/apps/
└── hello/
    ├── manifest.json   (必須)アプリ情報・権限定義
    └── main.aura        (必須)エントリポイント

manifest.json:

{
  "name": "hello",
  "version": "1.0.0",
  "display_name": "Hello World App",
  "description": "サンプルアプリです",
  "entry": "main.aura",
  "permissions": ["fs_user"],
  "width": 800,
  "height": 600
}
フィールド 必須 説明
name アプリ ID(ディレクトリ名と一致させる)
version バージョン番号
display_name - 表示名(省略時は name
description - アプリの説明
entry - エントリポイントファイル(省略時は main.aura
permissions - fs_user / fs_global / net / audio / graphics
width - 通常表示("normal")起動時のデフォルト幅(省略時は 500
height - 通常表示("normal")起動時のデフォルト高さ(省略時は 600

アプリのデータ保存先: /data/apps/{app_name}/(アンインストール時に消すかはユーザー判断)


6. エラーハンドリング・デバッグ(移動)

よくあるエラー

1. EvalError: cannot call 'xxx' as function

原因: 辞書やリストなどの非関数値を関数として呼び出そうとしている。

; ❌ エラー: net は辞書で、関数ではない
net("send", ...)

; ✅ 正解: net オブジェクト内の udp 関数を呼び出す
net.udp("send", ...)
net:udp("send", ...)

2. Key 'xxx' not found in dictionary

原因: 辞書に存在しないキーにアクセスしようとしている。

set(user, {"name": "Alice", "age": 30})

; ❌ エラー: "email" キーが存在しない
user:email

; ✅ 存在確認が必要な場合
; キーが存在しなければ nil が返される(エラーにならない)
user:unknown_key  ; => nil

3. List index must be a number

原因: リストのインデックスとして数字以外を使用している。

set(arr, (10 20 30))

; ❌ エラー: "a" は数字ではない
arr("a")

; ✅ 正解: 数字のインデックス
arr(0)  ; => 10

4. Cannot apply non-function: {...}

原因: 辞書をそのまま関数のように呼び出している。

; ❌ エラー
{"name": "Alice"}("key")

; ✅ 正解
set(user, {"name": "Alice"})
user:name

5. TypeError: nil cannot be evaluated as a boolean condition

原因: if, while など条件評価で nil を使用している。

; ❌ エラー
if(nil, print("true"), print("false"))

; ✅ 正解: false または 0 を使用
if(false, print("true"), print("false"))
if(0, print("true"), print("false"))

デバッグテクニック

1. 値の型を確認する:

type(net)          ; => "Dict"
type(net.udp)      ; => "BuiltinFunc"
type((1 2 3))      ; => "List"

2. 値の内容を表示する:

print(net)         ; 辞書の内容を表示
print(user:name)   ; 特定の値を表示

3. 式を段階的に評価する:

; 全体で失敗する式を、部分ごとに評価
print(net)         ; net が何か確認
print(net.udp)     ; net.udp が関数か確認
print("send")      ; 引数を確認
net.udp("send", "192.168.1.1", 5000, "msg")  ; 全体を実行

7. 使用例

基本的な算術と変数

; 算術演算
+(1, 2, 3)               ; => 6
*(5, 4)                  ; => 20
/(10, 3)                 ; => 10/3 (有理数)
-(100, 25)               ; => 75

; 変数の定義
set(x, 10)
set(message, "Hello, Aura!")
print(message)           ; => "Hello, Aura!"

; 変数の参照
x                        ; => 10
+(x, 5)                  ; => 15

関数定義と呼び出し

; 無名関数(ラムダ)を定義して変数に格納
func(double, lambda((x), *(x, 2)))
double(5)                ; => 10

; 複数引数の関数
func(add3, lambda((a, b, c), +(a, b, c)))
add3(1, 2, 3)           ; => 6

; 関数を引数として渡す(高階関数)
map(lambda((x), *(x, 2)), (1 2 3))  ; => (2 4 6)
filter(lambda((x), >(x, 5)), (3 7 2 8 1)) ; => (7 8)

辞書操作と名前空間アクセス

; 辞書の作成と アクセス
set(user, {"name": "Alice", "age": 30, "city": "Tokyo"})
user:name                ; => "Alice"
user.age                 ; => 30
get(user, "city")        ; => "Tokyo"

; 辞書の更新
set(user, "age", 31)

; OS 名前空間(辞書)へのアクセス
net.info                 ; ネットワークインターフェース情報
math.PI                  ; 円周率
math.sqrt(16)            ; => 4

リスト操作

; リストの作成
set(numbers, (10 20 30 40 50))

; インデックスアクセス
numbers(0)               ; => 10
numbers(2)               ; => 30
numbers(10)              ; => nil (範囲外)

; スライス
numbers(1, 3)            ; => (20 30)
numbers(0, 2)            ; => (10 20)

; リスト関数
length(numbers)          ; => 5
car(numbers)             ; => 10 (最初の要素)
cdr(numbers)             ; => (20 30 40 50) (最初以外)
cons(0, numbers)         ; => (0 10 20 30 40 50) (先頭に挿入)

; 関数型操作
map(lambda((x), *(x, 2)), (1 2 3)) ; => (2 4 6)
fold(lambda((acc, x), +(acc, x)), 0, (1 2 3)) ; => 6 (合計)

条件分岐

; if-then-else
set(score, 85)
if(ge(score, 80), print("Good!"), print("Need improvement"))

; condition(複数条件)
condition(
  (lt(score, 60) print("F"))
  (lt(score, 70) print("D"))
  (lt(score, 80) print("C"))
  (lt(score, 90) print("B"))
  (else print("A"))
)

; case(値の一致で分岐)
set(fruit, "apple")
case(fruit
  ("apple" print("Red fruit"))
  ("banana" print("Yellow fruit"))
  ("grape" print("Purple fruit"))
  (else print("Unknown fruit"))
)

ループ

; while ループ
set(i, 0)
while(lt(i, 5),
  print(i),
  set(i, +(i, 1))
)

; for ループ
for(x, (1 2 3 4 5),
  print(*(x, 2))
)

ファイル操作

; ファイル保存
fs.save("note.txt", "Hello, AtmOS!", "personal,notes")

; ファイル読み込みと表示
fs.cat("note.txt")       ; => "Hello, AtmOS!"

; ラベル付きファイル検索
fs.find("notes")         ; "personal,notes" ラベルを持つファイルを検索

; ディレクトリ操作
fs.ls()                  ; カレントディレクトリのファイル一覧
fs.pwd()                 ; カレントディレクトリを表示
fs.mkdir("newfolder")    ; ディレクトリ作成
fs.cd("/user/")          ; ディレクトリ移動

ネットワーク

; ネットワーク情報
net.info                 ; ネットワークインターフェース情報

; ICMP Ping
net.ping("8.8.8.8")      ; Google DNS への疎通確認
net.ping("google.com")   ; ホスト名指定での疎通確認(自動DNS解決)

; DNS 解決
net.dns("example.com")   ; => IP アドレス

; DHCP
net.dhcp("show")         ; DHCP 設定状態を表示
net.dhcp("start")        ; DHCP クライアントを起動

; UDP 送受信(バイナリデータ対応)
net.udp("send", "192.168.1.100", 5000, "Hello UDP")
net.udp("send", "192.168.1.100", 5000, (1 81 0 0))  ; バイナリ(リスト形式)
net.udp("recv", 5000)    ; ポート 5000 でデータ受信待機

; HTTP/HTTPS
net.https("get", "example.com", "/")  ; HTTPS GET リクエスト

文字列操作

; 文字列テンプレート
set(name, "Alice")
set(greeting, `Hello, ${name}!`)  ; => "Hello, Alice!"

; テンプレート書式指定
set(value, 255)
set(hex, `Value: ${value:#010x}`) ; => "Value: 0x000000ff"

set(pi, 3.14159)
set(pi_str, `π ≈ ${pi:.3f}`)       ; => "π ≈ 3.142"

; 文字列関数
str.length("hello")      ; => 5
str.split("a,b,c", ",")  ; => ("a" "b" "c")
str.join(("a" "b" "c"), "-")  ; => "a-b-c"
str.replace("hello", "l", "L")  ; => "heLLo"
str.substring("hello", 1, 3)    ; => "el"

グラフィック描画

; 画面クリア(黒色)
draw.clear_screen(0xFF000000)

; 矩形描画(白色の矩形)
draw.boxfill(10, 10, 100, 100, 0xFFFFFFFF)

; テキスト描画(サイズ 24)
draw.draw_string(10, 10, "AtmOS", 0xFFFFFFFF, 24)

セキュリティ機能

; テンプレート展開前ガード(SQLインジェクション対策)
os.set_template_guard(
  lambda((tmpl, vals),
    not(str.replace(tmpl, "UNION", ""))  ; UNION キーワードを禁止
  )
)

; テンプレート展開後ガード(XSS 対策)
os.set_template_post_guard(
  lambda((result),
    str.replace(result, "<script>", "&lt;script&gt;")  ; スクリプトタグをエスケープ
  )
)

並行処理

; タスクを非同期実行
task.parallel(lambda(() print("Running in parallel")))

; 複数タスクを並行実行して完了を待つ
task.fork_join((
  lambda(() +(1, 2))
  lambda(() *(3, 4))
  lambda(() /(10, 2))
))  ; => (3 12 5)

; スレッド間通信(キュー)
set(q, task.queue())
task.parallel(lambda(() 
  task.send(q, "Hello from thread")
))
set(msg, task.recv(q))  ; => "Hello from thread"

付録: 構文・リテラル詳細仕様

文字列リテラル

整数リテラル

進数 プレフィックス
10進数 なし 42, -7
2進数 0b 0b101 (5)
8進数 0o 0o755 (493)
16進数 0x 0xFA (250)

プレフィックスは必ず小文字(0B/0O/0X は不可)。

テンプレートリテラル

バッククォートで囲み ${式:書式} を埋め込む。$$$ をエスケープ。

書式指定: [#][0][width][,][.precision][fmt_type]

記号 出力
b/x/X Num 2/16進数(# でプレフィックス付与)
f/e/E Ratio 固定小数点/指数表記

シンボル(識別子)切り出しルール

区切り文字(空白・( ) { } : , " ' `)まで連続して収集。

Parser による糖衣構文展開: - obj:key / obj.key(get obj "key") - func(a, b)(func a b) の AST に変換

コメント構文

記法 種類 整形規則
# 1行 上の行のインデントを継承
## 1行 行頭に強制配置
#\| ... \|# ブロック インデント継承
##\| ... \|## ブロック 行頭強制