以下のような関数処理もコンパイルできるようにする
sum(m, n) {
acc = 0;
for (i = m; i <= n; i = i + 1)
acc = acc + i;
return acc;
}
main() {
return sum(1, 10);
}
Cではローカル変数はスタックに置くことにしている、グローバル変数はメモリに置く
関数ごとに呼び出されるメモリ領域を「関数フレーム」「アクティベーションレコード」という
レジスタで関数フレームを常に指しているレジスタをベースレジスタ、値をベースポインタと呼ぶ
ベースレジスタはRBPレジスタを使用する
push rbp
mov rbp, rsp
sub rsp, 16
アルファベットの小文字ならばident
// token type 構造体
typedef enum {
TK_RESERVED, // op
TK_INDENT,
TK_NUM,
TK_EOF, // end of input
} TokenKind;
program = stmt*
stmt = expr “;”
expr = assign
assign = equality (“=” assign)?
equality = relational (“==” relational | “!=” relational)*
relational = add(“<" add | "<=" add | ">” add | “>=” add)*
add = mul (“+” mul | “-” mul)*
mul = unary (“*” unary | “/” unary)*
unary = (“+” | “-“)? primary
primary = num | “(” expr “)”
Node *assign(){
Node *node = equality();
if (consume("="))
node = new_node(ND_ASSIGN, node, assign());
return node;
}
Node *expr() {
return assign();
}
Node *stmt() {
Node *node = expr();
expect(";");
return node;
}
void program() {
int i = 0;
while (!at_eof())
code[i++] = stmt();
code[i] = NULL;
}