🙌
ChatGPTを使ってRustで新しいプログラミング言語をつくり始めた話(フォルダ構成の再編と出力先の統一)
目的
- 役割別にクレートを整理して保守性を高める
- 生成物(transpile 結果・実行バイナリ)の置き場所を統一して、開発時の混乱を防止
新フォルダ構成
.
├── examples
│ └── main.pyro # ← 実行デフォルトを hello.pyro から main.pyro に変更
└── pyro
└── crates
├── pyroc # 解析(AST/Parser)
│ ├── Cargo.toml
│ └── src
│ ├── lib.rs
│ └── parser.rs
├── pyroc-bin # CLI エントリ(開発用)
│ ├── Cargo.toml
│ └── src
│ └── main.rs
└── pyrorts # コード生成(Rust)
├── Cargo.toml
└── src
└── lib.rs
- 出力物はpyro/outputに集約
- Transpile 結果: pyro/output/out.rs
- 実行バイナリ: pyro/output/bin/out
使い方(ルートから)
# ビルド
cargo build
# トランスパイル(examples/main.pyro → pyro/output/out.rs)
cargo run -p pyroc-bin -- run
# 実行バイナリ生成&実行(pyro/output/bin/out)
rustc pyro/output/out.rs -o pyro/output/bin/out
./pyro/output/bin/out
前回からのコード差分
- ルートのワークスペース定義(新規)
./Cargo.toml
+ [workspace]
+ members = [
+ "pyro/crates/pyroc",
+ "pyro/crates/pyrorts",
+ "pyro/crates/pyroc-bin",
+ ]
+ resolver = "2"
+
+ # (任意)無指定ビルド対象
+ default-members = ["pyro/crates/pyroc-bin"]
- 実行デフォルトを examples/main.pyro に変更 / 出力先を統一
※ 以前は examples/hello.pyro を既定入力にし、out.rs/out をルート直下に出していた)
./pyro/crates/pyroc-bin/src/main.rs
- use std::{env, fs};
- use std::path::PathBuf;
- use std::process::Command;
+ use std::fs;
+ use std::path::PathBuf;
+ use std::process::Command;
use pyroc::parser::Parser as PyroParser;
use pyrorts::generate;
// …(clap等、既存の引数処理があればそのまま)…
// run サブコマンド(例)
// 入力ファイルの既定を hello.pyro → main.pyro へ
- let src = fs::read_to_string("examples/hello.pyro").expect("failed to read source");
+ let src = fs::read_to_string("examples/main.pyro").expect("failed to read source");
let mut parser = PyroParser::new(&src).expect("lexer failed");
let m = parser.parse_module().expect("parse failed");
let out = generate(&m);
- // 以前: ルート直下に out.rs / out を出力していた
- fs::write("out.rs", out).expect("write out.rs failed");
- let status = Command::new("rustc")
- .arg("out.rs").arg("-o").arg("out")
- .status().expect("failed to run rustc");
- assert!(status.success());
- Command::new("./out").status().expect("failed to run program");
+ // 変更後: 出力先を pyro/output に統一し、実行バイナリは pyro/output/bin/out
+ let out_dir = PathBuf::from("pyro/output");
+ fs::create_dir_all(&out_dir).expect("failed to create output dir");
+ let out_rs = out_dir.join("out.rs");
+ fs::write(&out_rs, out).expect("write out.rs failed");
+ println!("✅ Transpiled to {}", out_rs.display());
+
+ let bin_dir = out_dir.join("bin");
+ fs::create_dir_all(&bin_dir).expect("failed to create bin dir");
+ let out_bin = bin_dir.join("out");
+ let status = Command::new("rustc")
+ .arg(&out_rs).arg("-o").arg(&out_bin)
+ .status().expect("failed to run rustc");
+ assert!(status.success());
+ println!("✅ Compiled binary -> {}", out_bin.display());
+ Command::new(&out_bin).status().expect("failed to run program");
- サンプル名の切り替え(hello → main)
- examples/hello.pyro
+ examples/main.pyro
既存のサンプルが hello.pyro のままなら、ファイル名だけ main.pyro にリネームすればOKです(中身はそのまま利用可能)。
補足(設計意図)
- 出力先を統一することで、リポジトリ直下の散らかりを解消
- 将来 CI/CD で成果物を拾う際も、pyro/output/** を見れば完結
- サンプル入力の既定名を main.pyro に固定し、チュートリアル導線を明確化
まとめ
- ルートに Cargo ワークスペースを置き、pyro/crates/* をメンバー化
- サンプル入力は examples/main.pyro
- 生成物は pyro/output/out.rs と pyro/output/bin/out に統一
ゆくゆくは、Pyro自体をプロジェクトフォルダに置かず、グローバルに導入できる形を目指しています。インストール時にRust環境およびCargo環境も同時に導入し、セットアップ直後からサンプルのビルド・実行まで完了できるワンステップ体験を提供する計画です。
Discussion