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}