// File: /workspace/github_c_makefile_star2_O0/adamjedlicka[P]blu/src/vm/compiler/compiler.c
// Function: classDeclaration
static void classDeclaration(bluCompiler* compiler) {
	uint16_t name = parseVariable(compiler, "Expect class name.");
	bluToken className = compiler->parser->previous;

	emitByte(compiler, OP_CLASS);
	emitShort(compiler, name);
	defineVariable(compiler, name);

	bluClassCompiler classCompiler;
	classCompiler.name = className;
	classCompiler.hasSuperclass = false;
	classCompiler.enclosing = compiler->classCompiler;

	compiler->classCompiler = &classCompiler;

	if (match(compiler, TOKEN_LESS)) {
		consume(compiler, TOKEN_IDENTIFIER, "Expect superclass name.");

		if (identifiersEqual(&className, &compiler->parser->previous)) {
			error(compiler, "A class cannot inherit from itself.");
		}

		classCompiler.hasSuperclass = true;

		beginScope(compiler);

		// Store the superclass in a local variable named "super".
		variable(compiler, false);
		addLocal(compiler, syntheticToken(compiler, "^"));
		defineVariable(compiler, 0);

		namedVariable(compiler, className, false);
		emitByte(compiler, OP_INHERIT);
	} else if (strncmp("Object", compiler->parser->previous.start, 6) != 0) {
		classCompiler.hasSuperclass = true;

		beginScope(compiler);

		namedVariable(compiler, syntheticToken(compiler, "Object"), false);
		addLocal(compiler, syntheticToken(compiler, "^"));
		defineVariable(compiler, 0);

		namedVariable(compiler, className, false);
		emitByte(compiler, OP_INHERIT);
	}

	consume(compiler, TOKEN_LEFT_BRACE, "Expect '{' before class body.");

	while (!check(compiler, TOKEN_RIGHT_BRACE) && !check(compiler, TOKEN_EOF)) {
		if (match(compiler, TOKEN_FN)) {
			namedVariable(compiler, className, false);
			method(compiler);
		} else if (match(compiler, TOKEN_STATIC) && match(compiler, TOKEN_FN)) {
			namedVariable(compiler, className, false);
			staticMethod(compiler);
		} else {
			errorAtCurrent(compiler, "Expect method declaration.");
		}
	}

	consume(compiler, TOKEN_RIGHT_BRACE, "Expect '}' after class body.");

	if (classCompiler.hasSuperclass) {
		endScope(compiler);
	}

	compiler->classCompiler = classCompiler.enclosing;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
leaq 0xa40a(%rip), %rsi      # 0xe4d4
callq 0x39b0
movw %ax, -0xa(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rcx
movq %rcx, -0x30(%rbp)
movq 0x28(%rax), %rcx
movq %rcx, -0x28(%rbp)
movq 0x30(%rax), %rcx
movq %rcx, -0x20(%rbp)
movq 0x38(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movl $0x29, %esi
callq 0x32b0
movq -0x8(%rbp), %rdi
movzwl -0xa(%rbp), %esi
callq 0x3140
movq -0x8(%rbp), %rdi
movzwl -0xa(%rbp), %esi
callq 0x3a20
movq -0x30(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movb $0x0, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rax
leaq -0x60(%rbp), %rcx
movq %rcx, 0x18(%rax)
movq -0x8(%rbp), %rdi
movl $0x13, %esi
callq 0x2c40
testb $0x1, %al
jne 0x4176
jmp 0x426e
movq -0x8(%rbp), %rdi
movl $0x19, %esi
leaq 0xa361(%rip), %rdx      # 0xe4e7
callq 0x3200
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rsi
addq $0x20, %rsi
leaq -0x30(%rbp), %rdi
callq 0x34a0
testb $0x1, %al
jne 0x41a6
jmp 0x41b6
movq -0x8(%rbp), %rdi
leaq 0xa34e(%rip), %rsi      # 0xe4ff
callq 0x2db0
movb $0x1, -0x38(%rbp)
movq -0x8(%rbp), %rdi
callq 0x3ad0
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x25e0
movq -0x8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x8(%rbp), %rsi
leaq -0x80(%rbp), %rdi
leaq 0xa203(%rip), %rdx      # 0xe3eb
callq 0x2fc0
movq -0xc8(%rbp), %rdi
leaq -0x80(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x3d00
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x3a20
movq -0x8(%rbp), %rdi
leaq -0x30(%rbp), %rax
xorl %esi, %esi
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x2ee0
movq -0x8(%rbp), %rdi
movl $0x2a, %esi
callq 0x32b0
jmp 0x439d
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x28(%rax), %rsi
leaq 0xa2a2(%rip), %rdi      # 0xe523
movl $0x6, %edx
callq 0x1050
cmpl $0x0, %eax
je 0x439b
movb $0x1, -0x38(%rbp)
movq -0x8(%rbp), %rdi
callq 0x3ad0
movq -0x8(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x8(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
leaq 0xa265(%rip), %rdx      # 0xe523
callq 0x2fc0
movq -0xd8(%rbp), %rdi
leaq -0xa0(%rbp), %rax
xorl %esi, %esi
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x2ee0
movq -0x8(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0x8(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
leaq 0xa0d4(%rip), %rdx      # 0xe3eb
callq 0x2fc0
movq -0xd0(%rbp), %rdi
leaq -0xc0(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x3d00
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x3a20
movq -0x8(%rbp), %rdi
leaq -0x30(%rbp), %rax
xorl %esi, %esi
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x2ee0
movq -0x8(%rbp), %rdi
movl $0x2a, %esi
callq 0x32b0
jmp 0x439d
movq -0x8(%rbp), %rdi
movl $0x5, %esi
leaq 0xa17d(%rip), %rdx      # 0xe52a
callq 0x3200
movq -0x8(%rbp), %rdi
movl $0x8, %esi
callq 0x2bf0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xd9(%rbp)
jne 0x43e5
movq -0x8(%rbp), %rdi
movl $0x2f, %esi
callq 0x2bf0
xorb $-0x1, %al
movb %al, -0xd9(%rbp)
movb -0xd9(%rbp), %al
testb $0x1, %al
jne 0x43f4
jmp 0x44bf
movq -0x8(%rbp), %rdi
movl $0x23, %esi
callq 0x2c40
testb $0x1, %al
jne 0x4408
jmp 0x4444
movq -0x8(%rbp), %rdi
leaq -0x30(%rbp), %rax
xorl %esi, %esi
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x2ee0
movq -0x8(%rbp), %rdi
callq 0x46d0
jmp 0x44ba
movq -0x8(%rbp), %rdi
movl $0x2b, %esi
callq 0x2c40
testb $0x1, %al
jne 0x4458
jmp 0x44a8
movq -0x8(%rbp), %rdi
movl $0x23, %esi
callq 0x2c40
testb $0x1, %al
jne 0x446c
jmp 0x44a8
movq -0x8(%rbp), %rdi
leaq -0x30(%rbp), %rax
xorl %esi, %esi
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x2ee0
movq -0x8(%rbp), %rdi
callq 0x4780
jmp 0x44b8
movq -0x8(%rbp), %rdi
leaq 0xa095(%rip), %rsi      # 0xe548
callq 0x3df0
jmp 0x44ba
jmp 0x43b2
movq -0x8(%rbp), %rdi
movl $0x8, %esi
leaq 0xa094(%rip), %rdx      # 0xe563
callq 0x3200
testb $0x1, -0x38(%rbp)
je 0x44e3
movq -0x8(%rbp), %rdi
callq 0x3b60
movq -0x60(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x18(%rax)
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopl (%rax,%rax)