// File: iamlouk[P]asbi/src/parser.cc
// Function: asbi::Parser::parse_assign()
ast::Node* Parser::parse_assign() {
	auto left = parse_logic();
	if (tokenizer.peek().type == tok::Assign) {
		tokenizer.next();
		auto right = parse_expr();

		ast::Variable* var = dynamic_cast<ast::Variable*>(left);
		if (var != nullptr)
			return new ast::AssignVariable(var, right);

		ast::Access* acs = dynamic_cast<ast::Access*>(left);
		if (acs != nullptr)
			return new ast::AssignAccess(acs, right);

		throw utils::parser_error("one can only assign to variables or dict subscripts", left);
	}

	if (tokenizer.peek().type == tok::Declare) {
		auto tok = tokenizer.next();

		auto right = parse_expr();
		auto var = dynamic_cast<ast::Variable*>(left);
		if (var != nullptr) {
			std::vector<std::pair<ast::Variable*, ast::Node*>> decls;
			decls.push_back(std::make_pair(var, right));
			while (tokenizer.peek().type == tok::Comma) {
				tokenizer.next();
				auto node = parse_logic();
				auto var = dynamic_cast<ast::Variable*>(node);
				if (var == nullptr)
					throw utils::parser_error("expected Variable", node);

				ast::Node* val = nullptr;
				if (tokenizer.peek().type == tok::Declare) {
					tokenizer.next();
					val = parse_logic();
				}

				decls.push_back(std::make_pair(var, val));
			}

			return new ast::VariableDecl(std::move(decls));
		}

		ast::List* list = dynamic_cast<ast::List*>(left);
		if (list != nullptr) {
			auto node = new ast::DestructList(std::move(list->values), right);
			list->values.clear();
			delete list;
			return node;
		}

		ast::Map* map = dynamic_cast<ast::Map*>(left);
		if (map != nullptr) {
			/*std::vector<std::pair<ast::Variable*, ast::Node*>> vars;
			for (auto [key, val]: map->values) {
				auto var = dynamic_cast<ast::Variable*>(val);
				if (var == nullptr)
					throw utils::parser_error("only variables allowed in destructuring", left);

				vars.push_back(std::make_pair(var, key));
			}
			map->values.clear();
			delete map;
			return new ast::DestructMap(std::move(vars), right);*/

			throw utils::parser_error("unimplemented!", left);
		}

		throw utils::parser_error("one can only declare variables or destruct using ':='", tok /*left*/);
	}

	return left;
}

// Assembly:
subq $0x2c8, %rsp            # imm = 0x2C8
movq %rdi, 0x2b8(%rsp)
movq 0x2b8(%rsp), %rdi
movq %rdi, 0x138(%rsp)
callq 0xf2c0
movq 0x138(%rsp), %rdi
movq %rax, 0x2b0(%rsp)
callq 0x92b0
movq %rax, 0x2a0(%rsp)
movq %rdx, 0x2a8(%rsp)
cmpl $0x6, 0x2a0(%rsp)
jne 0xe6f2
movq 0x138(%rsp), %rdi
callq 0x9340
movq 0x138(%rsp), %rdi
movq %rax, 0x290(%rsp)
movq %rdx, 0x298(%rsp)
callq 0xe090
movq %rax, 0x288(%rsp)
movq 0x2b0(%rsp), %rax
movq %rax, 0x130(%rsp)
cmpq $0x0, %rax
je 0xe518
movq 0x130(%rsp), %rdi
leaq 0x3d042(%rip), %rsi     # 0x4b540
leaq 0x3d153(%rip), %rdx     # 0x4b658
xorl %eax, %eax
movl %eax, %ecx
callq 0x6520
movq %rax, 0x128(%rsp)
jmp 0xe524
xorl %eax, %eax
movq %rax, 0x128(%rsp)
jmp 0xe524
movq 0x128(%rsp), %rax
movq %rax, 0x280(%rsp)
cmpq $0x0, 0x280(%rsp)
je 0xe5ae
movl $0x18, %edi
callq 0x6460
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x120(%rsp)
movq 0x280(%rsp), %rsi
movq 0x288(%rsp), %rdx
callq 0x12000
jmp 0xe56e
movq 0x120(%rsp), %rax
movq %rax, 0x2c0(%rsp)
jmp 0xee3d
movq 0x120(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
movl $0x18, %esi
callq 0x6470
jmp 0xee4d
movq 0x2b0(%rsp), %rax
movq %rax, 0x118(%rsp)
cmpq $0x0, %rax
je 0xe5ed
movq 0x118(%rsp), %rdi
leaq 0x3cf6d(%rip), %rsi     # 0x4b540
leaq 0x3d0c6(%rip), %rdx     # 0x4b6a0
xorl %eax, %eax
movl %eax, %ecx
callq 0x6520
movq %rax, 0x110(%rsp)
jmp 0xe5f9
xorl %eax, %eax
movq %rax, 0x110(%rsp)
jmp 0xe5f9
movq 0x110(%rsp), %rax
movq %rax, 0x268(%rsp)
cmpq $0x0, 0x268(%rsp)
je 0xe683
movl $0x18, %edi
callq 0x6460
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x108(%rsp)
movq 0x268(%rsp), %rsi
movq 0x288(%rsp), %rdx
callq 0x12050
jmp 0xe643
movq 0x108(%rsp), %rax
movq %rax, 0x2c0(%rsp)
jmp 0xee3d
movq 0x108(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
movl $0x18, %esi
callq 0x6470
jmp 0xee4d
movl $0x48, %edi
callq 0x6200
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x100(%rsp)
movq 0x2b0(%rsp), %rdx
leaq 0x2a187(%rip), %rsi     # 0x38831
callq 0x17550
jmp 0xe6b1
movq 0x100(%rsp), %rdi
leaq 0x3ce68(%rip), %rsi     # 0x4b528
leaq 0x35d9(%rip), %rdx      # 0x11ca0
callq 0x6780
movq 0x100(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
callq 0x6320
jmp 0xee4d
movq 0x138(%rsp), %rdi
callq 0x92b0
movq %rax, 0x258(%rsp)
movq %rdx, 0x260(%rsp)
cmpl $0x7, 0x258(%rsp)
jne 0xee2d
movq 0x138(%rsp), %rdi
callq 0x9340
movq 0x138(%rsp), %rdi
movq %rax, 0x248(%rsp)
movq %rdx, 0x250(%rsp)
callq 0xe090
movq %rax, 0x240(%rsp)
movq 0x2b0(%rsp), %rax
movq %rax, 0xf8(%rsp)
cmpq $0x0, %rax
je 0xe78e
movq 0xf8(%rsp), %rdi
leaq 0x3cdcc(%rip), %rsi     # 0x4b540
leaq 0x3cedd(%rip), %rdx     # 0x4b658
xorl %eax, %eax
movl %eax, %ecx
callq 0x6520
movq %rax, 0xf0(%rsp)
jmp 0xe79a
xorl %eax, %eax
movq %rax, 0xf0(%rsp)
jmp 0xe79a
movq 0xf0(%rsp), %rax
movq %rax, 0x238(%rsp)
cmpq $0x0, 0x238(%rsp)
je 0xeba0
leaq 0x220(%rsp), %rdi
callq 0x120a0
leaq 0x238(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0x120e0
movq %rdx, 0xe0(%rsp)
movq %rax, 0xe8(%rsp)
jmp 0xe7ed
movq 0xe0(%rsp), %rax
movq 0xe8(%rsp), %rcx
movq %rcx, 0x210(%rsp)
movq %rax, 0x218(%rsp)
leaq 0x220(%rsp), %rdi
leaq 0x210(%rsp), %rsi
callq 0x120b0
jmp 0xe824
jmp 0xe826
movq 0x138(%rsp), %rdi
callq 0x92b0
movq %rdx, 0xd0(%rsp)
movq %rax, 0xd8(%rsp)
jmp 0xe845
movq 0xd0(%rsp), %rax
movq 0xd8(%rsp), %rcx
movq %rcx, 0x200(%rsp)
movq %rax, 0x208(%rsp)
cmpl $0x1d, 0x200(%rsp)
jne 0xead8
movq 0x138(%rsp), %rdi
callq 0x9340
movq %rdx, 0xc0(%rsp)
movq %rax, 0xc8(%rsp)
jmp 0xe892
movq 0x138(%rsp), %rdi
movq 0xc0(%rsp), %rax
movq 0xc8(%rsp), %rcx
movq %rcx, 0x1f0(%rsp)
movq %rax, 0x1f8(%rsp)
callq 0xf2c0
movq %rax, 0xb8(%rsp)
jmp 0xe8c9
movq 0xb8(%rsp), %rax
movq %rax, 0x1e8(%rsp)
movq 0x1e8(%rsp), %rax
movq %rax, 0xb0(%rsp)
cmpq $0x0, %rax
je 0xe931
movq 0xb0(%rsp), %rdi
leaq 0x3cc42(%rip), %rsi     # 0x4b540
leaq 0x3cd53(%rip), %rdx     # 0x4b658
xorl %eax, %eax
movl %eax, %ecx
callq 0x6520
movq %rax, 0xa8(%rsp)
jmp 0xe93d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
jmp 0xeb8e
xorl %eax, %eax
movq %rax, 0xa8(%rsp)
jmp 0xe93d
movq 0xa8(%rsp), %rax
movq %rax, 0x1e0(%rsp)
cmpq $0x0, 0x1e0(%rsp)
jne 0xe9cc
movl $0x48, %edi
callq 0x6200
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0xa0(%rsp)
movq 0x1e8(%rsp), %rdx
leaq 0x29ee6(%rip), %rsi     # 0x38865
callq 0x17550
jmp 0xe986
movq 0xa0(%rsp), %rdi
leaq 0x3cb93(%rip), %rsi     # 0x4b528
leaq 0x3304(%rip), %rdx      # 0x11ca0
callq 0x6780
jmp 0xee5a
movq 0xa0(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
callq 0x6320
jmp 0xeb8e
movq 0x138(%rsp), %rdi
movq $0x0, 0x1d8(%rsp)
callq 0x92b0
movq %rdx, 0x90(%rsp)
movq %rax, 0x98(%rsp)
jmp 0xe9f7
movq 0x90(%rsp), %rax
movq 0x98(%rsp), %rcx
movq %rcx, 0x1c8(%rsp)
movq %rax, 0x1d0(%rsp)
cmpl $0x7, 0x1c8(%rsp)
jne 0xea81
movq 0x138(%rsp), %rdi
callq 0x9340
movq %rdx, 0x80(%rsp)
movq %rax, 0x88(%rsp)
jmp 0xea40
movq 0x138(%rsp), %rdi
movq 0x80(%rsp), %rax
movq 0x88(%rsp), %rcx
movq %rcx, 0x1b8(%rsp)
movq %rax, 0x1c0(%rsp)
callq 0xf2c0
movq %rax, 0x78(%rsp)
jmp 0xea74
movq 0x78(%rsp), %rax
movq %rax, 0x1d8(%rsp)
leaq 0x1e0(%rsp), %rdi
leaq 0x1d8(%rsp), %rsi
callq 0x120e0
movq %rdx, 0x68(%rsp)
movq %rax, 0x70(%rsp)
jmp 0xeaa2
movq 0x68(%rsp), %rax
movq 0x70(%rsp), %rcx
movq %rcx, 0x1a8(%rsp)
movq %rax, 0x1b0(%rsp)
leaq 0x220(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x120b0
jmp 0xead3
jmp 0xe826
movl $0x20, %edi
callq 0x6460
movq %rax, 0x60(%rsp)
jmp 0xeae9
movb $0x1, 0x18f(%rsp)
leaq 0x190(%rsp), %rdi
movq %rdi, 0x58(%rsp)
leaq 0x220(%rsp), %rsi
callq 0x12120
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x12150
jmp 0xeb1c
movq 0x60(%rsp), %rax
movb $0x0, 0x18f(%rsp)
movq %rax, 0x2c0(%rsp)
leaq 0x190(%rsp), %rdi
callq 0x121c0
leaq 0x220(%rsp), %rdi
callq 0x121c0
jmp 0xee3d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
leaq 0x190(%rsp), %rdi
callq 0x121c0
testb $0x1, 0x18f(%rsp)
jne 0xeb7d
jmp 0xeb8c
movq 0x60(%rsp), %rdi
movl $0x20, %esi
callq 0x6470
jmp 0xeb8e
leaq 0x220(%rsp), %rdi
callq 0x121c0
jmp 0xee4d
movq 0x2b0(%rsp), %rax
movq %rax, 0x50(%rsp)
cmpq $0x0, %rax
je 0xebd6
movq 0x50(%rsp), %rdi
leaq 0x3c981(%rip), %rsi     # 0x4b540
leaq 0x3cffa(%rip), %rdx     # 0x4bbc0
xorl %eax, %eax
movl %eax, %ecx
callq 0x6520
movq %rax, 0x48(%rsp)
jmp 0xebdf
xorl %eax, %eax
movq %rax, 0x48(%rsp)
jmp 0xebdf
movq 0x48(%rsp), %rax
movq %rax, 0x180(%rsp)
cmpq $0x0, 0x180(%rsp)
je 0xecf5
movl $0x28, %edi
callq 0x6460
movq %rax, 0x38(%rsp)
movq %rax, 0x30(%rsp)
movb $0x1, 0x15f(%rsp)
movq 0x180(%rsp), %rsi
addq $0x8, %rsi
leaq 0x160(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x12220
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rsi
movq 0x240(%rsp), %rdx
callq 0x12250
jmp 0xec4e
movb $0x0, 0x15f(%rsp)
leaq 0x160(%rsp), %rdi
callq 0x11ed0
movq 0x30(%rsp), %rax
movq %rax, 0x178(%rsp)
movq 0x180(%rsp), %rdi
addq $0x8, %rdi
callq 0x122d0
movq 0x180(%rsp), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0xec9f
movq 0x28(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq 0x178(%rsp), %rax
movq %rax, 0x2c0(%rsp)
jmp 0xee3d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
leaq 0x160(%rsp), %rdi
callq 0x11ed0
testb $0x1, 0x15f(%rsp)
jne 0xece1
jmp 0xecf0
movq 0x30(%rsp), %rdi
movl $0x28, %esi
callq 0x6470
jmp 0xee4d
movq 0x2b0(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0xed2b
movq 0x20(%rsp), %rdi
leaq 0x3c82c(%rip), %rsi     # 0x4b540
leaq 0x3cebd(%rip), %rdx     # 0x4bbd8
xorl %eax, %eax
movl %eax, %ecx
callq 0x6520
movq %rax, 0x18(%rsp)
jmp 0xed34
xorl %eax, %eax
movq %rax, 0x18(%rsp)
jmp 0xed34
movq 0x18(%rsp), %rax
movq %rax, 0x150(%rsp)
cmpq $0x0, 0x150(%rsp)
je 0xedb2
movl $0x48, %edi
callq 0x6200
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x10(%rsp)
movq 0x2b0(%rsp), %rdx
leaq 0x29b07(%rip), %rsi     # 0x38877
callq 0x17550
jmp 0xed77
movq 0x10(%rsp), %rdi
leaq 0x3c7a5(%rip), %rsi     # 0x4b528
leaq 0x2f16(%rip), %rdx      # 0x11ca0
callq 0x6780
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
callq 0x6320
jmp 0xee4d
movl $0x48, %edi
callq 0x6200
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x8(%rsp)
movups 0x248(%rsp), %xmm0
movaps %xmm0, 0x140(%rsp)
movq 0x140(%rsp), %rdx
movq 0x148(%rsp), %rcx
leaq 0x29a98(%rip), %rsi     # 0x38886
callq 0x17350
jmp 0xedf5
movq 0x8(%rsp), %rdi
leaq 0x3c727(%rip), %rsi     # 0x4b528
leaq 0x2e98(%rip), %rdx      # 0x11ca0
callq 0x6780
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x278(%rsp)
movl %eax, 0x274(%rsp)
callq 0x6320
jmp 0xee4d
movq 0x2b0(%rsp), %rax
movq %rax, 0x2c0(%rsp)
movq 0x2c0(%rsp), %rax
addq $0x2c8, %rsp            # imm = 0x2C8
retq
movq 0x278(%rsp), %rdi
callq 0x67a0
nopw (%rax,%rax)