// File: /workspace/github_cpp_makefile_star2_O2/taurheim[P]AgNES/semanticAnalyzer.cpp
// Function: SemanticAnalyzer::parseNode(ASTNode*)
void SemanticAnalyzer::parseNode(ASTNode * node) {
    switch (node->nodeType) {
        case AST_DECLARATION:
        case AST_FUNCTION:
            {
                VarType varType;
                std::string functionName = "";
                for (auto i = node->children.begin(); i != node->children.end(); i++) {
                    ASTNode * childNode = *i;
                    // Is TypeNode
                    if (i == node->children.begin()) {
                        varType = ((TypeNode *)*i)->varType;
                    } else if(node->nodeType == AST_DECLARATION) {
                        // Is AST_VARDECLARATION 
                        IdentifierNode * idNode = (IdentifierNode *)(*i)->children[0];
                        std::string varName = idNode->name;
                        symbolTable->addVariable(varType, varName);
                    } else if (node->nodeType == AST_FUNCTION && i == node->children.begin() + 1) {
                        // Second child of AST_FUNCTION is an Identifier
                        IdentifierNode * idNode = (IdentifierNode *)(*i);
                        functionName = idNode->name;
                        symbolTable->addFunction(varType, functionName);
                    } else if (node->nodeType == AST_FUNCTION && childNode->nodeType == AST_PARAMETERLIST) {
                        // Open the scope for the body of the function
                        symbolTable->openScope(functionName);
                        parseNode(childNode);
                    } else {
                        parseNode(childNode);
                    }
                }
                break;
            }
        case AST_PARAMETERLIST:
            {
                for (auto i = node->children.begin(); i != node->children.end(); i++) {
                    ASTNode * childNode = *i; // Parameter
                    TypeNode * paramType = (TypeNode*) childNode->children[0];
                    IdentifierNode * paramIdentifier = (IdentifierNode*) childNode->children[1];

                    symbolTable->addParam(paramType->varType, paramIdentifier->name);
                }
                break;
            }
        case AST_FUNCTIONBODY:
            {
                for (auto & n : node->children) {
                    parseNode(n);
                }
                symbolTable->closeScope();
                break;
            }
        case AST_IDENTIFIER:
            {
                IdentifierNode * idNode= (IdentifierNode*) node;
                STEntry * entry = symbolTable->lookup(idNode->name);
                if(entry == nullptr) {
                    std::cout << "Identifier \"" << idNode->name << "\" is undefined." << std::endl;
                }
                break;
            }
        default:
            for (auto & n : node->children) {
                parseNode(n);
            }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movq %rsi, %rbx
movq %rdi, -0x30(%rbp)
movl (%rsi), %eax
leal -0x2(%rax), %ecx
cmpl $0x2, %ecx
jb 0xa7a9
cmpl $0x4, %eax
je 0xa95d
cmpl $0x7, %eax
je 0xa906
cmpl $0x10, %eax
jne 0xa9e1
movq 0x8(%rbx), %r14
movq 0x10(%rbx), %rbx
cmpq %rbx, %r14
je 0xaa00
movq (%r14), %rsi
movq -0x30(%rbp), %rdi
callq 0xa746
addq $0x8, %r14
jmp 0xa78e
leaq 0x5b3c(%rip), %rsi      # 0x102ec
leaq -0x58(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x3110
movq 0x8(%rbx), %r12
leaq -0x58(%rbp), %r15
leaq -0x78(%rbp), %rdi
cmpq 0x10(%rbx), %r12
je 0xa8f8
movq (%r12), %r13
movq 0x8(%rbx), %rax
cmpq %rax, %r12
je 0xa849
movl (%rbx), %ecx
cmpl $0x2, %ecx
je 0xa855
cmpl $0x3, %ecx
jne 0xa89a
movq 0x8(%r13), %rax
movq (%rax), %rsi
addq $0x20, %rsi
leaq -0x98(%rbp), %r15
movq %r15, %rdi
callq 0x32e0
movq -0x30(%rbp), %rax
movq 0x8(%rax), %r13
leaq -0x118(%rbp), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x32e0
movq %r13, %rdi
movl -0x34(%rbp), %esi
movq %r14, %rdx
callq 0xb502
movq %r14, %rdi
callq 0x3140
leaq -0x98(%rbp), %rdi
jmp 0xa8e2
movl 0x20(%r13), %eax
movl %eax, -0x34(%rbp)
jmp 0xa8e7
addq $0x8, %rax
cmpq %rax, %r12
je 0xa8a8
cmpl $0x7, (%r13)
jne 0xa89a
movq -0x30(%rbp), %rax
movq %r15, %rsi
movq 0x8(%rax), %r15
callq 0x32e0
movq %r15, %rdi
leaq -0x78(%rbp), %r15
movq %r15, %rsi
callq 0xb708
movq %r15, %rdi
callq 0x3140
movq -0x30(%rbp), %rdi
movq %r13, %rsi
callq 0xa746
jmp 0xa8e7
movq -0x30(%rbp), %rdi
movq %r13, %rsi
callq 0xa746
jmp 0xa8e7
addq $0x20, %r13
movq %r15, %rdi
movq %r13, %rsi
callq 0x3180
movq %r15, %rsi
leaq -0xf8(%rbp), %r15
movq -0x30(%rbp), %rax
movq 0x8(%rax), %r13
movq %r15, %rdi
callq 0x32e0
movq %r13, %rdi
movl -0x34(%rbp), %esi
movq %r15, %rdx
callq 0xb654
movq %r15, %rdi
callq 0x3140
addq $0x8, %r12
leaq -0x78(%rbp), %rdi
leaq -0x58(%rbp), %r15
jmp 0xa7cc
leaq -0x58(%rbp), %rdi
callq 0x3140
jmp 0xa9cf
movq 0x8(%rbx), %r14
leaq -0xd8(%rbp), %r15
cmpq 0x10(%rbx), %r14
je 0xa9cf
movq (%r14), %rax
movq 0x8(%rax), %rax
movq (%rax), %rcx
movq 0x8(%rax), %rsi
movq -0x30(%rbp), %rax
movq 0x8(%rax), %r12
movl 0x20(%rcx), %r13d
addq $0x20, %rsi
movq %r15, %rdi
callq 0x32e0
movq %r12, %rdi
movl %r13d, %esi
movq %r15, %rdx
callq 0xb6ae
movq %r15, %rdi
callq 0x3140
addq $0x8, %r14
jmp 0xa911
movq -0x30(%rbp), %rax
movq 0x8(%rax), %r14
addq $0x20, %rbx
leaq -0xb8(%rbp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x32e0
movq %r14, %rdi
movq %r15, %rsi
callq 0xb7ac
movq %rax, %r14
leaq -0xb8(%rbp), %rdi
callq 0x3140
testq %r14, %r14
jne 0xa9cf
movq 0xd627(%rip), %rdi      # 0x17fc8
leaq 0x5c96(%rip), %rsi      # 0x1063e
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3210
leaq 0x5c8c(%rip), %rsi      # 0x1064b
movq %rax, %rdi
callq 0x3230
movq %rax, %rdi
callq 0x3150
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%rbx), %r14
movq 0x10(%rbx), %rbx
cmpq %rbx, %r14
je 0xa9cf
movq (%r14), %rsi
movq -0x30(%rbp), %rdi
callq 0xa746
addq $0x8, %r14
jmp 0xa9e9
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xb79a
movq %rax, %rbx
leaq -0xb8(%rbp), %rdi
jmp 0xaa7d
movq %rax, %rbx
jmp 0xaa82
movq %rax, %rbx
leaq -0x78(%rbp), %rdi
jmp 0xaa63
movq %rax, %rbx
leaq -0xf8(%rbp), %rdi
jmp 0xaa63
jmp 0xaa6a
jmp 0xaa6a
movq %rax, %rbx
leaq -0x118(%rbp), %rdi
callq 0x3140
jmp 0xaa5c
movq %rax, %rbx
leaq -0x98(%rbp), %rdi
callq 0x3140
jmp 0xaa6d
movq %rax, %rbx
leaq -0x58(%rbp), %rdi
jmp 0xaa7d
movq %rax, %rbx
leaq -0xd8(%rbp), %rdi
callq 0x3140
movq %rbx, %rdi
callq 0x33e0