// File: /workspace/github_c_makefile_star2_O2/atomlang[P]atomlang/src/pk_core.c
// Function: initializeCore
void initializeCore(PKVM* vm) {

#define INITIALIZE_BUILTIN_FN(name, fn, argc)                        \
  initializeBuiltinFN(vm, &vm->builtins[vm->builtins_count++], name, \
                      (int)strlen(name), argc, fn, DOCSTRING(fn));

#define MODULE_ADD_FN(module, name, fn, argc) \
  moduleAddFunctionInternal(vm, module, name, fn, argc, DOCSTRING(fn))

  // Initialize builtin functions.
  INITIALIZE_BUILTIN_FN("type_name",   coreTypeName,   1);

  // TODO: Add is keyword with modules for builtin types.
  // ex: val is Num; val is null; val is List; val is Range
  //     List.append(l, e) # List is implicitly imported core module.
  //     String.lower(s)

  INITIALIZE_BUILTIN_FN("help",        coreHelp,      -1);
  INITIALIZE_BUILTIN_FN("assert",      coreAssert,    -1);
  INITIALIZE_BUILTIN_FN("bin",         coreBin,        1);
  INITIALIZE_BUILTIN_FN("hex",         coreHex,        1);
  INITIALIZE_BUILTIN_FN("yield",       coreYield,     -1);
  INITIALIZE_BUILTIN_FN("to_string",   coreToString,   1);
  INITIALIZE_BUILTIN_FN("print",       corePrint,     -1);
  INITIALIZE_BUILTIN_FN("input",       coreInput,     -1);
  INITIALIZE_BUILTIN_FN("exit",        coreExit,      -1);

  // String functions.
  INITIALIZE_BUILTIN_FN("str_sub",     coreStrSub,     3);
  INITIALIZE_BUILTIN_FN("str_chr",     coreStrChr,     1);
  INITIALIZE_BUILTIN_FN("str_ord",     coreStrOrd,     1);

  // List functions.
  INITIALIZE_BUILTIN_FN("list_append", coreListAppend, 2);

  // Map functions.
  INITIALIZE_BUILTIN_FN("map_remove",  coreMapRemove,  2);

  // Core Modules /////////////////////////////////////////////////////////////

  Script* lang = newModuleInternal(vm, "lang");
  MODULE_ADD_FN(lang, "clock", stdLangClock,  0);
  MODULE_ADD_FN(lang, "gc",    stdLangGC,     0);
  MODULE_ADD_FN(lang, "disas", stdLangDisas,  1);
  MODULE_ADD_FN(lang, "write", stdLangWrite, -1);
#ifdef DEBUG
  MODULE_ADD_FN(lang, "debug_break", stdLangDebugBreak, 0);
#endif

  Script* math = newModuleInternal(vm, "math");
  MODULE_ADD_FN(math, "floor", stdMathFloor,       1);
  MODULE_ADD_FN(math, "ceil",  stdMathCeil,        1);
  MODULE_ADD_FN(math, "pow",   stdMathPow,         2);
  MODULE_ADD_FN(math, "sqrt",  stdMathSqrt,        1);
  MODULE_ADD_FN(math, "abs",   stdMathAbs,         1);
  MODULE_ADD_FN(math, "sign",  stdMathSign,        1);
  MODULE_ADD_FN(math, "hash",  stdMathHash,        1);
  MODULE_ADD_FN(math, "sin",   stdMathSine,        1);
  MODULE_ADD_FN(math, "cos",   stdMathCosine,      1);
  MODULE_ADD_FN(math, "tan",   stdMathTangent,     1);
  MODULE_ADD_FN(math, "sinh",  stdMathSinh,        1);
  MODULE_ADD_FN(math, "cosh",  stdMathCosh,        1);
  MODULE_ADD_FN(math, "tanh",  stdMathTanh,        1);
  MODULE_ADD_FN(math, "asin",  stdMathArcSine,     1);
  MODULE_ADD_FN(math, "acos",  stdMathArcCosine,   1);
  MODULE_ADD_FN(math, "atan",  stdMathArcTangent,  1);
  MODULE_ADD_FN(math, "log10", stdMathLog10,       1);
  MODULE_ADD_FN(math, "round", stdMathRound,       1);

  // Note that currently it's mutable (since it's a global variable, not
  // constant and atomlang doesn't support constant) so the user shouldn't
  // modify the PI, like in python.
  // TODO: at varSetAttrib() we can detect if the user try to change an
  // attribute of a core module and we can throw an error.
  moduleAddGlobalInternal(vm, math, "PI", VAR_NUM(M_PI));

  Script* fiber = newModuleInternal(vm, "Fiber");
  MODULE_ADD_FN(fiber, "new",      stdFiberNew,     1);
  MODULE_ADD_FN(fiber, "run",      stdFiberRun,    -1);
  MODULE_ADD_FN(fiber, "resume",   stdFiberResume, -1);

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl 0x5e8(%rdi), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rdi)
imulq $0x18, %rax, %rax
leaq (%rdi,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xa881(%rip), %rax      # 0x1a0f8
movq %rax, (%rsp)
leaq 0xa2e3(%rip), %rdx      # 0x19b65
leaq 0x818(%rip), %r9        # 0x100a1
pushq $0x9
popq %r13
pushq $0x1
popq %rbp
movl %r13d, %ecx
movl %ebp, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xa913(%rip), %rax      # 0x1a1d3
movq %rax, (%rsp)
leaq 0xa2a4(%rip), %rdx      # 0x19b6f
leaq 0x857(%rip), %r9        # 0x10129
pushq $0x4
popq %rcx
pushq $-0x1
popq %r14
movq %rbx, %rdi
movl %r14d, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xa94d(%rip), %rax      # 0x1a256
movq %rax, (%rsp)
leaq 0xa260(%rip), %rdx      # 0x19b74
leaq 0x938(%rip), %r9        # 0x10253
pushq $0x6
popq %rcx
movq %rbx, %rdi
movl %r14d, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xa99d(%rip), %rax      # 0x1a2eb
movq %rax, (%rsp)
leaq 0xa222(%rip), %rdx      # 0x19b7b
leaq 0xaa7(%rip), %r9        # 0x10407
pushq $0x3
popq %r12
movq %rbx, %rdi
movl %r12d, %ecx
movl %ebp, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xa9be(%rip), %rax      # 0x1a355
movq %rax, (%rsp)
leaq 0xa1dd(%rip), %rdx      # 0x19b7f
leaq 0xb36(%rip), %r9        # 0x104df
movq %rbx, %rdi
movl %r12d, %ecx
movl %ebp, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xa9d4(%rip), %rax      # 0x1a3b0
movq %rax, (%rsp)
leaq 0xa19c(%rip), %rdx      # 0x19b83
leaq 0xc28(%rip), %r9        # 0x10616
pushq $0x5
popq %r15
movq %rbx, %rdi
movl %r15d, %ecx
movl %r14d, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xaaaa(%rip), %rax      # 0x1a4cf
movq %rax, (%rsp)
leaq 0xa159(%rip), %rdx      # 0x19b89
leaq 0xc80(%rip), %r9        # 0x106b7
movq %rbx, %rdi
movl %r13d, %ecx
movl %ebp, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xaab4(%rip), %rax      # 0x1a51e
movq %rax, (%rsp)
leaq 0xa11e(%rip), %rdx      # 0x19b93
leaq 0xc70(%rip), %r9        # 0x106ec
movq %rbx, %rdi
movl %r15d, %ecx
movl %r14d, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xaadb(%rip), %rax      # 0x1a58a
movq %rax, (%rsp)
leaq 0xa0df(%rip), %rdx      # 0x19b99
leaq 0xccf(%rip), %r9        # 0x10790
movq %rbx, %rdi
movl %r15d, %ecx
movl %r14d, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xab3c(%rip), %rax      # 0x1a630
movq %rax, (%rsp)
leaq 0xa0a0(%rip), %rdx      # 0x19b9f
leaq 0xdd5(%rip), %r9        # 0x108db
movq %rbx, %rdi
pushq $0x4
popq %rcx
movl %r14d, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xac11(%rip), %rax      # 0x1a74a
movq %rax, (%rsp)
leaq 0xa060(%rip), %rdx      # 0x19ba4
leaq 0xe5c(%rip), %r9        # 0x109a7
pushq $0x7
popq %r15
movq %rbx, %rdi
movl %r15d, %ecx
movl %r12d, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xace0(%rip), %rax      # 0x1a862
movq %rax, (%rsp)
leaq 0xa01f(%rip), %rdx      # 0x19bac
leaq 0xfaf(%rip), %r9        # 0x10b43
movq %rbx, %rdi
movl %r15d, %ecx
movl %ebp, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xad1a(%rip), %rax      # 0x1a8e1
movq %rax, (%rsp)
leaq 0x9fe2(%rip), %rdx      # 0x19bb4
leaq 0x1047(%rip), %r9       # 0x10c20
movq %rbx, %rdi
movl %r15d, %ecx
movl %ebp, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xad55(%rip), %rax      # 0x1a961
movq %rax, (%rsp)
leaq 0x9fa5(%rip), %rdx      # 0x19bbc
leaq 0x10ac(%rip), %r9       # 0x10cca
pushq $0xb
popq %rcx
pushq $0x2
popq %r12
movq %rbx, %rdi
movl %r12d, %r8d
callq 0x10069
movl 0x5e8(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x5e8(%rbx)
imulq $0x18, %rax, %rax
leaq (%rbx,%rax), %rsi
addq $0x138, %rsi            # imm = 0x138
leaq 0xad9e(%rip), %rax      # 0x1a9f3
movq %rax, (%rsp)
leaq 0x9f68(%rip), %rdx      # 0x19bc8
leaq 0x117b(%rip), %r9       # 0x10de2
pushq $0xa
popq %rcx
movq %rbx, %rdi
movl %r12d, %r8d
callq 0x10069
leaq 0x9f57(%rip), %rsi      # 0x19bd3
movq %rbx, %rdi
callq 0xe6db
movq %rax, %r15
leaq 0x9f4a(%rip), %rdx      # 0x19bd8
leaq 0x124a(%rip), %rcx      # 0x10edf
leaq 0xade7(%rip), %r9       # 0x1aa83
movq %rbx, %rdi
movq %rax, %rsi
xorl %r8d, %r8d
callq 0xe974
leaq 0x9cc5(%rip), %rdx      # 0x19976
leaq 0x1252(%rip), %rcx      # 0x10f0a
leaq 0xae0f(%rip), %r9       # 0x1aace
movq %rbx, %rdi
movq %r15, %rsi
xorl %r8d, %r8d
callq 0xe974
leaq 0x9f0a(%rip), %rdx      # 0x19bde
leaq 0x127f(%rip), %rcx      # 0x10f5a
leaq 0xae3b(%rip), %r9       # 0x1ab1d
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9eed(%rip), %rdx      # 0x19be4
leaq 0x12e7(%rip), %rcx      # 0x10fe5
leaq 0xae6b(%rip), %r9       # 0x1ab70
movq %rbx, %rdi
movq %r15, %rsi
movl %r14d, %r8d
callq 0xe974
leaq 0x9ed0(%rip), %rdx      # 0x19bea
leaq 0x1342(%rip), %rcx      # 0x11063
leaq 0xaec7(%rip), %r9       # 0x1abef
movq %rbx, %rdi
movq %r15, %rsi
xorl %r8d, %r8d
callq 0xe974
leaq 0x9eb9(%rip), %rsi      # 0x19bf6
movq %rbx, %rdi
callq 0xe6db
movq %rax, %r15
leaq 0x9eac(%rip), %rdx      # 0x19bfb
leaq 0x130f(%rip), %rcx      # 0x11065
leaq 0xaedc(%rip), %r9       # 0x1ac39
movq %rbx, %rdi
movq %rax, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9e8f(%rip), %rdx      # 0x19c01
leaq 0x133c(%rip), %rcx      # 0x110b5
leaq 0xaed2(%rip), %r9       # 0x1ac52
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9e71(%rip), %rdx      # 0x19c06
leaq 0x1369(%rip), %rcx      # 0x11105
leaq 0xaec7(%rip), %r9       # 0x1ac6a
movq %rbx, %rdi
movq %r15, %rsi
movl %r12d, %r8d
callq 0xe974
leaq 0x9e52(%rip), %rdx      # 0x19c0a
leaq 0x13c0(%rip), %rcx      # 0x1117f
leaq 0xaebb(%rip), %r9       # 0x1ac81
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9e34(%rip), %rdx      # 0x19c0f
leaq 0x13fd(%rip), %rcx      # 0x111df
leaq 0xaeb0(%rip), %r9       # 0x1ac99
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9e15(%rip), %rdx      # 0x19c13
leaq 0x1435(%rip), %rcx      # 0x1123a
leaq 0xaea4(%rip), %r9       # 0x1acb0
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9df7(%rip), %rdx      # 0x19c18
leaq 0x148f(%rip), %rcx      # 0x112b7
leaq 0xae99(%rip), %r9       # 0x1acc8
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9de9(%rip), %rdx      # 0x19c2d
leaq 0x14e1(%rip), %rcx      # 0x1132c
leaq 0xaedc(%rip), %r9       # 0x1ad2e
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9dcb(%rip), %rdx      # 0x19c32
leaq 0x150e(%rip), %rcx      # 0x1137c
leaq 0xaf21(%rip), %r9       # 0x1ad96
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9dad(%rip), %rdx      # 0x19c37
leaq 0x153b(%rip), %rcx      # 0x113cc
leaq 0xaf68(%rip), %r9       # 0x1ae00
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9d70(%rip), %rdx      # 0x19c1d
leaq 0x1568(%rip), %rcx      # 0x1141c
leaq 0xafb0(%rip), %r9       # 0x1ae6b
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9d52(%rip), %rdx      # 0x19c22
leaq 0x1595(%rip), %rcx      # 0x1146c
leaq 0xafd6(%rip), %r9       # 0x1aeb4
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9d34(%rip), %rdx      # 0x19c27
leaq 0x15c2(%rip), %rcx      # 0x114bc
leaq 0xaffe(%rip), %r9       # 0x1aeff
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9d16(%rip), %rdx      # 0x19c2c
leaq 0x15ef(%rip), %rcx      # 0x1150c
leaq 0xb05b(%rip), %r9       # 0x1af7f
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9cf8(%rip), %rdx      # 0x19c31
leaq 0x169e(%rip), %rcx      # 0x115de
leaq 0xb0b1(%rip), %r9       # 0x1aff8
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9cda(%rip), %rdx      # 0x19c36
leaq 0x174d(%rip), %rcx      # 0x116b0
leaq 0xb0f9(%rip), %r9       # 0x1b063
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9cbc(%rip), %rdx      # 0x19c3b
leaq 0x177a(%rip), %rcx      # 0x11700
leaq 0xb142(%rip), %r9       # 0x1b0cf
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9c9f(%rip), %rdx      # 0x19c41
leaq 0x17a7(%rip), %rcx      # 0x11750
leaq 0xb16b(%rip), %r9       # 0x1b11b
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %r8d
callq 0xe974
movsd 0x986a(%rip), %xmm0     # 0x19830
callq 0x34ce
leaq 0x97d2(%rip), %rdx      # 0x197a4
movq %rbx, %rdi
movq %r15, %rsi
movq %rax, %rcx
callq 0xe8a9
leaq 0x8673(%rip), %rsi      # 0x1865a
movq %rbx, %rdi
callq 0xe6db
movq %rax, %r15
leaq 0x9c4e(%rip), %rdx      # 0x19c47
leaq 0x17a0(%rip), %rcx      # 0x117a0
leaq 0xb16c(%rip), %r9       # 0x1b173
movq %rbx, %rdi
movq %rax, %rsi
movl %ebp, %r8d
callq 0xe974
leaq 0x9c2f(%rip), %rdx      # 0x19c4b
leaq 0x17bd(%rip), %rcx      # 0x117e0
leaq 0xb1f6(%rip), %r9       # 0x1b220
movq %rbx, %rdi
movq %r15, %rsi
movl %r14d, %r8d
callq 0xe974
leaq 0x9c10(%rip), %rdx      # 0x19c4f
leaq 0x18d4(%rip), %rcx      # 0x1191a
leaq 0xb2b7(%rip), %r9       # 0x1b304
movq %rbx, %rdi
movq %r15, %rsi
movl %r14d, %r8d
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xe974