// File: /workspace/github_c_makefile_star2_O2/creationix[P]color-control/src/compile.c
// Function: main
int main() {

  mpc_parser_t *State  = mpc_new("statement");
  mpc_parser_t *Ident  = mpc_new("ident");
  mpc_parser_t *Number  = mpc_new("number");
  mpc_parser_t *Hex  = mpc_new("hex");
  mpc_parser_t *Dec  = mpc_new("decimal");
  mpc_parser_t *Bool  = mpc_new("boolean");
  mpc_parser_t *For  = mpc_new("for");
  mpc_parser_t *Range  = mpc_new("range");
  mpc_parser_t *By  = mpc_new("by");
  mpc_parser_t *If  = mpc_new("if");
  mpc_parser_t *Assign  = mpc_new("assign");
  mpc_parser_t *Expr  = mpc_new("expression");
  mpc_parser_t *Call  = mpc_new("call");
  mpc_parser_t *Not  = mpc_new("not");
  mpc_parser_t *Or  = mpc_new("or");
  mpc_parser_t *And  = mpc_new("and");
  mpc_parser_t *Equal  = mpc_new("equality");
  mpc_parser_t *Comp  = mpc_new("comparison");
  mpc_parser_t *Sum  = mpc_new("sum");
  mpc_parser_t *Prod  = mpc_new("product");
  mpc_parser_t *Value = mpc_new("value");
  mpc_parser_t *Block = mpc_new("block");
  mpc_parser_t *Prog = mpc_new("program");

  mpc_err_t* err = mpca_lang(MPCA_LANG_DEFAULT,
    "statement: <for> | <if> | <assign> | <expression>;"
    "for : \"for\" <ident> \"in\" <number> <range>? <by>? <block>;"
    "range: /\\.\\.\\.?/ <number>;"
    "by: \"by\" <number>;"
    "if : \"if\" <expression> <block>;"
    "assign : <ident> '=' <expression>;"
    "expression: <or>;"
    "ident: /[a-zA-Z_][a-zA-Z_0-9]*/;"
    "number: <boolean> | <hex> | <decimal>;"
    "hex: /0x[0-9a-f]+/;"
    "decimal: /[0-9]+/;"
    "boolean: \"true\" | \"false\";"
    "or : <and> ( \"||\" <and> )*;"
    "and : <equality> ( \"&&\" <equality> )*;"
    "equality : <comparison> ( (\"==\" | \"!=\") <comparison> )*;"
    "comparison : <sum> ( (\"<=\" | \">=\" | '<' | '>') <sum> )*;"
    "sum : <product> ( ('+' | '-') <product> )*;"
    "product : <not> ( ('*' | '/' | '%') <not> )*;"
    "not: '!' <value> | <value>;"
    "call:  <ident> '(' <statement>? (',' <statement>)* ')';"
    "value : <number> | <call> | <ident> | '(' <statement> ')';"
    "block: '{' <statement>* '}';"
    "program : /^/ <statement>* /$/;",
    State, Ident, Number, Hex, Dec, Bool, For, Range, By, If, Assign, Expr, Call, Not, Or, And, Equal, Comp, Sum, Prod, Value, Block, Prog, NULL);

  if (err) {
    mpc_err_print_to(err, stderr);
    return -1;
  }

  uint8_t* input = stdin_read(NULL);

  // replace comments with white space as preprocessor.
  {
    size_t i = 0;
    bool comment = false;
    uint8_t c;
    while ((c = input[i])) {
      if (comment) {
        if (c == '\n') comment = false;
        else input[i] = ' ';
      }
      else {
        if (c == '#') {
          comment = true;
          input[i] = ' ';
        }
      }
      i++;
    }
  }

  // fprintf(stderr, "\n## Source with comments stripped ##\n\n%s\n", input);

  mpc_result_t r;
  if (mpc_parse("input", (char*)input, Prog, &r)) {
    // mpc_ast_print_to(r.output, stderr);
    generate_block(r.output);
    mpc_ast_delete(r.output);
  } else {
    mpc_err_print_to(r.error, stderr);
    mpc_err_delete(r.error);
  }
  stdin_free(input);

  mpc_cleanup(21, State, Ident, Number, Hex, Dec, Bool, For, Range, By, If, Assign, Expr, Call, Not, Or, And, Equal, Comp, Sum, Prod, Value, Block, Prog);

  // Tag ends with marker bytes so we can tell apart from random serial stuff.
  output[0] = '(';
  output[1] = ']';
  output[output_len++] = '[';
  output[output_len++] = ')';
  // Write full length (including header/trailer as big-endian uint16_t)
  output[2] = output_len >> 8;
  output[3] = output_len & 0xff;

  write(1, output, output_len);

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
leaq 0x2b3e(%rip), %rdi      # 0xb6c5
callq 0x3bc6
movq %rax, 0xc0(%rsp)
leaq 0x2b34(%rip), %rdi      # 0xb6cf
callq 0x3bc6
movq %rax, 0xb8(%rsp)
leaq 0x299f(%rip), %rdi      # 0xb54e
callq 0x3bc6
movq %rax, 0x68(%rsp)
leaq 0x2b15(%rip), %rdi      # 0xb6d5
callq 0x3bc6
movq %rax, 0x58(%rsp)
leaq 0x2975(%rip), %rdi      # 0xb546
callq 0x3bc6
movq %rax, 0x50(%rsp)
leaq 0x2af7(%rip), %rdi      # 0xb6d9
callq 0x3bc6
movq %rax, 0x8(%rsp)
leaq 0x2aee(%rip), %rdi      # 0xb6e1
callq 0x3bc6
movq %rax, 0x70(%rsp)
leaq 0x2980(%rip), %rdi      # 0xb584
callq 0x3bc6
movq %rax, 0x30(%rsp)
leaq 0x2ad0(%rip), %rdi      # 0xb6e5
callq 0x3bc6
movq %rax, 0x60(%rsp)
leaq 0x2ac2(%rip), %rdi      # 0xb6e8
callq 0x3bc6
movq %rax, 0x48(%rsp)
leaq 0x2ab4(%rip), %rdi      # 0xb6eb
callq 0x3bc6
movq %rax, 0x18(%rsp)
leaq 0x2aaa(%rip), %rdi      # 0xb6f2
callq 0x3bc6
movq %rax, 0x40(%rsp)
leaq 0x2aa4(%rip), %rdi      # 0xb6fd
callq 0x3bc6
movq %rax, 0x38(%rsp)
leaq 0x2a98(%rip), %rdi      # 0xb702
callq 0x3bc6
movq %rax, 0x10(%rsp)
leaq 0x2a67(%rip), %rdi      # 0xb6e2
callq 0x3bc6
movq %rax, 0x28(%rsp)
leaq 0x30d2(%rip), %rdi      # 0xbd5e
callq 0x3bc6
movq %rax, 0x20(%rsp)
leaq 0x2a69(%rip), %rdi      # 0xb706
callq 0x3bc6
movq %rax, %rbx
leaq 0x2a63(%rip), %rdi      # 0xb70f
callq 0x3bc6
movq %rax, %r15
leaq 0x2a5f(%rip), %rdi      # 0xb71a
callq 0x3bc6
movq %rax, %r13
leaq 0x2a54(%rip), %rdi      # 0xb71e
callq 0x3bc6
movq %rax, %r14
leaq 0x2a4d(%rip), %rdi      # 0xb726
callq 0x3bc6
movq %rax, %rbp
leaq 0x2a44(%rip), %rdi      # 0xb72c
callq 0x3bc6
movq %rax, %r12
leaq 0x2a3b(%rip), %rdi      # 0xb732
callq 0x3bc6
subq $0xa0, %rsp
movq %rax, 0x120(%rsp)
movq %rax, 0x90(%rsp)
movq %r12, 0x138(%rsp)
movq %r12, 0x88(%rsp)
movq %rbp, 0x140(%rsp)
movq %rbp, 0x80(%rsp)
movq %r14, 0x128(%rsp)
movq %r14, 0x78(%rsp)
movq %r13, 0x148(%rsp)
movq %r13, 0x70(%rsp)
movq %r15, 0x150(%rsp)
movq %r15, 0x68(%rsp)
movq %rbx, 0x130(%rsp)
movq %rbx, 0x60(%rsp)
movq 0xc0(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0xc8(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0xb0(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0xb8(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0xe8(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x100(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x110(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, (%rsp)
andq $0x0, 0x98(%rsp)
leaq 0x2928(%rip), %rsi      # 0xb73a
xorl %edi, %edi
movq 0x160(%rsp), %rdx
movq %rdx, %r12
movq 0x158(%rsp), %rcx
movq %rcx, %r13
movq 0x108(%rsp), %r8
movq 0xf8(%rsp), %r9
xorl %eax, %eax
callq 0x8127
addq $0xa0, %rsp
testq %rax, %rax
je 0x8e67
movq 0x81a4(%rip), %rcx      # 0x10ff8
movq (%rcx), %rsi
movq %rax, %rdi
callq 0x23d6
pushq $-0x1
popq %rbp
jmp 0x8fd1
movq %r13, %r15
xorl %ebx, %ebx
xorl %edi, %edi
callq 0x89fa
movq %rax, %rbp
movq 0x80(%rsp), %rdx
movb (%rax), %cl
testb %cl, %cl
je 0x8ea1
testb $0x1, %bl
je 0x8e92
cmpb $0xa, %cl
jne 0x8e97
xorl %ebx, %ebx
jmp 0x8e9c
cmpb $0x23, %cl
jne 0x8e8e
movb $0x20, (%rax)
movb $0x1, %bl
incq %rax
jmp 0x8e7e
leaq 0x2569(%rip), %rdi      # 0xb411
leaq 0x78(%rsp), %rbx
movq %rbp, %rsi
movq %rdx, %r13
movq %rbx, %rcx
callq 0x3626
movq (%rbx), %rdi
testl %eax, %eax
je 0x8ed3
callq 0x8fe5
movq 0x78(%rsp), %rdi
callq 0x6878
jmp 0x8eec
movq 0x811e(%rip), %rax      # 0x10ff8
movq (%rax), %rsi
callq 0x23d6
movq 0x78(%rsp), %rdi
callq 0x237c
movq 0x8(%rsp), %rbx
movq %rbp, %rdi
callq 0x2280
xorl %ebp, %ebp
pushq $0x15
popq %rdi
movq %r12, %rsi
movq %r15, %rdx
movq 0x68(%rsp), %rcx
movq 0x58(%rsp), %r8
movq 0x50(%rsp), %r9
xorl %eax, %eax
pushq %r13
pushq 0xa0(%rsp)
pushq 0xb0(%rsp)
pushq 0xa0(%rsp)
pushq 0xc8(%rsp)
pushq 0xd8(%rsp)
pushq 0xc0(%rsp)
pushq 0x58(%rsp)
pushq 0x68(%rsp)
pushq 0x58(%rsp)
pushq 0x88(%rsp)
pushq 0x98(%rsp)
pushq 0x78(%rsp)
pushq 0xb0(%rsp)
pushq 0xd0(%rsp)
pushq 0xa8(%rsp)
pushq 0xf0(%rsp)
pushq %rbx
callq 0x3f97
addq $0x90, %rsp
movw $0x5d28, 0x826f(%rip)   # imm = 0x5D28
leaq 0x8268(%rip), %rsi      # 0x11200
movzwl 0x8241(%rip), %eax      # 0x111e0
leal 0x1(%rax), %ecx
movb $0x5b, (%rax,%rsi)
leal 0x2(%rax), %edx
movw %dx, 0x8230(%rip)       # 0x111e0
movl $0xffff, %eax           # imm = 0xFFFF
andl %eax, %ecx
movb $0x29, (%rcx,%rsi)
movb %dh, 0x8241(%rip)       # 0x11202
movb %dl, 0x823c(%rip)       # 0x11203
andl %eax, %edx
pushq $0x1
popq %rdi
callq 0x2090
movl %ebp, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq