sosukesuzuki / minis_rb

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

minis_rb

概要

minis_rb は minis の Ruby 実装です。筑波大学 の ソフトウェアサイエンス特別講義 A の課題として作成されました。

使い方

構文木を JSON で記述したファイルのパスを指定するとそのプログラムを評価し、結果を返します。たとえば以下の内容で program.json を作成します。

[
    {
        "type": "+",
        "left": 3,
        "right": 4
    }
]

このとき、以下のコマンドを実行すると、7 と表示されます。

$ ./bin/minis program.json
7

機能

二項演算子

以下の二項演算子をサポートしています。

  • +
  • -
  • *
  • /
  • <
  • <=
  • >
  • >=
  • ==
  • !=

例:

{
    "type": "+",
    "left": 3,
    "right": 4
}

変数の宣言と代入

変数の宣言と代入をサポートしています。どちらも代入演算子によって行われます。

代入は式であり、代入された値が結果になります。以下の例では、x3を代入し、式全体の結果は3です。

例:

{
    "type": "assign",
    "name": "x",
    "value": 3
}

if 式

if 式をサポートしています。

例:

{
    "type": "if",
    "condition": {
        "type": "==",
        "left": 1,
        "right": 2
    },
    "then": 1,
    "else": 2
}

このJSONをJavaScript風の構文で表すと以下のようになります:

if (1 == 2) {
    1;
} else {
    2;
}

while 式

while 式をサポートしています。while 式は常に nil を返します。

例:

[
    {
        "type": "assign",
        "name": "x",
        "value": 0
    },
    {
        "type": "while",
        "condition": {
            "type": "!=",
            "left": {
                "type": "id",
                "name": "x"
            },
            "right": 10
        },
        "body": {
            "type": "assign",
            "name": "x",
            "value": {
                "type": "+",
                "left": {
                    "type": "id",
                    "name": "x"
                },
                "right": 1
            }
        }
    },
    {
        "type": "id",
        "name": "x"
    }
]

このJSONをJavaScript風の構文で表すと以下のようになります:

let x = 0;
while (x != 10) {
    x++;
}
x;

関数宣言と関数呼び出し

関数の宣言と呼び出しをサポートしています。

例:

[
    {
        "type": "def",
        "name": "f",
        "params": [
            "x"
        ],
        "body": {
            "type": "+",
            "left": {
                "type": "id",
                "name": "x"
            },
            "right": 1
        }
    },
    {
        "type": "call",
        "name": "f",
        "args": [
            2
        ]
    }
]

このJSONをJavaScript風の構文で表すと以下のようになります:

function f(x) {
  return x + 1;
}
f(2);

配列

配列と、インデックスを使った要素へのアクセスをサポートしています。

例:

[
    {
        "type": "assign",
        "name": "x",
        "value": [1, 2, 3, 4]
    },
    {
        "type": "index",
        "array": {
            "type": "id",
            "name": "x"
        },
        "index": 3
    }
]

このJSONをJavaScript風の構文で表すと以下のようになります:

const x = [1, 2, 3, 4];
x[3];

ソースコードとテスト

ファイル名 概要
/lib/minis_rb/minis_ast.rb 内部的なAST表現と、そのビルダー関数。ロジックがほとんど存在しないため、テストはない。
./lib/minis_rb/minis_evaluator.rb ASTを評価して結果を得る関数。https://github.com/sosukesuzuki/minis_rb/blob/main/spec/minis_evaluator_spec.rb でテストしている。
./lib/minis_rb/minis_json_evaluator.rb JSON文字列をパースしてAST表現に変換する。https://github.com/sosukesuzuki/minis_rb/blob/main/spec/minis_json_evaluator_spec.rb でテストしている。

About

License:MIT License


Languages

Language:Ruby 99.6%Language:Shell 0.4%