🙌

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

前回からのコード差分

  1. ルートのワークスペース定義(新規)
./Cargo.toml
+ [workspace]
+ members = [
+   "pyro/crates/pyroc",
+   "pyro/crates/pyrorts",
+   "pyro/crates/pyroc-bin",
+ ]
+ resolver = "2"
+ 
+ # (任意)無指定ビルド対象
+ default-members = ["pyro/crates/pyroc-bin"]
  1. 実行デフォルトを 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");
  1. サンプル名の切り替え(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環境も同時に導入し、セットアップ直後からサンプルのビルド・実行まで完了できるワンステップ体験を提供する計画です。

コラボスタイル Developers

Discussion