emela コマンド
emela は検査、ビルド、実行、テスト、整形、文書の生成、言語サーバーを1つにまとめたコマンドです。どのサブコマンドもプロジェクトのディレクトリか単独のファイルを受け取り、省けば . を対象にします。
$ emela --helpCompile, run, test, and format Emela programs
Usage: emela <COMMAND>
Commands: check Report diagnostics without compiling build Compile to JavaScript under `target/emela/js` (or to a native executable with `--target c`) run Compile and run: on Node.js, or as a native executable with `--target c` test Run the functions marked `@test` fmt Format the sources in place doc Generate API documentation under `target/emela/doc` lsp Start the language server over standard input and output help Print this message or the help of the given subcommand(s)| コマンド | 働き |
|---|---|
emela check [PATH] | 診断だけを出す。コンパイルしない |
emela build [PATH] | コンパイルして出力先に書き出す |
emela run [PATH] [-- ARGS...] | コンパイルして実行する |
emela test [PATH] [FILTER] | @test の関数を実行する |
emela fmt [PATHS...] | ソースを整形して書き換える |
emela doc [PATH] | API の文書を生成する |
emela lsp | 言語サーバーとして動く |
PATH にはプロジェクトのディレクトリか、エントリのファイルを渡します。
ディレクトリを渡すと、祖先をたどって最初に見つかった Pome.toml のプロジェクト全体が対象になり、エントリは src/main.emel です。渡せるのはプロジェクトのディレクトリか src/ の中のディレクトリで、src/ の外(scripts/ など)はエラーになります。src/ の中のディレクトリを渡しても、型の検査はモジュールをまたぐのでプロジェクト全体を検査します。Pome.toml が見つからないディレクトリもエラーです。
ファイルを渡して Pome.toml が見つからなければ、単独のファイルとして扱います。同じディレクトリの直下の .emel だけがモジュールになり、エントリから import でたどれるファイルだけを読みます。ファイル名は小文字の snake_case で、モジュール名に変換できる形でなければなりません(p.emel のように変換後の名前が型名にならないものはエラーです)。
プロジェクトの決まりは プロジェクトと Pome にあります。
$ emela check scriptserror[E0208]: directory `scripts` is outside the source root `src` = note: source files of a project (the directory with Pome.toml) go under src/; pass the project directory, or a file or directory under src/
1 erroremela check
Section titled “emela check”Usage: emela check [PATH]- 型を検査して診断を出します。何も書き出しません。
- 診断は標準エラーに出します。形は エディタと言語サーバー にあります。
- 今の
checkは--targetを取らず、Pome.tomlの[build].targetも見ません。ターゲットに関わる診断(そのターゲットにない操作、知らないターゲット名など)はbuildで出ます。
emela build
Section titled “emela build”Usage: emela build [OPTIONS] [PATH]
Options: --out-dir <OUT_DIR> Output directory [default: <project>/target/emela/<target>] --target <TARGET> The target [default: `[build].target` of Pome.toml, or js]- 出力先はプロジェクトなら
<プロジェクト>/target/emela/<ターゲット>、単独のファイルならファイルのあるディレクトリのtarget/emela/<ターゲット>です。--out-dirで変えられます。 jsでは、エントリを写したmain.mjsとランタイム(emela_runtime.mjs)を書き出します。同梱の std のホストのファイルはemela_core/の下に置きます。cでは、main.cと C のランタイム(emela_runtime.c、emela.hなど)を書き出し、cc でコンパイルした実行ファイルmainを置きます。
$ emela build --target c main.emel$ ls target/emela/cemela.h emela_core emela_runtime.c emela_runtime.h main main.c—target
Section titled “—target”| 値 | 内容 |
|---|---|
js | Node.js で動く JavaScript |
c | cc でコンパイルする C。native の実行ファイルになる |
- 省けば
Pome.tomlの[build].target、それもなければjsです。--targetが優先します。 - JS は Node 18 以降、Deno、Bun のようなサーバーのホストを前提にします。ブラウザは 0.20 の対象外です。
- C は Tier 2 で、対象は macOS(arm64)と Linux(x86_64)、C11 のコンパイラを前提にします。
emela run
Section titled “emela run”Usage: emela run [OPTIONS] [PATH] [-- <ARGS>...]
Options: --out-dir <OUT_DIR> Output directory [default: <project>/target/emela/<target>] --target <TARGET> The target [default: `[build].target` of Pome.toml, or js]buildと同じ出力先に書き出してから実行します。前の出力は消さずに上書きします。- 診断はプログラムを起動する前に出します。エラーがあれば起動しません。
- プログラムへの引数は
--の後に書きます(emela run -- a b)。0.20 の std には、引数を読む API はまだありません。 mainが返した値は表示しません。- エントリに
mainがなければエラーです。
$ emela run main.emelerror: Oops(code: 3)$ echo $?1emela test
Section titled “emela test”Usage: emela test [OPTIONS] [PATH] [FILTER]
Options: --out-dir <OUT_DIR> Output directory [default: <project>/target/emela/test, or test-c for `--target c`] --target <TARGET> The target [default: `[build].target` of Pome.toml, or js]@testを付けた関数を1つずつ実行します。- テストの名前は、エントリのモジュールのものは関数名だけ、ほかのモジュールのものはモジュール名を前に付けます(
Greeting.says_hello)。 FILTERを渡すと、名前に部分一致する(大文字小文字を区別する)テストだけを実行します。単独のファイルでは、エントリから import でたどれるモジュールのテストだけが対象です。- 出力は
target/emela/test(C はtarget/emela/test-c)に書き、通常のビルドの出力を上書きしません。 - 1つでも失敗すれば終了コード 1、なければ 0 です(テストが0個でも 0)。
- テストだけのファイルに
mainは要りません。
$ emela test . saysrunning 1 testtest Greeting.says_hello ... ok
test result: ok. 1 passed; 0 failed; 1 filtered outテストの書き方は テスト にあります。
emela fmt
Section titled “emela fmt”Usage: emela fmt [OPTIONS] [PATHS]...
Arguments: [PATHS]... Files or directories to format [default: `src` of the project at `.`]. `-` reads standard input and writes standard output
Options: --check Do not write; list the files that need formatting on standard output and exit with 1 if any- 渡したファイルとディレクトリの
.emelを整形して書き換えます。省けば.のプロジェクトのsrcです。 - ディレクトリには
Pome.tomlが要ります。プロジェクトのディレクトリならソースのルートの下全部、ソースのルートの中ならその下全部が対象で、ソースのルートの外はエラーです。 .で始まるものは飛ばします。名前がモジュール名にならないファイルも整形します。- 構文エラーのファイルは書き換えず、診断を出してほかのファイルを続けます。
--checkは書き換えず、整形が要るファイルを標準出力に1行ずつ出します。CI で使えます。-は標準入力を整形して標準出力に書きます。エディタから呼ぶときに使います。- 終了コードは、診断にエラーがあるか、
--checkで整形が要るファイルがあれば 1、引数の誤りは 2 です。
$ emela fmt --checksrc/main.emel$ printf 'fn main( ) {\n dbg( 1+2 )\n}\n' | emela fmt -fn main() { dbg(1 + 2)}emela doc
Section titled “emela doc”Usage: emela doc [OPTIONS] [PATH]
Options: --std Document the bundled core and std instead of the project --format <FORMAT> Output format [default: html] [possible values: html, md] --out-dir <OUT_DIR> Output directory [default: <project>/target/emela/doc]pubの宣言と、その##の文書コメントから API の文書を作ります。--format html(既定)はモジュールの一覧のサイドバー、色付けしたシグネチャ、型の間のリンクを持つページを書きます。--format mdはindex.mdとモジュールごとの Markdown を書きます。--stdは、プロジェクトの代わりに同梱の core と std の文書を作ります。
$ emela doc --std --format md --out-dir std-docs$ ls std-docsFloat.md index.md Int.md Int64.md List.md Option.md Prelude.md Std.Cause.md ...emela lsp
Section titled “emela lsp”Usage: emela lsp引数を取らず、標準入出力で言語サーバーとして動きます。機能とエディタの設定は エディタと言語サーバー にあります。
| 変数 | 働き |
|---|---|
EMELA_NODE | run と test が使う node。なければ PATH の node。見つからなければエラー |
EMELA_CC | --target c が使う C コンパイラ。なければ PATH の cc。起動できないときと、コンパイルに失敗したときはエラー |
NO_COLOR | 空でない値を入れると、診断に色を付けない。色は、標準エラーが端末で NO_COLOR が空か未設定のときだけ付く |
$ EMELA_NODE=/nonexistent/node emela run main.emelerror[E0904]: `/nonexistent/node` not found = note: install Node.js and add it to PATH, or set EMELA_NODE to the node executable
1 errorcheck、build、run、test の終了コードです。
| コード | 意味 |
|---|---|
| 0 | 成功。診断が警告だけのときも 0 |
| 1 | 診断にエラーがある。run では、main まで届いたエラー。test では、失敗したテストがある |
| 101 | run で、プログラムが defect で止まった |
| 130 | run で、中断したまま再開されずにプログラムが終わった |
| 128 + シグナル番号 | シグナルで止まった(SIGTERM なら 143) |
| 2 | コマンドの引数の誤り |
$ emela run defect.emeldefect: boom$ echo $?101エラーと defect の違いは エラー、中断は 中断と再開 にあります。