// File: /workspace/github_cpp_makefile_star2_O2/johan-bjareholt[P]lua-compiler/src/convert.cc
// Function: outMainBlock(std::ostream&, BBlock&)
void outMainBlock(std::ostream& ss, BBlock& startblock){
    std::stringstream headss;
    std::stringstream mainss;
    std::stringstream bodyss;
    
    // Standard functions
    headss << "// Standard functions" << std::endl;
	headss << "#include <stdlib.h>" << std::endl;
	headss << "#include <stdio.h>" << std::endl;
    headss << "long io_write(const char* msg){printf(\"%s\", msg); return 0;}" << std::endl;
    headss << "long io_write_i(long num){ printf(\"%ld\", num); return 0;}" << std::endl;
    headss << "long print(const char* msg){ printf(\"%s\\n\", msg); return 0;}" << std::endl;
    headss << "long print_i(long num){ printf(\"%ld\\n\", num);; return 0;}" << std::endl;
    headss << "long io_read(const char* msg){ long num; scanf(\"%ld\", &num); return num; }" << std::endl;
	
    mainss << "int main(){" << std::endl;

	std::set<std::string> inputSymbols = std::set<std::string>();
	
    std::set<std::string> outputSymbols = std::set<std::string>();

	bodyss << "    asm (" << std::endl;
    bodyss << "    // main" << std::endl;
    // Output global
	outBlock(startblock, bodyss, outputSymbols, inputSymbols, true, false);
    // Output functions
    for (auto funcentry : funcdefs){
        std::string funcname = funcentry.first;
        BBlock* funcblock = funcentry.second;
        outFunctionBlock(funcname, *funcblock, bodyss, outputSymbols, inputSymbols);
    }
    bodyss << std::endl;
    bodyss << pre_in << "label_end:" << post_in;
    bodyss << pre_in << "movq $0, %%rdi" << post_in;
    bodyss << pre_in << "call exit" << post_in;
    
    // Define storage variables
    headss << std::endl;
    headss << "// Variables" << std::endl;
    for (auto var : vars2){
        std::string name = var.first;
        std::string val = var.second.second;
        int type = var.second.first;
        switch (type){
            case VT_STRING:
                headss << "const char* " << name << " = " << val << ";"<< std::endl;
                break;
            case VT_INT:
            case VT_UNKNOWN:
	            headss << "long " << name << ";" << std::endl;
                break;
            case VT_POINTER:
                headss << "void* " << name << ";" << std::endl;
                break;
            case VT_FUNCTION:
            case VT_LABEL:
                break;
            default:
                std::cout << "Unknown vartype" << std::endl;
                exit(1);
                break;
        }
    }
    headss << std::endl;

    // Strings
    //mainss << "    // Strings decl" << std::endl;
    //for (std::pair<int, std::string> strp : strings){
    //    mainss << "    const char* " << "_s" << strp.first << " = " << strp.second << ";"<< std::endl;
    //}

	mainss << bodyss.str();
	mainss << "    : // Output symbols" << std::endl;
	for (auto iter = outputSymbols.begin(); iter!=outputSymbols.end(); iter++){
        if (inputSymbols.find(*iter) != inputSymbols.end()){
            inputSymbols.erase(*iter);
		    mainss << "      [" << *iter << "] \"+m\" (" << *iter << ")";
        }
        else
		    mainss << "      [" << *iter << "] \"=m\" (" << *iter << ")";
		if (std::next(iter) != outputSymbols.end())
			mainss << ",";
		mainss << std::endl;
	}
	mainss << "    : // Input symbols" << std::endl;
	for (auto iter = inputSymbols.begin(); iter!=inputSymbols.end(); iter++){
		mainss << "      [" << *iter << "] \"m\" (" << *iter << ")";
		if (std::next(iter) != inputSymbols.end())
			mainss << ",";
		mainss << std::endl;
	}

    mainss << "    : // Clobbers" << std::endl;
    mainss << "      \"cc\", \"rax\", \"rbx\", \"rcx\", \"rdx\", \"rsi\", \"rdi\", \"rsp\"" << std::endl;
    //mainss << "      ,\"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r13\", \"r14\", \"r15\"" << std::endl;
	mainss << "    );" << std::endl;
	mainss << "    return 0;" << std::endl;
	mainss << "}" << std::endl;

    ss << headss.str();
    ss << mainss.str();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x5d8, %rsp            # imm = 0x5D8
movq %rsi, %r12
movq %rdi, -0x30(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0x3180
leaq -0x470(%rbp), %rdi
callq 0x3180
leaq -0x5f8(%rbp), %rdi
callq 0x3180
leaq -0x2d8(%rbp), %rdi
leaq 0xa002(%rip), %rsi      # 0x1231d
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0xa004(%rip), %rsi      # 0x12333
leaq -0x2d8(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0x9ffd(%rip), %rsi      # 0x12347
leaq -0x2d8(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0x9ff5(%rip), %rsi      # 0x1235a
leaq -0x2d8(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0xa017(%rip), %rsi      # 0x12397
leaq -0x2d8(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0xa036(%rip), %rsi      # 0x123d1
leaq -0x2d8(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0xa058(%rip), %rsi      # 0x1240e
leaq -0x2d8(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0xa077(%rip), %rsi      # 0x12448
leaq -0x2d8(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq -0x460(%rbp), %rdi
leaq 0xa0a0(%rip), %rsi      # 0x12493
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq -0xa8(%rbp), %rax
xorps %xmm0, %xmm0
movaps %xmm0, -0x8(%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq -0xd8(%rbp), %rax
andq $0x0, 0x8(%rax)
movaps %xmm0, -0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq -0x5e8(%rbp), %rdi
leaq 0xa054(%rip), %rsi      # 0x1249f
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0xa04a(%rip), %rsi      # 0x124a9
leaq -0x5e8(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
andl $0x0, (%rsp)
leaq -0x160(%rbp), %rdi
leaq -0xe0(%rbp), %rcx
leaq -0xb0(%rbp), %r8
pushq $0x1
popq %r9
movq %r12, %rsi
leaq -0x5e8(%rbp), %rdx
callq 0x8b42
leaq -0x160(%rbp), %rdi
callq 0x3448
leaq 0x13e3e(%rip), %rax     # 0x1c2f0
movq 0x18(%rax), %r14
addq $0x8, %rax
movq %rax, -0x80(%rbp)
leaq -0x78(%rbp), %rbx
leaq -0x140(%rbp), %r15
cmpq -0x80(%rbp), %r14
je 0x8545
leaq 0x20(%r14), %rsi
movq %rbx, %rdi
callq 0x466e
leaq -0x100(%rbp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x32f0
movq -0x58(%rbp), %r13
movq %r15, %rdi
movq %r12, %rsi
callq 0x32f0
movq %r15, %rdi
movq %r13, %rsi
leaq -0x5e8(%rbp), %rdx
leaq -0xe0(%rbp), %rcx
leaq -0xb0(%rbp), %r8
callq 0x8fbe
movq %r15, %rdi
callq 0x3448
leaq -0x100(%rbp), %rdi
callq 0x3448
movq %rbx, %rdi
callq 0x3448
movq %r14, %rdi
callq 0x3170
movq %rax, %r14
jmp 0x84c9
leaq -0x5e8(%rbp), %rdi
callq 0x3100
leaq 0x13e08(%rip), %rsi     # 0x1c360
leaq -0x5e8(%rbp), %rdi
callq 0x31d0
leaq 0x9f4a(%rip), %rsi      # 0x124b5
movq %rax, %rdi
callq 0x31f0
leaq 0x13e06(%rip), %rsi     # 0x1c380
movq %rax, %rdi
callq 0x31d0
leaq 0x13dd7(%rip), %rsi     # 0x1c360
leaq -0x5e8(%rbp), %rdi
callq 0x31d0
leaq 0x9f24(%rip), %rsi      # 0x124c0
movq %rax, %rdi
callq 0x31f0
leaq 0x13dd5(%rip), %rsi     # 0x1c380
movq %rax, %rdi
callq 0x31d0
leaq 0x13da6(%rip), %rsi     # 0x1c360
leaq -0x5e8(%rbp), %rdi
callq 0x31d0
leaq 0x9f02(%rip), %rsi      # 0x124cf
movq %rax, %rdi
callq 0x31f0
leaq 0x13da4(%rip), %rsi     # 0x1c380
movq %rax, %rdi
callq 0x31d0
leaq -0x2d8(%rbp), %rdi
callq 0x3100
leaq 0x9ee2(%rip), %rsi      # 0x124d9
leaq -0x2d8(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
movq 0x13da6(%rip), %rbx     # 0x1c3b8
leaq -0x78(%rbp), %r15
leaq -0x120(%rbp), %r13
leaq 0x9c88(%rip), %r14      # 0x122ac
leaq -0x100(%rbp), %r12
leaq 0x13d76(%rip), %rax     # 0x1c3a8
cmpq %rax, %rbx
je 0x870a
leaq 0x20(%rbx), %rsi
movq %r15, %rdi
callq 0xa324
movq %r12, %rdi
movq %r15, %rsi
callq 0x32f0
movq %r13, %rdi
leaq -0x50(%rbp), %rsi
callq 0x32f0
movl -0x58(%rbp), %eax
cmpq $0x5, %rax
ja 0x8a3b
movslq (%r14,%rax,4), %rax
addq %r14, %rax
leaq 0x9e7e(%rip), %rsi      # 0x124f7
jmpq *%rax
leaq -0x2d8(%rbp), %rdi
leaq 0x9e5d(%rip), %rsi      # 0x124e6
callq 0x31f0
movq %rax, %rdi
movq %r12, %rsi
callq 0x31d0
movq %rax, %rdi
leaq 0x9e50(%rip), %rsi      # 0x124f3
callq 0x31f0
movq %r13, %rsi
jmp 0x86c3
leaq 0x9e49(%rip), %rsi      # 0x124fd
leaq -0x2d8(%rbp), %rdi
callq 0x31f0
movq %r12, %rsi
movq %rax, %rdi
callq 0x31d0
movq %rax, %rdi
leaq 0x99fc(%rip), %rsi      # 0x120d1
callq 0x31f0
movq %rax, %rdi
callq 0x3100
movq %r13, %rdi
callq 0x3448
movq %r12, %rdi
callq 0x3448
movq %r15, %rdi
callq 0xa35e
movq %rbx, %rdi
callq 0x3170
movq %rax, %rbx
jmp 0x862b
leaq -0x2d8(%rbp), %rdi
callq 0x3100
leaq -0x460(%rbp), %rbx
leaq -0x5e0(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x3380
leaq -0x78(%rbp), %rsi
movq %rbx, %rdi
callq 0x31d0
leaq -0x78(%rbp), %rdi
callq 0x3448
leaq 0x9dcb(%rip), %rsi      # 0x12514
movq %rbx, %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
movq -0xc8(%rbp), %r12
leaq -0xb0(%rbp), %rbx
leaq 0xb5e1(%rip), %r13      # 0x13d4f
pushq $0x1
popq %r15
leaq -0xd8(%rbp), %rax
cmpq %rax, %r12
je 0x8859
leaq 0x20(%r12), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0xaaa0
leaq -0xa8(%rbp), %rcx
cmpq %rcx, %rax
je 0x87d0
movq %rbx, %rdi
movq %r14, %rsi
callq 0xab2a
leaq -0x460(%rbp), %rdi
leaq 0x9d75(%rip), %rsi      # 0x1252c
callq 0x31f0
movq %rax, %rdi
movq %r14, %rsi
callq 0x31d0
leaq 0x9d66(%rip), %rsi      # 0x12534
jmp 0x87f5
leaq -0x460(%rbp), %rdi
leaq 0x9d4e(%rip), %rsi      # 0x1252c
callq 0x31f0
movq %rax, %rdi
movq %r14, %rsi
callq 0x31d0
leaq 0x9d48(%rip), %rsi      # 0x1253d
movq %rax, %rdi
callq 0x31f0
movq %rax, %rdi
movq %r14, %rsi
callq 0x31d0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31f0
movq %r12, %rdi
movq %r15, %rsi
callq 0xa37e
leaq -0xd8(%rbp), %rcx
cmpq %rcx, %rax
je 0x883d
leaq -0x460(%rbp), %rdi
leaq 0x9d0e(%rip), %rsi      # 0x12546
callq 0x31f0
leaq -0x460(%rbp), %rdi
callq 0x3100
movq %r12, %rdi
callq 0x3250
movq %rax, %r12
jmp 0x8772
leaq 0x9ce8(%rip), %rsi      # 0x12548
leaq -0x460(%rbp), %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
movq -0x98(%rbp), %r12
leaq 0x9cdd(%rip), %r15      # 0x1255f
leaq 0xb4c6(%rip), %r13      # 0x13d4f
pushq $0x1
popq %r14
leaq -0xa8(%rbp), %rax
cmpq %rax, %r12
je 0x8927
leaq -0x460(%rbp), %rdi
leaq 0x9c81(%rip), %rsi      # 0x1252c
callq 0x31f0
leaq 0x20(%r12), %rbx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x31d0
movq %rax, %rdi
movq %r15, %rsi
callq 0x31f0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x31d0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31f0
movq %r12, %rdi
movq %r14, %rsi
callq 0xa37e
leaq -0xa8(%rbp), %rcx
cmpq %rcx, %rax
je 0x890b
leaq -0x460(%rbp), %rdi
leaq 0x9c40(%rip), %rsi      # 0x12546
callq 0x31f0
leaq -0x460(%rbp), %rdi
callq 0x3100
movq %r12, %rdi
callq 0x3250
movq %rax, %r12
jmp 0x888d
leaq 0x9c39(%rip), %rsi      # 0x12567
leaq -0x460(%rbp), %rbx
movq %rbx, %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0x9c2d(%rip), %rsi      # 0x12579
movq %rbx, %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0x9c52(%rip), %rsi      # 0x125b5
movq %rbx, %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0x9c42(%rip), %rsi      # 0x125bc
movq %rbx, %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq 0x9b00(%rip), %rsi      # 0x12491
movq %rbx, %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x3100
leaq -0x2d0(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x3380
leaq -0x78(%rbp), %rsi
movq -0x30(%rbp), %rdi
callq 0x31d0
leaq -0x78(%rbp), %rdi
callq 0x3448
leaq -0x458(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x3380
leaq -0x78(%rbp), %rsi
movq -0x30(%rbp), %rdi
callq 0x31d0
leaq -0x78(%rbp), %rdi
callq 0x3448
leaq -0xe0(%rbp), %rdi
callq 0xa94a
leaq -0xb0(%rbp), %rdi
callq 0xa94a
leaq -0x5f8(%rbp), %rdi
callq 0x3190
leaq -0x470(%rbp), %rdi
callq 0x3190
leaq -0x2e8(%rbp), %rdi
callq 0x3190
addq $0x5d8, %rsp            # imm = 0x5D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x13586(%rip), %rdi     # 0x1bfc8
leaq 0x9abb(%rip), %rsi      # 0x12504
callq 0x31f0
movq %rax, %rdi
callq 0x3100
pushq $0x1
popq %rdi
callq 0x32a0
jmp 0x8aa1
jmp 0x8afb
jmp 0x8aa1
jmp 0x8afb
jmp 0x8aa1
jmp 0x8afb
movq %rax, %rbx
jmp 0x8b22
movq %rax, %rbx
jmp 0x8b2e
jmp 0x8ad3
movq %rax, %rbx
jmp 0x8b16
jmp 0x8afb
jmp 0x8afb
jmp 0x8afb
jmp 0x8afb
movq %rax, %rbx
jmp 0x8aee
movq %rax, %rbx
jmp 0x8ae2
jmp 0x8afb
movq %rax, %rbx
jmp 0x8ac6
movq %rax, %rbx
jmp 0x8aba
movq %rax, %rbx
leaq -0x140(%rbp), %rdi
callq 0x3448
leaq -0x100(%rbp), %rdi
callq 0x3448
leaq -0x78(%rbp), %rdi
callq 0x3448
jmp 0x8afe
jmp 0x8afb
movq %rax, %rbx
leaq -0x120(%rbp), %rdi
callq 0x3448
leaq -0x100(%rbp), %rdi
callq 0x3448
leaq -0x78(%rbp), %rdi
callq 0xa35e
jmp 0x8afe
jmp 0x8afb
movq %rax, %rbx
leaq -0xe0(%rbp), %rdi
callq 0xa94a
leaq -0xb0(%rbp), %rdi
callq 0xa94a
leaq -0x5f8(%rbp), %rdi
callq 0x3190
leaq -0x470(%rbp), %rdi
callq 0x3190
leaq -0x2e8(%rbp), %rdi
callq 0x3190
movq %rbx, %rdi
callq 0x33f0