// File: WayfireWM[P]wf-utils/wayfire/parser/lambda_rule_parser.cpp
// Function: wf::lambda_rule_parser_t::parse(wf::lexer_t&, std::function<bool ()>, std::function<bool ()>)
std::shared_ptr<lambda_rule_t> lambda_rule_parser_t::parse(lexer_t &lexer, lambda_t if_lambda, lambda_t else_lambda)
{
    std::string signal;
    std::shared_ptr<condition_t> condition;

    try
    {
        // Expect the first symbol to be the 'on' keyword.
        auto symbol = lexer.parse_symbol();
        if ((symbol.type != symbol_t::type_t::KEYWORD) || (get_string(symbol.value) != "on"))
        {
            throw std::runtime_error("Lambda rule parser error. Expected 'on' keyword.");
        }

        // Expect a signal next.
        symbol = lexer.parse_symbol();
        if (symbol.type != symbol_t::type_t::SIGNAL)
        {
            throw std::runtime_error("Lambda rule parser error. Expected signal.");
        }
        signal = get_string(symbol.value);

        // Expect the 'if' keyword next.
        symbol = lexer.parse_symbol();
        if ((symbol.type != symbol_t::type_t::KEYWORD) || (get_string(symbol.value) != "if"))
        {
            throw std::runtime_error("Lambda rule parser error. Expected 'if' keyword.");
        }

        // Delegate to logical condition parser.
        condition = condition_parser_t().parse(lexer);

        // Expect the lexer to be at the end - 1.
        lexer.parse_symbol();
        symbol = lexer.parse_symbol();
        if (symbol.type != symbol_t::type_t::END)
        {
            std::string error = "Lambda rule parser error. Unexpected symbol: ";
            error.append(to_string(symbol));
            throw std::runtime_error(error);
        }
    }
    catch (std::runtime_error &e)
    {
        std::cout << "Malformed input:" << std::endl;
        std::cout << lexer.text() << std::endl;
        std::string pad;
        auto pos = lexer.current_symbol_position();
        for (std::size_t i = 0; i < pos; ++i)
        {
            pad.append(" ");
        }
        pad.append("^ ");
        std::cout << pad << e.what() << std::endl;
    }

    auto rule = std::make_shared<lambda_rule_t>(signal, condition);
    if (rule != nullptr)
    {
        rule->setIfLambda(if_lambda);
        rule->setElseLambda(else_lambda);
    }
    return rule;
}

// Assembly:
subq $0x388, %rsp            # imm = 0x388
movq %r8, 0x88(%rsp)
movq %rcx, 0x90(%rsp)
movq %rdi, 0x98(%rsp)
movq %rdi, %rax
movq %rax, 0xa0(%rsp)
movq %rdi, 0x380(%rsp)
movq %rsi, 0x378(%rsp)
movq %rdx, 0x370(%rsp)
movq %rcx, 0x368(%rsp)
movq %r8, 0x360(%rsp)
leaq 0x340(%rsp), %rdi
callq 0x6430
leaq 0x330(%rsp), %rdi
callq 0x9d50
movq 0x370(%rsp), %rsi
leaq 0x300(%rsp), %rdi
callq 0xc270
jmp 0x19b23
movl 0x300(%rsp), %ecx
movb $0x0, 0x2cf(%rsp)
movb $0x1, %al
cmpl $0x4, %ecx
movb %al, 0x87(%rsp)
jne 0x19b8c
leaq 0x308(%rsp), %rsi
leaq 0x2d0(%rsp), %rdi
callq 0x1bea0
jmp 0x19b57
movb $0x1, 0x2cf(%rsp)
leaq 0x568e(%rip), %rsi      # 0x1f1f4
leaq 0x2d0(%rsp), %rdi
callq 0x15030
movb %al, 0x86(%rsp)
jmp 0x19b7c
movb 0x86(%rsp), %al
movb %al, 0x87(%rsp)
jmp 0x19b8c
movb 0x87(%rsp), %al
movb %al, 0x85(%rsp)
testb $0x1, 0x2cf(%rsp)
jne 0x19ba6
jmp 0x19bb3
leaq 0x2d0(%rsp), %rdi
callq 0x61d0
movb 0x85(%rsp), %al
testb $0x1, %al
jne 0x19bc3
jmp 0x19c8a
movl $0x10, %edi
callq 0x6170
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x78(%rsp)
leaq 0x5e84(%rip), %rsi      # 0x1fa63
callq 0x6100
jmp 0x19be6
movq 0x78(%rsp), %rdi
movq 0x153fe(%rip), %rsi     # 0x2eff0
movq 0x153af(%rip), %rdx     # 0x2efa8
callq 0x64d0
jmp 0x1a4c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
jmp 0x1a112
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
jmp 0x1a105
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
testb $0x1, 0x2cf(%rsp)
jne 0x19c55
jmp 0x19c62
leaq 0x2d0(%rsp), %rdi
callq 0x61d0
jmp 0x1a105
movq 0x78(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
callq 0x6240
jmp 0x1a105
movq 0x370(%rsp), %rsi
leaq 0x298(%rsp), %rdi
callq 0xc270
jmp 0x19ca1
leaq 0x300(%rsp), %rdi
leaq 0x298(%rsp), %rsi
callq 0x12fc0
leaq 0x298(%rsp), %rdi
callq 0xc5f0
cmpl $0x6, 0x300(%rsp)
je 0x19d30
movl $0x10, %edi
callq 0x6170
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x70(%rsp)
leaq 0x5dab(%rip), %rsi      # 0x1fa94
callq 0x6100
jmp 0x19cf0
movq 0x70(%rsp), %rdi
movq 0x152f4(%rip), %rsi     # 0x2eff0
movq 0x152a5(%rip), %rdx     # 0x2efa8
callq 0x64d0
jmp 0x1a4c0
movq 0x70(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
callq 0x6240
jmp 0x1a105
leaq 0x308(%rsp), %rsi
leaq 0x278(%rsp), %rdi
callq 0x1bea0
jmp 0x19d47
leaq 0x340(%rsp), %rdi
leaq 0x278(%rsp), %rsi
movq %rsi, 0x68(%rsp)
callq 0x63d0
movq 0x68(%rsp), %rdi
callq 0x61d0
movq 0x370(%rsp), %rsi
leaq 0x248(%rsp), %rdi
callq 0xc270
jmp 0x19d82
leaq 0x300(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x12fc0
leaq 0x248(%rsp), %rdi
callq 0xc5f0
movl 0x300(%rsp), %ecx
movb $0x0, 0x227(%rsp)
movb $0x1, %al
cmpl $0x4, %ecx
movb %al, 0x67(%rsp)
jne 0x19e01
leaq 0x308(%rsp), %rsi
leaq 0x228(%rsp), %rdi
callq 0x1bea0
jmp 0x19dd5
movb $0x1, 0x227(%rsp)
leaq 0x5403(%rip), %rsi      # 0x1f1e7
leaq 0x228(%rsp), %rdi
callq 0x15030
movb %al, 0x66(%rsp)
jmp 0x19df7
movb 0x66(%rsp), %al
movb %al, 0x67(%rsp)
jmp 0x19e01
movb 0x67(%rsp), %al
movb %al, 0x65(%rsp)
testb $0x1, 0x227(%rsp)
jne 0x19e15
jmp 0x19e22
leaq 0x228(%rsp), %rdi
callq 0x61d0
movb 0x65(%rsp), %al
testb $0x1, %al
jne 0x19e2f
jmp 0x19ec4
movl $0x10, %edi
callq 0x6170
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x58(%rsp)
leaq 0x5c74(%rip), %rsi      # 0x1fabf
callq 0x6100
jmp 0x19e52
movq 0x58(%rsp), %rdi
movq 0x15192(%rip), %rsi     # 0x2eff0
movq 0x15143(%rip), %rdx     # 0x2efa8
callq 0x64d0
jmp 0x1a4c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
testb $0x1, 0x227(%rsp)
jne 0x19e8f
jmp 0x19e9c
leaq 0x228(%rsp), %rdi
callq 0x61d0
jmp 0x1a105
movq 0x58(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
callq 0x6240
jmp 0x1a105
leaq 0x1d0(%rsp), %rdi
callq 0x13e40
jmp 0x19ed3
movq 0x370(%rsp), %rdx
leaq 0x210(%rsp), %rdi
leaq 0x1d0(%rsp), %rsi
callq 0x13e90
jmp 0x19ef2
leaq 0x330(%rsp), %rdi
leaq 0x210(%rsp), %rsi
movq %rsi, 0x50(%rsp)
callq 0x1a5b0
movq 0x50(%rsp), %rdi
callq 0x9db0
leaq 0x1d0(%rsp), %rdi
callq 0x1a5e0
movq 0x370(%rsp), %rsi
leaq 0x1a0(%rsp), %rdi
callq 0xc270
jmp 0x19f3a
leaq 0x1a0(%rsp), %rdi
callq 0xc5f0
movq 0x370(%rsp), %rsi
leaq 0x170(%rsp), %rdi
callq 0xc270
jmp 0x19f5e
leaq 0x300(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x12fc0
leaq 0x170(%rsp), %rdi
callq 0xc5f0
cmpl $0x0, 0x300(%rsp)
je 0x1a0f3
leaq 0x14f(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x6500
movq 0x48(%rsp), %rdx
leaq 0x5b44(%rip), %rsi      # 0x1faf0
leaq 0x150(%rsp), %rdi
callq 0x8280
jmp 0x19fbb
leaq 0x14f(%rsp), %rdi
callq 0x6360
leaq 0x128(%rsp), %rdi
leaq 0x300(%rsp), %rsi
callq 0x12840
jmp 0x19fdf
leaq 0x150(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x6560
jmp 0x19ff6
leaq 0x128(%rsp), %rdi
callq 0x61d0
movl $0x10, %edi
callq 0x6170
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x40(%rsp)
leaq 0x150(%rsp), %rsi
callq 0x64a0
jmp 0x1a027
movq 0x40(%rsp), %rdi
movq 0x14fbd(%rip), %rsi     # 0x2eff0
movq 0x14f6e(%rip), %rdx     # 0x2efa8
callq 0x64d0
jmp 0x1a4c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
leaq 0x1d0(%rsp), %rdi
callq 0x1a5e0
jmp 0x1a105
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
leaq 0x14f(%rsp), %rdi
callq 0x6360
jmp 0x1a105
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
jmp 0x1a0e4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
leaq 0x128(%rsp), %rdi
callq 0x61d0
jmp 0x1a0e4
movq 0x40(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
callq 0x6240
leaq 0x150(%rsp), %rdi
callq 0x61d0
jmp 0x1a105
leaq 0x300(%rsp), %rdi
callq 0xc5f0
jmp 0x1a2df
leaq 0x300(%rsp), %rdi
callq 0xc5f0
movl 0x2f4(%rsp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x1a491
movq 0x2f8(%rsp), %rdi
callq 0x6110
movq %rax, 0x120(%rsp)
movq 0x14e7e(%rip), %rdi     # 0x2efc0
leaq 0x59d5(%rip), %rsi      # 0x1fb1e
callq 0x62f0
movq %rax, 0x38(%rsp)
jmp 0x1a155
movq 0x38(%rsp), %rdi
movq 0x14e27(%rip), %rsi     # 0x2ef88
callq 0x6340
jmp 0x1a168
movq 0x370(%rsp), %rdi
callq 0xcc00
movq %rax, 0x30(%rsp)
jmp 0x1a17c
movq 0x30(%rsp), %rsi
movq 0x14e38(%rip), %rdi     # 0x2efc0
callq 0x62b0
movq %rax, 0x28(%rsp)
jmp 0x1a194
movq 0x28(%rsp), %rdi
movq 0x14de8(%rip), %rsi     # 0x2ef88
callq 0x6340
jmp 0x1a1a7
leaq 0x100(%rsp), %rdi
callq 0x6430
movq 0x370(%rsp), %rdi
callq 0xcc10
movq %rax, 0x20(%rsp)
jmp 0x1a1c8
movq 0x20(%rsp), %rax
movq %rax, 0xf8(%rsp)
movq $0x0, 0xf0(%rsp)
movq 0xf0(%rsp), %rax
cmpq 0xf8(%rsp), %rax
jae 0x1a260
leaq 0x4e70(%rip), %rsi      # 0x1f06a
leaq 0x100(%rsp), %rdi
callq 0x6540
jmp 0x1a209
jmp 0x1a20b
movq 0xf0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xf0(%rsp)
jmp 0x1a1e1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
jmp 0x1a3d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
leaq 0x100(%rsp), %rdi
callq 0x61d0
jmp 0x1a3d0
leaq 0x58c8(%rip), %rsi      # 0x1fb2f
leaq 0x100(%rsp), %rdi
callq 0x6540
jmp 0x1a276
movq 0x14d43(%rip), %rdi     # 0x2efc0
leaq 0x100(%rsp), %rsi
callq 0x62b0
movq %rax, 0x18(%rsp)
jmp 0x1a291
movq 0x120(%rsp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x62f0
movq %rax, 0x10(%rsp)
jmp 0x1a2b6
movq 0x10(%rsp), %rdi
movq 0x14cc6(%rip), %rsi     # 0x2ef88
callq 0x6340
jmp 0x1a2c9
leaq 0x100(%rsp), %rdi
callq 0x61d0
callq 0x64b0
jmp 0x1a2dd
jmp 0x1a2df
movq 0x98(%rsp), %rdi
movb $0x0, 0xef(%rsp)
leaq 0x340(%rsp), %rsi
leaq 0x330(%rsp), %rdx
callq 0x1a610
jmp 0x1a306
movq 0x98(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1a690
testb $0x1, %al
jne 0x1a320
jmp 0x1a43b
movq 0x98(%rsp), %rdi
callq 0x1a6b0
movq 0x90(%rsp), %rsi
movq %rax, 0x8(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x1a4c0
jmp 0x1a349
movq 0x8(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x1b350
jmp 0x1a35d
leaq 0xc8(%rsp), %rdi
callq 0x1a570
movq 0x98(%rsp), %rdi
callq 0x1a6b0
movq 0x88(%rsp), %rsi
movq %rax, (%rsp)
leaq 0xa8(%rsp), %rdi
callq 0x1a4c0
jmp 0x1a392
movq (%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x1b3d0
jmp 0x1a3a5
leaq 0xa8(%rsp), %rdi
callq 0x1a570
jmp 0x1a43b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
jmp 0x1a491
callq 0x64b0
jmp 0x1a3d7
jmp 0x1a491
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
jmp 0x1a484
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x1a570
jmp 0x1a484
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2f8(%rsp)
movl %eax, 0x2f4(%rsp)
leaq 0xa8(%rsp), %rdi
callq 0x1a570
jmp 0x1a484
movb $0x1, 0xef(%rsp)
testb $0x1, 0xef(%rsp)
jne 0x1a45a
movq 0x98(%rsp), %rdi
callq 0x1a6c0
leaq 0x330(%rsp), %rdi
callq 0x9db0
leaq 0x340(%rsp), %rdi
callq 0x61d0
movq 0xa0(%rsp), %rax
addq $0x388, %rsp            # imm = 0x388
retq
movq 0x98(%rsp), %rdi
callq 0x1a6c0
leaq 0x330(%rsp), %rdi
callq 0x9db0
leaq 0x340(%rsp), %rdi
callq 0x61d0
movq 0x2f8(%rsp), %rdi
callq 0x64f0
movq %rax, %rdi
callq 0x8340