このページは malbolge20_creator
リポジトリの compiler/highlevel(C風高級言語 .c から
制御付き疑似命令列 .mg へのコンパイラ)のソース
(parser.yy / scanner.ll / define.h)を一次情報として記述している.
| program | ::= | decl* |
| decl | ::= | var_decl | func_decl | proto_decl |
| proto_decl | ::= | type_decl func_name ( dummy_arg_list? ) ; |
| func_decl | ::= | type_decl func_name ( dummy_arg_list? ) { var_decl* statement* } |
| dummy_arg_list | ::= | type id ( , type id )* |
| var_decl | ::= | type_decl var_init ( , var_init )* ; |
| var_init | ::= | id | id = num | id = + num | id = - num | id = true | id = false | id [ num ] (配列宣言) |
| type_decl | ::= | type | static type |
| type | ::= | int | bool |
| block | ::= | { statement* } | statement |
| statement | ::= | expression ; | ; | if_statement | while_statement | return_statement |
| if_statement | ::= | if ( expression ) block ( else block )? |
| while_statement | ::= | while ( expression ) block |
| return_statement | ::= | return expression ; |
| expression | ::= |
id |
id [ expression ] |
( expression ) |
num | true | false | ++id | id++ | --id | id-- | ++id[expression] | id[expression]++ | --id[expression] | id[expression]-- | id = expression | id += expression | id -= expression | id[expression] = expression | expression + expression | expression - expression | + expression | - expression | expression && expression | expression || expression | ! expression | expression == expression | expression != expression | expression < expression | expression <= expression | expression > expression | expression >= expression | func_name ( expression_list? ) |
| expression_list | ::= | expression ( , expression )* |
※演算子の優先順位は,代入系(= += -=,右結合)が最も低く,
以下 ||,&&,比較演算子(== !=,左結合),
順序比較演算子(< <= > >=,左結合),
+ -(左結合),単項の ++ -- !(右結合),単項の + -(右結合)の順に高くなる.
単項の + - は int の任意の式に付けられ(-a,3 - -a,- -a など),定数に付けた場合(-5 など)はコンパイル時に畳み込まれる.
宣言時の初期化 var_init の右辺は数値リテラル(符号付き可)と true/false に限られ,式は書けない.
※num は10進の非負整数リテラル,または 'c' 形式の文字リテラル
(1バイト目の文字コードに置き換わる).id/func_name
は英字から始まり英数字とアンダースコアが続く任意の文字列.
hello.c — putchar による文字出力のみ
while.c — グローバル変数・while・比較・前置インクリメント
array.c — グローバル配列宣言・配列アクセス
int bool true false
if else static return while).
flex -i でビルドされているため.//(行末まで)と /* ... */ の2種類.upper_ident).組み込み関数
putchar / getchar も大文字小文字を区別せず呼び出せる.int は20tritの符号付き整数.負の数のリテラル -num は
320 の補数(3486784401 - num)として扱われる.bool は true/false の2値のみを取る.
bool の変数・式を算術演算子(+ - 等)に使うことはできない
(int と bool は型検査で区別される).static 修飾可)に分かれる.static ローカル変数は呼び出し間で値を保持する.type id[num]; の形でのみ宣言できる(static な配列は不可).
要素は2ワード間隔でメモリに配置され,id[n] の絶対アドレスは
「配列先頭アドレス + n * 2」で計算される.type name(引数…);)が使える.STACK_TOP を先頭とする専用のメモリ領域)を介して
受け渡される.main という名前の関数を明示的に呼び出すことはできない.putchar(n)/getchar() は組み込み関数で,通常の関数呼び出しとは別扱い
(ユーザ定義関数として再定義できない).
このコンパイラが生成する 制御付き疑似命令列(.mg)の
ROT/OPR 命令は,変数1つ1つに対する
低級アセンブリ言語のtrit演算に展開される.
そのため C風高級言語の算術・論理・比較演算はすべて,20桁のtrit列に対する繰り返し演算(多くは20回の
REPEAT)として実現されている.例えば比較演算子は,2つの値を最上位tritから1桁ずつ比較しながら
真偽を確定させる形で実装されている.C言語の意味論としては通常の符号付き整数比較と変わらない.