0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BE-Lang を C で構築する試み

0
Last updated at Posted at 2026-03-14

導入

 みなさん! お久しぶりです! 開発で記事が書けていませんでした... 本当に突然なんですが、 BE-Lang の様子が最近おかしいんですね...(?) 記事のタグを見ればわかると思いますが、 BE-Lang の処理系を Ruby から C に移行しました。1 なんで C 移行したかと言うと、

  • めちゃくちゃ高速だから。 (コンパイラ型言語だから)
  • Yacc (Yet-Another-Compiler-Compiler) や、 Flex などの強力なライブラリがあるから。
  • CRubyC 実装だから 2
  • 自分のキャリアを積むため。 3

 とまぁ、いろいろ理由はありますが... 結局の理由は、

CRubyC 実装だから

ですね。

BE-Lang の仕様をお披露目しまーす!

 やっぱり言語は速度とか、性能が人気の秘訣じゃなくて、やっぱり 文法 とか、標準ライブラリが充実しているかどうか。とかですね。だから、今回は、抽象構文木をそのままトラバースして歩き渡る処理系にします! 4 さて、次に文法ですね。文法で勝負するしかありません! Hello, World! はこんな感じ!

HelloWorld.be
puts("Hello, World!"); /* 文末にセミコロンを付けます。 */
/* ちなみに Ruby みたいに文字列連結もできます。 */
puts("Hello," + " " + "World!");

結構いいと思いますよ! ただ、不満はたった一つあって、 ; を文末につけるというものですね。 設計段階で \n (改行) で Ruby みたいに区切ろうと思ってたんですが、 Yacc とかがコンフリクトエラーを 110個ぐらい吐かれたので仕方なくそうしています。 5 これだといまいちわからないと思うので yacc 記述をここに書いておきますね。

puts_stmt: PUTS '(' exp ')'
/* PUTS はキーワードで puts にヒットします。 exp は先程の "Hello, World" とか、 "Hello," + " " + "World!" みたいなのを指します。 */
/* 1 + 1 も exp です。 */

ここで、首をかしげている人もいるかもしれません。多分その疑問は...

C でどのように AST (=抽象構文木) を?

 いい質問ですね! 前の Ruby 実装の BE-Lang はトークンの塊をチェックしていましたが、 C 実装の BE-Lang はどのようにするかと言いますと、

example.h
#ifndef COMMON_H
#define COMMON_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum { TYPE_INT, TYPE_STR, TYPE_BOOL } ValueType;
typedef struct {
    ValueType type;
    union {
        double i_val;
        char* s_val;
        bool b_val;
    } as;
} Value;
typedef struct Node {
    int type; 
    // note: if (exp) then { program }
    // (exp) -> left, { program } -> right
    struct Node *left, *right;
    struct Node *else_node;
    Value val;
} Node;
// ... 以下略
#endif

2026/3/15 追記。
if の再起呼び出しを使って else if が可能になりました。 While を実装しました。 FizzBuzzゲームはこんな感じで書けます。 あと、 ; つけなくても良くなりました...

FizzBuzz.be
n = 0
while (n < 30) then {
  if (n % 15 == 0) then     { puts("Fizz Buzz") }
  else if (n % 5 == 0) then { puts("Buzz") }
  else if (n % 3 == 0) then { puts("Fizz") }
  else                      { puts(n) }
  n += 1
}

こういういわゆる、構造体と言われるもので実装するんですね。 まだ未公開なので抜粋なのですが、こういう手順を踏んで AST を生成して実行します。

  1. 実行時にファイル名を指定。
  2. yacc のアクションでノードを生成。 (これが AST 生成)
  3. インタプリタループで個の構造体の int type を参照。タイプに応じて処理を行う。

 ね。簡単でしょ?6 こんな簡単な手順を踏んだら誰でもプログラミング言語をつくれます。ぜひみなさんもやってみてください!

終わりに

 まさか、 Ruby から C になるとは思っていませんよね..? 驚いたと思います。これからもいい感じに進化させていこうかなと思っています。それではまた次の記事で。さようなら!

  1. なんだろう...上位互換みたいに語ってますが今のところは puts , if , 数式 しか書けない電卓なんですが... (あと else )

  2. GithubCRuby のリポジトリを見てみたところ、 C より Ruby の方が、記述量が多いらしいです。(2026/3/14 時点) 自分の靴紐ひっぱって飛んだのかな? 物理的にできるのか?... よし! 私も靴紐頑張って引っ張るぞー!

  3. どうやら、高校生とか大学生になると C を触るらしいです。外国も C なんだろうか?

  4. 言い訳にしか聞こえないのは私だけ?

  5. 言い訳 再来。 \n でも行けるようにしろって。

  6. ね。既視感しかないでしょ?

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?