b2c2_compiler_common/
lib.rs

1// b2c2-compiler-common crate
2// author: Leonardone @ NEETSDKASU
3
4use b2c2_casl2 as casl2;
5
6pub const MAX_ALLOCATION_SIZE: usize = 30000;
7pub const MAX_ARRAY_SIZE: usize = 256;
8
9// プログラム名のラベルとしての正当性チェック
10pub fn is_valid_program_name(program_name: &str) -> bool {
11    // 予約済みラベル
12    // EOF    Inputステートメント、EOF()関数で使用
13    // EXIT   Endステートメントで使用
14    // MEM    Allocatorが確保したメモリのアドレスを保持する領域
15    // ALLOC  Allocatorのサブルーチン名
16    // 自動生成のラベルとの重複を避けるチェックが必要
17    // B** 真理値変数
18    // I** 整数変数
19    // T** 式展開時の一時変数(真理値/整数で共有)(主にForループの終点とステップで使用)
20    // V** 組み込みサブルーチンのローカル変数
21    // J** ループや条件分岐に使うジャンプ先ラベルのId
22    // C** 組み込みサブルーチンの入り口のラベル
23    // F** スニペットのサブルーチン
24    // SL** 文字列変数の長さ
25    // SB** 文字列変数の内容位置
26    // BA** 真理値配列
27    // IA** 整数配列
28    // LL** IN/OUTで使用の文字列定数の長さ
29    // LB** IN/OUTで使用の文字列定数の内容位置
30    // TL** 式展開時の一時的な文字列変数の長さ
31    // TB** 式展開時の一時的な文字列変数の内容位置
32    // ARG* プログラム引数
33    casl2::Label::from(program_name).is_valid()
34        && !(matches!(program_name, "EOF" | "EXIT" | "MEM" | "ALLOC")
35            || ((program_name.chars().count() >= 2)
36                && ["B", "I", "T", "V", "J", "C", "F"]
37                    .iter()
38                    .any(|prefix| program_name.starts_with(prefix))
39                && program_name.chars().skip(1).all(|ch| ch.is_ascii_digit()))
40            || ((program_name.chars().count() >= 3)
41                && ["SL", "SB", "BA", "IA", "LL", "LB", "TL", "TB"]
42                    .iter()
43                    .any(|prefix| program_name.starts_with(prefix))
44                && program_name.chars().skip(2).all(|ch| ch.is_ascii_digit()))
45            || ((program_name.chars().count() == 4)
46                && program_name.starts_with("ARG")
47                && program_name.chars().skip(3).all(|ch| ch.is_ascii_digit())))
48}