// File: luizaes[P]post-machine-simulator/post_machine_sim.cpp
// Function: PostMachineSimulator::TraverseDiagram(int)
int PostMachineSimulator::TraverseDiagram(int current_node) {

	char symbol, current_queue_symbol = NONE;
	bool transition_found = false;
	string name;
	list<state>::iterator it;

	/*
		If the work queue is empty and we haven't reached the accepting state, reject entry
		If we reached the accepting state, accept entry
	*/ 
	if(flow_diagram[current_node].name.compare(accept_state) == 0) {
		return ACCEPT;
	} else if(work_queue.empty()) {
		return REJECT;
	}

	/* If current state is READ */
	if(flow_diagram[current_node].name.front() == 'R' || flow_diagram[current_node].name.front() == 'r') {
		
		/* Check first element of the queue */
		symbol = work_queue.front();
		for(it = flow_diagram[current_node].flows.begin(); it != flow_diagram[current_node].flows.end(); it++) {
			if((*it).read_symbol == symbol) {
				transition_found = true;
				name = (*it).name;
				current_queue_symbol = (*it).add_symbol;
				break;
			}
		}

		/* If the transition was not found, the machine halts by indefinition */
		if(!transition_found) {
			return REJECT;
		} else {
			/* Remove element from the queue, since it was already read */
			work_queue.pop();
			for(int i = 0; i < flow_diagram.size(); i++) {
				if(name.compare(flow_diagram[i].name) == 0) {
					if(current_queue_symbol != NONE) {
						work_queue.push(current_queue_symbol);
					}
					return TraverseDiagram(i);
				}
			}
		}

	/* If current state is ADD or START */
	} else {
		name = flow_diagram[current_node].flows.front().name;
		current_queue_symbol = flow_diagram[current_node].flows.front().add_symbol;

		for(int i = 0; i < flow_diagram.size(); i++) {
			if(name.compare(flow_diagram[i].name) == 0) {
				if(current_queue_symbol != NONE) {
					work_queue.push(current_queue_symbol);
				}
				return TraverseDiagram(i);
			}
		}
	}
	return REJECT;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x80(%rbp)
movb $0x24, -0x16(%rbp)
movb $0x0, -0x17(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x22c0
leaq -0x40(%rbp), %rdi
callq 0x4c30
movq -0x80(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0x4c50
movq -0x80(%rbp), %rsi
movq %rax, %rdi
addq $0x88, %rsi
callq 0x2030
movl %eax, -0x74(%rbp)
jmp 0x38f9
movl -0x74(%rbp), %eax
cmpl $0x0, %eax
jne 0x392e
movl $0x1, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x3c54
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x2160
jmp 0x3c69
movq -0x80(%rbp), %rdi
addq $0x18, %rdi
callq 0x4c70
movb %al, -0x81(%rbp)
jmp 0x3943
movb -0x81(%rbp), %al
testb $0x1, %al
jne 0x394f
jmp 0x3962
movl $0x0, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x3c54
jmp 0x3964
movq -0x80(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0x4c50
movq %rax, %rdi
callq 0x20a0
movsbl (%rax), %eax
cmpl $0x52, %eax
je 0x39a2
movq -0x80(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0x4c50
movq %rax, %rdi
callq 0x20a0
movsbl (%rax), %eax
cmpl $0x72, %eax
jne 0x3b50
movq -0x80(%rbp), %rdi
addq $0x18, %rdi
callq 0x4c90
movq %rax, -0x90(%rbp)
jmp 0x39b8
movq -0x80(%rbp), %rdi
movq -0x90(%rbp), %rax
movb (%rax), %al
movb %al, -0x15(%rbp)
movslq -0x14(%rbp), %rsi
callq 0x4c50
movq %rax, %rdi
addq $0x20, %rdi
callq 0x4cb0
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x80(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0x4c50
movq %rax, %rdi
addq $0x20, %rdi
callq 0x4d10
movq %rax, -0x60(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x4ce0
testb $0x1, %al
jne 0x3a19
jmp 0x3a70
leaq -0x40(%rbp), %rdi
callq 0x4d40
movsbl 0x20(%rax), %eax
movsbl -0x15(%rbp), %ecx
cmpl %ecx, %eax
jne 0x3a5a
movb $0x1, -0x17(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x4d40
movq %rax, %rsi
leaq -0x38(%rbp), %rdi
callq 0x2040
jmp 0x3a49
leaq -0x40(%rbp), %rdi
callq 0x4d40
movb 0x21(%rax), %al
movb %al, -0x16(%rbp)
jmp 0x3a70
jmp 0x3a5c
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
callq 0x4d60
movq %rax, -0x68(%rbp)
jmp 0x39e9
testb $0x1, -0x17(%rbp)
jne 0x3a89
movl $0x0, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x3c54
movq -0x80(%rbp), %rdi
addq $0x18, %rdi
callq 0x4d90
jmp 0x3a98
movl $0x0, -0x6c(%rbp)
movq -0x80(%rbp), %rdi
movslq -0x6c(%rbp), %rax
movq %rax, -0x98(%rbp)
callq 0x4db0
movq %rax, %rcx
movq -0x98(%rbp), %rax
cmpq %rcx, %rax
jae 0x3b49
movq -0x80(%rbp), %rdi
movslq -0x6c(%rbp), %rsi
callq 0x4c50
movq %rax, %rsi
leaq -0x38(%rbp), %rdi
callq 0x2030
movl %eax, -0x9c(%rbp)
jmp 0x3ae7
movl -0x9c(%rbp), %eax
cmpl $0x0, %eax
jne 0x3b39
movsbl -0x16(%rbp), %eax
cmpl $0x24, %eax
je 0x3b10
movq -0x80(%rbp), %rdi
addq $0x18, %rdi
leaq -0x16(%rbp), %rsi
callq 0x4de0
jmp 0x3b0e
jmp 0x3b10
movq -0x80(%rbp), %rdi
movl -0x6c(%rbp), %esi
callq 0x38a0
movl %eax, -0xa0(%rbp)
jmp 0x3b24
movl -0xa0(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x3c54
jmp 0x3b3b
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x3a9f
jmp 0x3b4b
jmp 0x3c46
movq -0x80(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0x4c50
movq %rax, %rdi
addq $0x20, %rdi
callq 0x4e10
movq %rax, %rsi
leaq -0x38(%rbp), %rdi
callq 0x2040
jmp 0x3b77
movq -0x80(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0x4c50
movq %rax, %rdi
addq $0x20, %rdi
callq 0x4e10
movb 0x21(%rax), %al
movb %al, -0x16(%rbp)
movl $0x0, -0x70(%rbp)
movq -0x80(%rbp), %rdi
movslq -0x70(%rbp), %rax
movq %rax, -0xa8(%rbp)
callq 0x4db0
movq %rax, %rcx
movq -0xa8(%rbp), %rax
cmpq %rcx, %rax
jae 0x3c44
movq -0x80(%rbp), %rdi
movslq -0x70(%rbp), %rsi
callq 0x4c50
movq %rax, %rsi
leaq -0x38(%rbp), %rdi
callq 0x2030
movl %eax, -0xac(%rbp)
jmp 0x3be5
movl -0xac(%rbp), %eax
cmpl $0x0, %eax
jne 0x3c34
movsbl -0x16(%rbp), %eax
cmpl $0x24, %eax
je 0x3c0e
movq -0x80(%rbp), %rdi
addq $0x18, %rdi
leaq -0x16(%rbp), %rsi
callq 0x4de0
jmp 0x3c0c
jmp 0x3c0e
movq -0x80(%rbp), %rdi
movl -0x70(%rbp), %esi
callq 0x38a0
movl %eax, -0xb0(%rbp)
jmp 0x3c22
movl -0xb0(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x3c54
jmp 0x3c36
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x3b9d
jmp 0x3c46
movl $0x0, -0x4(%rbp)
movl $0x1, -0x50(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x2160
movl -0x4(%rbp), %eax
addq $0xb0, %rsp
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x2370
nopw %cs:(%rax,%rax)