// File: baziotis[P]minijava-cpp/parse.cpp
// Function: parse_type_declaration()
static TypeDeclaration *parse_type_declaration() {
    TypeDeclaration *cls = new TypeDeclaration;
    cls->loc = loc;
    const char *id = NULL;
    if (!match_token(TOK::CLASS)) {
        syntax_error("Expected `class` to start TypeDeclaration");
        goto Lerror;
    }
    id = token.id;
    if (!expect_token_in_rule(TOK::ID, "class declaration")) {
        skip_tokens(TOK::CLASS, false);
        goto Lerror;
    }
    cls->id = id;
    if (match_token(TOK::EXTENDS)) {
        cls->extends = token.id;
        if (!expect_token_in_rule(TOK::ID, "class extends declaration")) {
            goto Lerror;
        }
    }
    if (!match_token(TOK::LBRACE)) {
        syntax_error("Expected `{` in class declaration with name: ", cls->id);
    }
    // Parse VarDeclarations
    while (starts_local()) {
        parse_local_and_push(&cls->vars);
        expect_token_in_rule(TOK::SEMI, "var declaration");
    }
    while (starts_method(token.kind)) {
        parse_method_and_push(&cls->methods);
    }
    if (!match_token(TOK::RBRACE)) {
        syntax_error("Expected `}` in class declaration with name: ", cls->id);
    }
    return cls;
Lerror:
    cls->make_undefined();
    return cls;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movl $0x48, %edi
callq 0xabf0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x30(%rbp)
callq 0xb430
jmp 0x80b3
movq -0x30(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
leaq 0x1c5da(%rip), %rcx     # 0x246a0
movl (%rcx), %ecx
movl %ecx, (%rax)
movq $0x0, -0x28(%rbp)
movl $0x16, %edi
callq 0x82c0
testb $0x1, %al
jne 0x8110
leaq 0x1314e(%rip), %rdi     # 0x1b235
callq 0x83d0
jmp 0x8236
movq -0x30(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x48, %esi
callq 0x2120
jmp 0x8251
leaq 0x1c591(%rip), %rax     # 0x246a8
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movl $0x8, %edi
leaq 0x13134(%rip), %rsi     # 0x1b25f
xorl %edx, %edx
callq 0x8300
testb $0x1, %al
jne 0x8147
movl $0x16, %edi
xorl %esi, %esi
callq 0x8450
jmp 0x8236
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
movl $0x17, %edi
callq 0x82c0
testb $0x1, %al
jne 0x8163
jmp 0x8194
leaq 0x1c53e(%rip), %rax     # 0x246a8
movq 0x8(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x10(%rax)
movl $0x8, %edi
leaq 0x130ef(%rip), %rsi     # 0x1b271
xorl %edx, %edx
callq 0x8300
testb $0x1, %al
jne 0x8192
jmp 0x8236
jmp 0x8194
movl $0x7, %edi
callq 0x82c0
testb $0x1, %al
jne 0x81b6
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x130da(%rip), %rdi     # 0x1b28b
callq 0xa4b0
jmp 0x81b8
callq 0x8560
testb $0x1, %al
jne 0x81c3
jmp 0x81e5
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0x85d0
movl $0x1e, %edi
leaq 0x12a9e(%rip), %rsi     # 0x1ac7a
xorl %edx, %edx
callq 0x8300
jmp 0x81b8
jmp 0x81e7
leaq 0x1c4ba(%rip), %rax     # 0x246a8
movl (%rax), %edi
callq 0xa4f0
testb $0x1, %al
jne 0x81fb
jmp 0x820a
movq -0x10(%rbp), %rdi
addq $0x30, %rdi
callq 0xa510
jmp 0x81e7
movl $0x1a, %edi
callq 0x82c0
testb $0x1, %al
jne 0x822c
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x13092(%rip), %rdi     # 0x1b2b9
callq 0xa4b0
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x8247
movq -0x10(%rbp), %rdi
callq 0xb470
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x30, %rsp
popq %rbp
retq
movq -0x18(%rbp), %rdi
callq 0x21c0
nopw (%rax,%rax)