関数・ローカル変数とcompiler

以下のような関数処理もコンパイルできるようにする

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;
}