// File: /workspace/github_c_makefile_star2_O0/martincameron[P]towntalk/towntalk.c
// Function: parse_expression
struct element* parse_expression( struct element *elem,
	struct function *func, struct variables *vars, struct expression *prev, char *message ) {
	struct element *next = elem->next;
	char *value = elem->str.string, chr = value[ 0 ];
	struct local_variable *local;
	enum reference_type type = 0;
	struct operator *oper;
	struct string *decl;
	if( ( chr >= '0' && chr <= '9' ) || ( chr == '-' && ( value[ 1 ] >= '0' && value[ 1 ] <= '9' ) ) ) {
		/* Number literal. */
		next = parse_number_literal_expression( elem, prev, message );
	} else if( chr == '"' ) {
		/* String literal. */
		next = parse_string_literal_expression( elem, prev, message );
	} else if( chr == '$' && value[ 1 ] == 0 ) {
		/* Element literal. */
		next = parse_element_literal_expression( elem, func->env, prev, message );
	} else if( ( chr == '`' || chr == '\'' ) && value[ 1 ] == 0 ) {
		/* Infix operator.*/
		next = parse_infix_expression( elem, func, vars, prev, message );
	} else if( chr == '\'' && value[ 1 ] ) {
		/* Character literal. */
		next = parse_character_literal_expression( elem, prev, message );
	} else if( chr == '\\' && value[ 1 ] == 0 && elem->next && elem->next->str.string[ 0 ] == '"' ) {
		/* Escaped character literal. */
		next = parse_character_literal_expression( elem->next, prev, message );
	} else if( chr == '[' ) {
		/* Array index operator. */
		next = parse_index_expression( elem, func, vars, prev, message );
	} else if( elem->str.length > 128 ) {
		sprintf( message, "Invalid expression '%.64s' on line %d.", value, elem->line );
	} else if( chr == '@' ) {
		if( value[ 1 ] ) {
			/* Function reference operator. */
			next = parse_func_ref_expression( elem, func, prev, message );
		} else {
			/* Recursive function call. */
			next = parse_call_expression( elem, func, vars, func, prev, message );
		}
	} else if( value[ 0 ] == ':' ) {
		if( value[ 1 ] == 0 ) {
			/* Function reference call. */
			next = parse_refcall_expression( elem, func, vars, prev, message );
		} else {
			/* Member function call. */
			next = parse_thiscall_expression( elem, func, vars, prev, message );
		}
	} else {
		local = get_local_variable( func->variable_decls, value, "+-.:" );
		if( local ) {
			/* Local variable reference.*/
			next = parse_local_expression( elem, func, vars, local, prev, message );
		} else {
			local = NULL;
			if( vars ) {
				local = get_local_variable( vars->func->variable_decls, value, ".:" );
			}
			if( local ) {
				/* Captured local variable. */
				next = parse_capture_expression( elem, func, vars, local, prev, message );
			} else {
				oper = get_operator( value, func->env->operators_index[ hash_code( value, 0 ) ] );
				if( oper ) {
					/* Operator. */
					next = parse_operator_expression( elem, oper, func, vars, prev, message );
				} else {
					decl = find_decl( func, value, 0, "!.:" );
					if( decl ) {
						type = decl->type;
					}
					switch( type ) {
						case CONST: case GLOBAL:
							/* Global variable reference.*/
							next = parse_global_expression( elem, func, vars, ( struct global_variable * ) decl, prev, message );
							break;
						case FUNCTION:
							/* Function call.*/
							next = parse_call_expression( elem, func, vars, ( struct function * ) decl, prev, message );
							break;
						case STRUCT:
							/* Structure. */
							next = parse_struct_expression( elem, func, vars, ( struct structure * ) decl, prev, message );
							break;
						default:
							sprintf( message, "Unhandled expression '%.64s' on line %d.", value, elem->line );
							break;
					}
				}
			}
		}
	}
	if( message[ 0 ] == 0 && next && next->str.string[ 0 ] == '(' ) {
		sprintf( message, "Unexpected '(' after expression on line %d.", next->line );
	}
	if( message[ 0 ] ) {
		dispose_expressions( prev->next );
		prev->next = NULL;
	}
	return next;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movb (%rax), %al
movb %al, -0x39(%rbp)
movl $0x0, -0x4c(%rbp)
movsbl -0x39(%rbp), %eax
cmpl $0x30, %eax
jl 0x6119
movsbl -0x39(%rbp), %eax
cmpl $0x39, %eax
jle 0x613c
movsbl -0x39(%rbp), %eax
cmpl $0x2d, %eax
jne 0x6156
movq -0x38(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x30, %eax
jl 0x6156
movq -0x38(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x39, %eax
jg 0x6156
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x65f0
movq %rax, -0x30(%rbp)
jmp 0x657c
movsbl -0x39(%rbp), %eax
cmpl $0x22, %eax
jne 0x6179
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x66c0
movq %rax, -0x30(%rbp)
jmp 0x657a
movsbl -0x39(%rbp), %eax
cmpl $0x24, %eax
jne 0x61b1
movq -0x38(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x61b1
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x6730
movq %rax, -0x30(%rbp)
jmp 0x6578
movsbl -0x39(%rbp), %eax
cmpl $0x60, %eax
je 0x61c3
movsbl -0x39(%rbp), %eax
cmpl $0x27, %eax
jne 0x61f2
movq -0x38(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x61f2
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
callq 0x6880
movq %rax, -0x30(%rbp)
jmp 0x6576
movsbl -0x39(%rbp), %eax
cmpl $0x27, %eax
jne 0x6222
movq -0x38(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x0, %eax
je 0x6222
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x6a60
movq %rax, -0x30(%rbp)
jmp 0x6574
movsbl -0x39(%rbp), %eax
cmpl $0x5c, %eax
jne 0x6275
movq -0x38(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x6275
movq -0x8(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x6275
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rax
movsbl (%rax), %eax
cmpl $0x22, %eax
jne 0x6275
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x6a60
movq %rax, -0x30(%rbp)
jmp 0x6572
movsbl -0x39(%rbp), %eax
cmpl $0x5b, %eax
jne 0x62a0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
callq 0x6b70
movq %rax, -0x30(%rbp)
jmp 0x6570
movq -0x8(%rbp), %rax
cmpl $0x80, 0x10(%rax)
jle 0x62cf
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rdx
movq -0x8(%rbp), %rax
movl 0x28(%rax), %ecx
leaq 0x15474(%rip), %rsi     # 0x1b737
movb $0x0, %al
callq 0x31f0
jmp 0x656e
movsbl -0x39(%rbp), %eax
cmpl $0x40, %eax
jne 0x6323
movq -0x38(%rbp), %rax
cmpb $0x0, 0x1(%rax)
je 0x62fd
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x6c70
movq %rax, -0x30(%rbp)
jmp 0x631e
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %r8
movq -0x28(%rbp), %r9
callq 0x6d50
movq %rax, -0x30(%rbp)
jmp 0x656c
movq -0x38(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3a, %eax
jne 0x637d
movq -0x38(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x635b
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
callq 0x6ec0
movq %rax, -0x30(%rbp)
jmp 0x6378
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
callq 0x7010
movq %rax, -0x30(%rbp)
jmp 0x656a
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rdi
movq -0x38(%rbp), %rsi
leaq 0x153ce(%rip), %rdx     # 0x1b75e
callq 0x74c0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x63c6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x48(%rbp), %rcx
movq -0x20(%rbp), %r8
movq -0x28(%rbp), %r9
callq 0x7560
movq %rax, -0x30(%rbp)
jmp 0x6568
movq $0x0, -0x48(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x63f5
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x48(%rax), %rdi
movq -0x38(%rbp), %rsi
leaq 0x15378(%rip), %rdx     # 0x1b764
callq 0x74c0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x6422
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x48(%rbp), %rcx
movq -0x20(%rbp), %r8
movq -0x28(%rbp), %r9
callq 0x7740
movq %rax, -0x30(%rbp)
jmp 0x6566
movq -0x38(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x38(%rbp), %rdi
xorl %esi, %esi
callq 0x7960
movq -0x70(%rbp), %rdi
movl %eax, %ecx
movq -0x68(%rbp), %rax
movslq %ecx, %rcx
movq 0x180(%rax,%rcx,8), %rsi
callq 0x7900
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
je 0x648c
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
movq -0x20(%rbp), %r8
movq -0x28(%rbp), %r9
callq 0x79e0
movq %rax, -0x30(%rbp)
jmp 0x6564
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
leaq 0x152c6(%rip), %rcx     # 0x1b763
callq 0x7b80
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
je 0x64b8
movq -0x60(%rbp), %rax
movsbl 0x14(%rax), %eax
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movl %eax, -0x74(%rbp)
subl $0x3, %eax
je 0x6522
jmp 0x64c5
movl -0x74(%rbp), %eax
addl $-0x4, %eax
subl $0x2, %eax
jb 0x64dc
jmp 0x64d2
movl -0x74(%rbp), %eax
subl $0x6, %eax
je 0x64ff
jmp 0x6545
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x60(%rbp), %rcx
movq -0x20(%rbp), %r8
movq -0x28(%rbp), %r9
callq 0x7dd0
movq %rax, -0x30(%rbp)
jmp 0x6562
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x60(%rbp), %rcx
movq -0x20(%rbp), %r8
movq -0x28(%rbp), %r9
callq 0x6d50
movq %rax, -0x30(%rbp)
jmp 0x6562
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x60(%rbp), %rcx
movq -0x20(%rbp), %r8
movq -0x28(%rbp), %r9
callq 0x8040
movq %rax, -0x30(%rbp)
jmp 0x6562
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rdx
movq -0x8(%rbp), %rax
movl 0x28(%rax), %ecx
leaq 0x1520c(%rip), %rsi     # 0x1b767
movb $0x0, %al
callq 0x31f0
jmp 0x6564
jmp 0x6566
jmp 0x6568
jmp 0x656a
jmp 0x656c
jmp 0x656e
jmp 0x6570
jmp 0x6572
jmp 0x6574
jmp 0x6576
jmp 0x6578
jmp 0x657a
jmp 0x657c
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
jne 0x65b8
cmpq $0x0, -0x30(%rbp)
je 0x65b8
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movsbl (%rax), %eax
cmpl $0x28, %eax
jne 0x65b8
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rax
movl 0x28(%rax), %edx
leaq 0x151df(%rip), %rsi     # 0x1b790
movb $0x0, %al
callq 0x31f0
movq -0x28(%rbp), %rax
cmpb $0x0, (%rax)
je 0x65da
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x3e60
movq -0x20(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x30(%rbp), %rax
addq $0x80, %rsp
popq %rbp
retq
nopw (%rax,%rax)