// File: /workspace/github_cpp_makefile_star2_O2/luizaes[P]post-machine-simulator/post_machine_sim.cpp
// Function: PostMachineSimulator::BuildDiagram()
DiagramState* PostMachineSimulator::BuildDiagram() {
	string state_name, input_entry, transition, error_text;
	int number_states, number_transitions, output, start_index = 0;
	node node_aux;
	state state_aux;
	bool error_found = false, state_found = false;
	char symbol, current_queue_symbol = NONE;

	/* Read the number of states the Post Machine has */
	cin >> number_states;

	/* Read the name of each of these states, storing them in an adjacency list */
	for (int i = 0; i < number_states; i++) {
		cin >> state_name;
		node_aux.name = state_name;
		flow_diagram.push_back(node_aux);
	}

	/* Read the name of the starting state */
	cin >> start_state;

	/* Read the name of the accepting state - we don't have a rejection state, 
	   the machine halts and rejects an input by indefinition */
	cin >> accept_state;

	/* Read the number of transitions present in the diagram */
	cin >> number_transitions;

	/* Read each transition */
	for(int i = 0; i < number_transitions; i++) {
		cin >> transition;
		state_found = false;

		for (int j = 0; j < number_states; j++) {
			/* If the state specified in the transition exists */
			if(flow_diagram[j].name.compare(transition) == 0) {
				state_found = true;

				/* If the transition starts with a READ state */
				if(transition.front() == 'R' || transition.front() == 'r') {
					cin >> symbol;
					ReadInputLine(transition);

					if(transition.compare(start_state) == 0) {
						string message = "[ERROR] Invalid transition: it's not possible to have a transition pointing to the starting state.";
						DiagramState* response = new DiagramState(/*has_error=*/true, message);
						return response;
					} else if(transition.compare(" " + accept_state) != 0 && (transition.at(1) == 'A' || transition.at(1) == 'a')) {
						current_queue_symbol = transition.substr(transition.length()-1, 1).front();
						transition = transition.substr(1, transition.length()-3);
					} else {
						transition = transition.substr(1, transition.length()-1);
					}

					state_aux.name = transition;
					state_aux.read_symbol = symbol;
					state_aux.add_symbol = current_queue_symbol;
					current_queue_symbol = NONE;
					flow_diagram[j].flows.push_back(state_aux);

				/* If the transition starts with a START state */
				} else if(transition.compare(start_state) == 0) {
					ReadInputLine(transition);

					if(transition.at(1) == 'A' || transition.at(1) == 'a') {
						current_queue_symbol = transition.substr(transition.length()-1, 1).front();
						transition = transition.substr(1, transition.length()-3);
					}

					state_aux.name = transition;
					state_aux.read_symbol = NONE;
					state_aux.add_symbol = current_queue_symbol;
					current_queue_symbol = NONE;
					flow_diagram[j].flows.push_back(state_aux);
				}  else if(transition.compare(accept_state) == 0) {
					string message = "[ERROR] Invalid transition: the accepting state cannot have a transition to any other state.";
					DiagramState* response = new DiagramState(/*has_error=*/true, message);
					return response;
				/* If the transition starts with an ADD state */
				} else if(transition.front() == 'A' || transition.front() == 'a') {
					cin >> symbol;
					ReadInputLine(transition);
					if(transition.compare(" " + start_state) == 0) {
						string message = "[ERROR] Invalid transition: it's not possible to have a transition pointing to the starting state.";
						DiagramState* response = new DiagramState(/*has_error=*/true, message);
						return response;
					} else if(transition.at(1) == 'A' || transition.at(1) == 'a') {
						current_queue_symbol = transition.substr(transition.length()-1, 1).front();
						transition = transition.substr(1, transition.length()-3);
					} else {
						transition = transition.substr(1, transition.length()-1);
					}
					state_aux.name = transition;
					state_aux.read_symbol = NONE;
					state_aux.add_symbol = current_queue_symbol;
					current_queue_symbol = NONE;
					flow_diagram[j].flows.push_back(state_aux);
				}
				break;
			}
		}

		if(!state_found) {
			string message = "[ERROR] Invalid transition: the specified state does not exist.";
			DiagramState* response = new DiagramState(/*has_error=*/true, message);
			return response;
		}
	}
	string message = "";
	DiagramState* response = new DiagramState(/*has_error=*/false, message);
	return response;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x128, %rsp            # imm = 0x128
leaq -0xc8(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movq %rdi, %rbx
xorl %r13d, %r13d
leaq -0x108(%rbp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
movb %r13b, (%rax)
movb %r13b, (%rcx)
leaq -0x78(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
leaq -0x140(%rbp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
movb %r13b, (%rcx)
leaq -0x130(%rbp), %rcx
movq %rcx, 0x8(%rcx)
movq %rcx, (%rcx)
andq $0x0, 0x10(%rcx)
leaq -0xe8(%rbp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
movb %r13b, (%rax)
movb %r13b, (%rcx)
leaq -0xa8(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb %r13b, (%rax)
movq 0x43e7(%rip), %rdi      # 0x6fe0
leaq -0x54(%rbp), %rsi
callq 0x2110
movq 0x43d7(%rip), %r14      # 0x6fe0
leaq -0xd8(%rbp), %r15
leaq -0x150(%rbp), %r12
cmpl -0x54(%rbp), %r13d
jge 0x2c43
movq %r14, %rdi
movq %r15, %rsi
callq 0x21c0
movq %r12, %rdi
movq %r15, %rsi
callq 0x20f0
movq %rbx, %rdi
movq %r12, %rsi
callq 0x32e4
incl %r13d
jmp 0x2c17
leaq 0x68(%rbx), %rsi
movq 0x4392(%rip), %rdi      # 0x6fe0
movq %rsi, -0x60(%rbp)
callq 0x21c0
leaq 0x88(%rbx), %rsi
movq 0x437b(%rip), %rdi      # 0x6fe0
movq %rsi, -0x90(%rbp)
callq 0x21c0
movq 0x4368(%rip), %rdi      # 0x6fe0
leaq -0x68(%rbp), %rsi
callq 0x2110
xorl %r12d, %r12d
leaq -0x88(%rbp), %r13
cmpl -0x68(%rbp), %r12d
jge 0x30df
movq 0x4344(%rip), %rdi      # 0x6fe0
movq %r13, %rsi
callq 0x21c0
pushq $-0x1
popq %r14
pushq $-0x18
popq %r15
movslq -0x54(%rbp), %rax
incq %r14
cmpq %rax, %r14
jge 0x304b
movq (%rbx), %rax
leaq (%rax,%r15), %rdi
addq $0x18, %rdi
movq %r13, %rsi
callq 0x2030
addq $0x38, %r15
testl %eax, %eax
jne 0x2cac
movl %r12d, -0x64(%rbp)
movq -0x88(%rbp), %rax
movzbl (%rax), %eax
orl $0x20, %eax
cmpl $0x72, %eax
jne 0x2d67
movq 0x42ec(%rip), %rdi      # 0x6fe0
leaq -0x2a(%rbp), %rsi
callq 0x21e0
movq %r13, %rdi
callq 0x2938
movq %r13, %rdi
movq -0x60(%rbp), %rsi
callq 0x2030
testl %eax, %eax
je 0x3111
leaq -0x50(%rbp), %r12
movq %r12, %rdi
leaq 0x13d4(%rip), %rsi      # 0x40fb
movq -0x90(%rbp), %rdx
callq 0x335b
movq %r13, %rdi
movq %r12, %rsi
callq 0x2030
testl %eax, %eax
je 0x2e7a
movq %r13, %rdi
pushq $0x1
popq %rsi
callq 0x2270
cmpb $0x41, (%rax)
jne 0x2e84
movq %r12, %rdi
callq 0x20c0
jmp 0x2ea0
movq %r13, %rdi
movq -0x60(%rbp), %rsi
callq 0x2030
testl %eax, %eax
je 0x2f68
movq %r13, %rdi
movq -0x90(%rbp), %rsi
callq 0x2030
testl %eax, %eax
je 0x3144
movq -0x88(%rbp), %rax
movzbl (%rax), %eax
orl $0x20, %eax
cmpl $0x61, %eax
jne 0x2f5c
movq 0x4231(%rip), %rdi      # 0x6fe0
leaq -0x2a(%rbp), %rsi
callq 0x21e0
movq %r13, %rdi
callq 0x2938
leaq -0x50(%rbp), %r12
movq %r12, %rdi
leaq 0x132d(%rip), %rsi      # 0x40fb
movq -0x60(%rbp), %rdx
callq 0x335b
movq %r13, %rdi
movq %r12, %rsi
callq 0x2030
movl %eax, %r14d
movq %r12, %rdi
callq 0x20c0
testl %r14d, %r14d
je 0x3177
movq %r13, %rdi
pushq $0x1
popq %rsi
callq 0x2270
cmpb $0x41, (%rax)
je 0x2e1a
movq %r13, %rdi
pushq $0x1
popq %rsi
callq 0x2270
cmpb $0x61, (%rax)
jne 0x3005
movq -0x80(%rbp), %rdx
decq %rdx
leaq -0x50(%rbp), %rdi
movq %r13, %rsi
pushq $0x1
popq %r14
movq %r14, %rcx
callq 0x21a0
movq -0x50(%rbp), %rax
movb (%rax), %r12b
leaq -0x50(%rbp), %rdi
callq 0x20c0
movq -0x80(%rbp), %rcx
addq $-0x3, %rcx
leaq -0x50(%rbp), %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x21a0
movq %r13, %rdi
leaq -0x50(%rbp), %r14
movq %r14, %rsi
callq 0x21b0
movq %r14, %rdi
callq 0x20c0
movl %r12d, %r14d
jmp 0x3034
movq %r12, %rdi
callq 0x20c0
jmp 0x2efe
movq %r13, %rdi
pushq $0x1
popq %rsi
callq 0x2270
movb (%rax), %r14b
movq %r12, %rdi
callq 0x20c0
cmpb $0x61, %r14b
jne 0x2efe
movq -0x80(%rbp), %rdx
decq %rdx
movq %r12, %rdi
movq %r13, %rsi
pushq $0x1
popq %r14
movq %r14, %rcx
callq 0x21a0
movq %r12, %rcx
movq -0x50(%rbp), %rax
movb (%rax), %r12b
movq %rcx, %rdi
callq 0x20c0
movq -0x80(%rbp), %rcx
addq $-0x3, %rcx
leaq -0x50(%rbp), %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x21a0
movq %r13, %rdi
leaq -0x50(%rbp), %r14
movq %r14, %rsi
callq 0x21b0
movq %r14, %rdi
callq 0x20c0
movl %r12d, %r14d
jmp 0x2f29
movq -0x80(%rbp), %rcx
decq %rcx
movq %r12, %rdi
movq %r13, %rsi
pushq $0x1
popq %rdx
callq 0x21a0
movq %r13, %rdi
movq %r12, %rsi
callq 0x21b0
movq %r12, %rdi
callq 0x20c0
movb $0x24, %r14b
leaq -0xb8(%rbp), %rdi
movq %r13, %rsi
callq 0x20f0
movb -0x2a(%rbp), %r12b
movb %r12b, -0x98(%rbp)
movb %r14b, -0x97(%rbp)
addq (%rbx), %r15
movq %r15, %rdi
leaq -0xb8(%rbp), %rsi
callq 0x33d2
movl -0x64(%rbp), %r12d
incl %r12d
jmp 0x2c8b
movq %r13, %rdi
callq 0x2938
movq %r13, %rdi
pushq $0x1
popq %rsi
callq 0x2270
cmpb $0x41, (%rax)
je 0x2f93
movq %r13, %rdi
pushq $0x1
popq %rsi
callq 0x2270
movb $0x24, %r14b
cmpb $0x61, (%rax)
jne 0x2fee
movq -0x80(%rbp), %rdx
decq %rdx
leaq -0x50(%rbp), %rdi
movq %r13, %rsi
pushq $0x1
popq %r14
movq %r14, %rcx
callq 0x21a0
movq -0x50(%rbp), %rax
movb (%rax), %r12b
leaq -0x50(%rbp), %rdi
callq 0x20c0
movq -0x80(%rbp), %rcx
addq $-0x3, %rcx
leaq -0x50(%rbp), %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x21a0
movq %r13, %rdi
leaq -0x50(%rbp), %r14
movq %r14, %rsi
callq 0x21b0
movq %r14, %rdi
callq 0x20c0
movl %r12d, %r14d
movb $0x24, %r12b
leaq -0xb8(%rbp), %rdi
movq %r13, %rsi
callq 0x20f0
jmp 0x2f3c
movq -0x80(%rbp), %rcx
decq %rcx
leaq -0x50(%rbp), %r14
movq %r14, %rdi
movq %r13, %rsi
pushq $0x1
popq %rdx
callq 0x21a0
movq %r13, %rdi
movq %r14, %rsi
callq 0x21b0
movq %r14, %rdi
callq 0x20c0
movb $0x24, %r14b
movb $0x24, %r12b
leaq -0xb8(%rbp), %rdi
movq %r13, %rsi
callq 0x20f0
jmp 0x2f3c
leaq 0x1108(%rip), %rsi      # 0x415a
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x3320
pushq $0x28
popq %rdi
callq 0x2180
movq %rax, %r14
pushq $0x1
popq %rsi
leaq -0x50(%rbp), %rdx
movq %rax, %rdi
callq 0x3b9c
leaq -0x50(%rbp), %rdi
callq 0x20c0
leaq -0xb8(%rbp), %rdi
callq 0x20c0
leaq -0x150(%rbp), %rdi
callq 0x28ba
leaq -0xf8(%rbp), %rdi
callq 0x20c0
leaq -0x88(%rbp), %rdi
callq 0x20c0
leaq -0x118(%rbp), %rdi
callq 0x20c0
leaq -0xd8(%rbp), %rdi
callq 0x20c0
movq %r14, %rax
addq $0x128, %rsp            # imm = 0x128
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1016(%rip), %rsi      # 0x40fc
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x3320
pushq $0x28
popq %rdi
callq 0x2180
movq %rax, %r14
leaq -0x50(%rbp), %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x3b9c
jmp 0x3079
leaq 0xf80(%rip), %rsi       # 0x4098
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x3320
pushq $0x28
popq %rdi
callq 0x2180
movq %rax, %r14
pushq $0x1
popq %rsi
leaq -0x50(%rbp), %rdx
movq %rax, %rdi
callq 0x3b9c
jmp 0x3079
leaq 0xfb2(%rip), %rsi       # 0x40fd
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x3320
pushq $0x28
popq %rdi
callq 0x2180
movq %rax, %r14
pushq $0x1
popq %rsi
leaq -0x50(%rbp), %rdx
movq %rax, %rdi
callq 0x3b9c
jmp 0x3079
leaq 0xf1a(%rip), %rsi       # 0x4098
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x3320
pushq $0x28
popq %rdi
callq 0x2180
movq %rax, %r14
pushq $0x1
popq %rsi
leaq -0x50(%rbp), %rdx
movq %rax, %rdi
callq 0x3b9c
jmp 0x3079
jmp 0x31d8
jmp 0x31ec
jmp 0x3202
jmp 0x31d8
jmp 0x31ec
jmp 0x3202
jmp 0x31d8
jmp 0x31ec
jmp 0x3202
jmp 0x3202
jmp 0x31d8
jmp 0x31ec
jmp 0x3202
jmp 0x3202
jmp 0x3202
jmp 0x3202
jmp 0x3202
jmp 0x31ec
jmp 0x3202
jmp 0x3202
jmp 0x3202
jmp 0x3202
jmp 0x3202
movq %rax, %rbx
pushq $0x28
popq %rsi
movq %r14, %rdi
callq 0x2190
jmp 0x31ef
jmp 0x31ec
jmp 0x3202
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x20c0
jmp 0x3205
jmp 0x3202
jmp 0x3202
jmp 0x3202
jmp 0x3202
movq %rax, %rbx
leaq -0xb8(%rbp), %rdi
callq 0x20c0
leaq -0x150(%rbp), %rdi
callq 0x28ba
leaq -0xf8(%rbp), %rdi
callq 0x20c0
leaq -0x88(%rbp), %rdi
callq 0x20c0
leaq -0x118(%rbp), %rdi
callq 0x20c0
leaq -0xd8(%rbp), %rdi
callq 0x20c0
movq %rbx, %rdi
callq 0x2250
nop