// File: /workspace/github_c_makefile_star2_O0/martincameron[P]towntalk/towntalk.c
// Function: parse_thiscall_expression
static struct element* parse_thiscall_expression( struct element *elem,
	struct function *func, struct variables *vars, struct expression *prev, char *message ) {
	char *field;
	int idx, count;
	struct variable *var;
	struct structure *struc = NULL;
	struct element *next = elem->next;
	struct global_variable *global = NULL;
	struct string *decl = find_decl( func, &elem->str.string[ 1 ], 0, "!." );
	struct local_variable *captured = NULL, *local = get_local_variable( func->variable_decls, &elem->str.string[ 1 ], "." );
	struct expression param = { 0 }, *this, *expr = calloc( 1, sizeof( struct value_expression ) );
	if( expr ) {
		prev->next = expr;
		expr->line = elem->line;
		if( local ) {
			struc = local->type;
		} else {
			if( vars ) {
				captured = get_local_variable( vars->func->variable_decls, &elem->str.string[ 1 ], "." );
			}
			if( captured ) {
				struc = captured->type;
			} else if( decl ) {
				if( decl->type == GLOBAL ) {
					global = ( struct global_variable * ) decl;
					struc = global->type;
				} else if( decl->type == STRUCT ) {
					struc = ( struct structure * ) decl;
				}
			}
		}
		field = field_end( elem->str.string, "!." );
		if( struc && field[ 0 ] ) {
			( ( struct value_expression * ) expr )->str = &struc->str;
			idx = get_string_list_index( struc->fields, &field[ 1 ] );
			if( idx >= 0 ) {
				if( next && next->str.string[ 0 ] == '(' ) {
					parse_expressions( next->child, func, vars, 0, &param, &count, message );
					expr->parameters = param.next;
					if( local || captured || global ) {
						this = calloc( 1, sizeof( struct value_expression ) );
						if( this ) {
							if( local ) {
								this->index = local->index;
								this->evaluate = evaluate_local;
							} else if( captured ) {
								var = &vars->locals[ captured->index ];
								this->index = ( long_int ) var->number_value;
								( ( struct value_expression * ) this )->num = var->number_value;
								if( var->string_value ) {
									var->string_value->reference_count++;
									( ( struct value_expression * ) this )->str = var->string_value;
									this->evaluate = evaluate_string_literal_expression;
								} else {
									this->evaluate = evaluate_number_literal_expression;
								}
							} else {
								( ( struct value_expression * ) this )->str = &global->str;
								this->evaluate = evaluate_global;
							}
							this->next = expr->parameters;
							expr->parameters = this;
							count++;
						} else {
							strcpy( message, OUT_OF_MEMORY );
						}
					}
					if( message[ 0 ] == 0 ) {
						if( count > 0 && count < 256 ) {
							expr->index = ( ( idx & 0x7FFFFF ) << 8 ) | count;
							expr->evaluate = evaluate_thiscall_expression;
							next = next->next;
						} else {
							sprintf( message, "Expected expression after '(' on line %d.", next->line );
						}
					}
				} else {
					sprintf( message, "Expected '(' after '%.64s' on line %d.", elem->str.string, elem->line );
				}
			} else {
				sprintf( message, "Field '%.64s' not declared on line %d.", &elem->str.string[ 1 ], elem->line );
			}
		} else {
			sprintf( message, "Undeclared variable, structure or field '%.64s' on line %d.", elem->str.string, elem->line );
		}
	} else {
		strcpy( message, OUT_OF_MEMORY );
	}
	return next;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movq -0x10(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rsi
addq $0x1, %rsi
xorl %edx, %edx
leaq 0x14b64(%rip), %rcx     # 0x1bbc8
callq 0x7b80
movq %rax, -0x60(%rbp)
movq $0x0, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rsi
addq $0x1, %rsi
leaq 0x14b39(%rip), %rdx     # 0x1bbc9
callq 0x74c0
movq %rax, -0x70(%rbp)
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x30f0
movl $0x1, %edi
movl $0x30, %esi
callq 0x3120
movq %rax, -0xa0(%rbp)
cmpq $0x0, -0xa0(%rbp)
je 0x749c
movq -0xa0(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x8(%rbp), %rax
movl 0x28(%rax), %ecx
movq -0xa0(%rbp), %rax
movl %ecx, (%rax)
cmpq $0x0, -0x70(%rbp)
je 0x7107
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x7192
cmpq $0x0, -0x18(%rbp)
je 0x7136
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x48(%rax), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rsi
addq $0x1, %rsi
leaq 0x14a9c(%rip), %rdx     # 0x1bbc9
callq 0x74c0
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x68(%rbp)
je 0x714b
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x7190
cmpq $0x0, -0x60(%rbp)
je 0x718e
movq -0x60(%rbp), %rax
movsbl 0x14(%rax), %eax
cmpl $0x4, %eax
jne 0x7175
movq -0x60(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x718c
movq -0x60(%rbp), %rax
movsbl 0x14(%rax), %eax
cmpl $0x3, %eax
jne 0x718a
movq -0x60(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x718c
jmp 0x718e
jmp 0x7190
jmp 0x7192
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x14a27(%rip), %rsi     # 0x1bbc8
callq 0xaf10
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x7479
movq -0x30(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
je 0x7479
movq -0x48(%rbp), %rcx
movq -0xa0(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x30(%rbp), %rsi
addq $0x1, %rsi
callq 0xafd0
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jl 0x7452
cmpq $0x0, -0x50(%rbp)
je 0x742f
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
movsbl (%rax), %eax
cmpl $0x28, %eax
jne 0x742f
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x28(%rbp), %rax
xorl %ecx, %ecx
leaq -0x90(%rbp), %r8
leaq -0x38(%rbp), %r9
movq %rax, (%rsp)
callq 0xac40
movq -0x80(%rbp), %rcx
movq -0xa0(%rbp), %rax
movq %rcx, 0x8(%rax)
cmpq $0x0, -0x70(%rbp)
jne 0x7267
cmpq $0x0, -0x68(%rbp)
jne 0x7267
cmpq $0x0, -0x58(%rbp)
je 0x73be
movl $0x1, %edi
movl $0x30, %esi
callq 0x3120
movq %rax, -0x98(%rbp)
cmpq $0x0, -0x98(%rbp)
je 0x73ac
cmpq $0x0, -0x70(%rbp)
je 0x72b9
movq -0x70(%rbp), %rax
movl (%rax), %ecx
movq -0x98(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x98(%rbp), %rax
leaq -0x26f0(%rip), %rcx     # 0x4bc0
movq %rcx, 0x18(%rax)
jmp 0x7379
cmpq $0x0, -0x68(%rbp)
je 0x7356
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x68(%rbp), %rcx
movslq (%rcx), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl (%rax), %ecx
movq -0x98(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x40(%rbp), %rax
movl (%rax), %ecx
movq -0x98(%rbp), %rax
movl %ecx, 0x28(%rax)
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x7342
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x98(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x98(%rbp), %rax
leaq -0x358c(%rip), %rcx     # 0x3db0
movq %rcx, 0x18(%rax)
jmp 0x7354
movq -0x98(%rbp), %rax
leaq -0x35d0(%rip), %rcx     # 0x3d80
movq %rcx, 0x18(%rax)
jmp 0x7377
movq -0x58(%rbp), %rcx
movq -0x98(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x98(%rbp), %rax
leaq -0x2643(%rip), %rcx     # 0x4d30
movq %rcx, 0x18(%rax)
jmp 0x7379
movq -0xa0(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x98(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x98(%rbp), %rcx
movq -0xa0(%rbp), %rax
movq %rcx, 0x8(%rax)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x73bc
movq -0x28(%rbp), %rdi
movq 0x19da9(%rip), %rsi     # 0x21160
callq 0x3070
jmp 0x73be
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
jne 0x742d
cmpl $0x0, -0x38(%rbp)
jle 0x7412
cmpl $0x100, -0x38(%rbp)     # imm = 0x100
jge 0x7412
movl -0x34(%rbp), %ecx
andl $0x7fffff, %ecx         # imm = 0x7FFFFF
shll $0x8, %ecx
orl -0x38(%rbp), %ecx
movq -0xa0(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0xa0(%rbp), %rax
leaq 0x3c50(%rip), %rcx      # 0xb050
movq %rcx, 0x18(%rax)
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x50(%rbp)
jmp 0x742b
movq -0x28(%rbp), %rdi
movq -0x50(%rbp), %rax
movl 0x28(%rax), %edx
leaq 0x14711(%rip), %rsi     # 0x1bb35
movb $0x0, %al
callq 0x31f0
jmp 0x742d
jmp 0x7450
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x8(%rbp), %rax
movl 0x28(%rax), %ecx
leaq 0x143cb(%rip), %rsi     # 0x1b814
movb $0x0, %al
callq 0x31f0
jmp 0x7477
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdx
addq $0x1, %rdx
movq -0x8(%rbp), %rax
movl 0x28(%rax), %ecx
leaq 0x1475b(%rip), %rsi     # 0x1bbcb
movb $0x0, %al
callq 0x31f0
jmp 0x749a
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x8(%rbp), %rax
movl 0x28(%rax), %ecx
leaq 0x1475f(%rip), %rsi     # 0x1bbf2
movb $0x0, %al
callq 0x31f0
jmp 0x74ac
movq -0x28(%rbp), %rdi
movq 0x19cb9(%rip), %rsi     # 0x21160
callq 0x3070
movq -0x50(%rbp), %rax
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax)