#ifndef CODUO_SCRIPT_COMPILE_PRIVATE_H
#define CODUO_SCRIPT_COMPILE_PRIVATE_H

#include <stdint.h>
#include <stdio.h>

#include "coduo_engine_structs.h"
#include "script_runtime_private.h"

typedef struct coduo_scr_ast_node_s coduo_scr_ast_node_t;

void ScriptCompile(coduo_scr_ast_node_t *script,
                   uint16_t currentFunctionRoot);
void Scr_UsingTree(const char *animTreeName,
                   uint32_t sourcePos);
void Scr_LoadAnimTreeAtIndex(int32_t treeIndex,
                             coduo_script_anim_tree_alloc_fn allocCallback);

/* Script operands are byte-packed and may start at any byte offset.  These
 * char pointers are full-width addresses, not narrowed integer pointers; they
 * deliberately make no uint16_t/int32_t alignment promise.  Constant-size
 * memcpy access preserves the original i386 word/dword values and normally
 * folds to the same single x86 access. If a compiler does not fold one, the
 * byte-copy sequence is an intentional portability-only code-generation
 * deviation with identical stored bytes. */
typedef struct script_code_offset_patch_s {
    char *patch;
    struct script_code_offset_patch_s *next;
} script_code_offset_patch_t;

typedef struct script_switch_case_record_s {
    uint32_t value;
    coduo_script_value_payload_t codeOffset;
    uint32_t sourcePos;
    struct script_switch_case_record_s *next;
} script_switch_case_record_t;

typedef struct script_code_string_fixup_s {
    char *codepos;
    struct script_code_string_fixup_s *next;
} script_code_string_fixup_t;

typedef struct coduo_scr_parser_words1_s {
    coduo_script_yystype_word_t words[1];
} coduo_scr_parser_words1_t;

typedef struct coduo_scr_parser_words2_s {
    coduo_script_yystype_word_t words[2];
} coduo_scr_parser_words2_t;

typedef struct coduo_scr_parser_words3_s {
    coduo_script_yystype_word_t words[3];
} coduo_scr_parser_words3_t;

typedef struct coduo_scr_parser_words4_s {
    coduo_script_yystype_word_t words[4];
} coduo_scr_parser_words4_t;

typedef struct coduo_scr_parser_words5_s {
    coduo_script_yystype_word_t words[5];
} coduo_scr_parser_words5_t;

typedef struct coduo_scr_parser_words6_s {
    coduo_script_yystype_word_t words[6];
} coduo_scr_parser_words6_t;

typedef struct coduo_scr_parser_words7_s {
    coduo_script_yystype_word_t words[7];
} coduo_scr_parser_words7_t;

/*
 * Stock parser string tokens are 16-bit script string handles carried in the
 * low half of a 32-bit semantic word.  Consumers use movzx WORD PTR loads from
 * AST fields before string/variable-table calls.
 */
#define SCR_AST_STRING_HANDLE(value) ((uint16_t)(value))

typedef struct coduo_scr_parser_list_link_s {
    coduo_script_yystype_word_t value;
    struct coduo_scr_parser_list_link_s *next;
} coduo_scr_parser_list_link_t;

typedef struct coduo_scr_parser_list_s {
    coduo_scr_parser_list_link_t *head;
    coduo_scr_parser_list_link_t *tail;
} coduo_scr_parser_list_t;

typedef struct coduo_scr_ast_expression_entry_s {
    coduo_scr_ast_node_t *node;
    uint32_t sourcePos;
} coduo_scr_ast_expression_entry_t;

typedef struct coduo_scr_ast_string_entry_s {
    coduo_script_yystype_word_t string;
    coduo_script_yystype_word_t sourcePos;
} coduo_scr_ast_string_entry_t;

typedef struct coduo_scr_ast_list_item_s {
    union {
        coduo_scr_ast_expression_entry_t *entry;
        coduo_scr_ast_string_entry_t *stringEntry;
    };
    struct coduo_scr_ast_list_item_s *next;
} coduo_scr_ast_list_item_t;

typedef struct coduo_scr_ast_list_s {
    coduo_scr_ast_list_item_t *head;
} coduo_scr_ast_list_t;

typedef struct coduo_scr_ast_statement_item_s {
    coduo_scr_ast_node_t *node;
    struct coduo_scr_ast_statement_item_s *next;
} coduo_scr_ast_statement_item_t;

typedef struct coduo_scr_ast_statement_list_s {
    int32_t kind;
    coduo_scr_ast_statement_item_t *head;
} coduo_scr_ast_statement_list_t;

typedef struct coduo_scr_ast_statement_block_s {
    coduo_scr_ast_statement_list_t *list;
} coduo_scr_ast_statement_block_t;

typedef struct coduo_scr_ast_script_entry_list_s {
    int32_t kind;
    coduo_scr_ast_list_item_t *head;
} coduo_scr_ast_script_entry_list_t;

typedef struct coduo_scr_ast_script_entry_block_s {
    coduo_scr_ast_script_entry_list_t *list;
} coduo_scr_ast_script_entry_block_t;

typedef struct coduo_scr_script_load_record_s {
    uint16_t filename;
    uint16_t padding02; /* Compiler padding before the 32-bit source position. */
    uint32_t sourcePos;
} coduo_scr_script_load_record_t;

extern int32_t script_animCheckEnabled;
extern const char
    *script_animPropertyNames[CODUO_SCRIPT_ANIM_PROPERTY_NAME_COUNT];
extern coduo_script_anim_tree_table_t script_animTrees;
extern coduo_script_anim_tree_handle_table_t script_animTreeHandles;
extern coduo_script_anim_tree_count_table_t script_animTreeCounts;
extern uint16_t script_animTreeRoot;
extern int32_t script_animCommentDepth;
extern char *script_animParseState;
extern const char *script_animParseStart;
extern uint16_t script_animCurrentTreeRoot;
extern uint16_t script_animCurrentUsingTree;
extern uint32_t script_animTreeChecksum;
extern uint32_t script_activeAnimTreeHandle;
extern uint8_t script_breakAllowed;
extern uint8_t script_breakAllowedInDeveloperBlock;
extern script_code_offset_patch_t *script_breakPatchList;
extern uint8_t script_caseAllowed;
extern uint8_t script_caseAllowedInDeveloperBlock;
extern script_switch_case_record_t *script_caseRecordList;
extern uint8_t *script_codeBase;
extern uint32_t script_codeChecksum;
extern uint8_t *script_codeEmitCursor;
extern uint8_t *script_codeEnd;
extern uint8_t *script_codeLastOpcodePos;
extern int32_t script_codeMaxLocalDepth;
extern int32_t script_codeMaxStackDepth;
extern uint8_t script_codeNeedsDeferredCheck;
extern uint8_t script_codeOwnsStrings;
extern uint8_t *script_codeRelocationEnd;
extern uint8_t *script_codeRelocationStart;
extern size_t script_codeSize;
extern int32_t script_codeStackDepth;
extern script_code_string_fixup_t *script_codeStringFixups;
extern size_t script_codeTempSize;
extern int32_t script_codegenMode;
extern uint8_t script_continueAllowed;
extern uint8_t script_continueAllowedInDeveloperBlock;
extern script_code_offset_patch_t *script_continuePatchList;
extern uint16_t script_currentFunctionRoot;
extern uint8_t *script_developerOpBuffer;
extern int32_t script_developerOpcodePatchCapacity;
extern uint8_t **script_developerOpcodePatchTable;
extern coduo_script_frame_backup_codepos_t script_frameBackupCodepos;
extern coduo_script_frame_backup_opcode_t script_frameBackupOpcode;
extern uint8_t *script_importFieldBuffer;
extern uint16_t script_loadAnimTreeRoot;
extern uint8_t script_loadAnimTreesActive;
extern uint16_t script_loadScriptCodeRoot;
extern uint16_t script_loadScriptHandleRoot;
extern uint8_t script_loadScriptsActive;
extern int32_t script_pendingScriptLoadCount;
extern coduo_scr_script_load_record_t *script_pendingScriptLoadCursor;
extern int32_t script_parseSourceDone;
extern char *script_parseSource;
extern coduo_scr_ast_node_t *script_parseRoot;
extern int32_t script_parseErrorCount;
extern const uint8_t *script_sourceBufferEnd;
extern uint32_t script_sourceBufferOffset;
extern const uint8_t *script_sourceBufferStart;
extern uint32_t script_sourceChecksum;
extern const int16_t script_yyAccept[];
extern const int16_t script_yyBase[];
extern const int16_t script_yyChk[];
extern char *script_yyCBufferPosition;
extern const int16_t script_yyDef[];
extern int32_t script_yyDidBufferSwitchOnEof;
extern const uint32_t script_yyEc[];
extern uint8_t script_yyHoldChar;
extern int32_t script_yyInit;
extern char *script_yyInputCursor;
extern int32_t script_yyLastAcceptingState;
extern char *script_yyLastAcceptingCpos;
extern int32_t script_yyLength;
extern const uint32_t script_yyMeta[];
extern int32_t script_yyNChars;
extern const int16_t script_yyNxt[];
extern uint32_t script_yyCurrentSourcePos;
extern uint32_t script_yyPreviousSourcePos;
extern FILE *script_yyInputFile;
extern FILE *script_yyOutputFile;
extern int32_t script_yyStart;
extern char *script_yyText;
extern const int16_t script_yycheck[];
extern int32_t script_yychar;
extern coduo_script_yy_buffer_t *script_yyCurrentBuffer;
extern const int16_t script_yydef[];
extern const int16_t script_yydgoto[];
extern int32_t script_yyerrflag;
extern const int16_t script_yygindex[];
extern const int16_t script_yylhs[];
extern sval_u script_yylval;
extern const int16_t script_yylen[];
extern int16_t script_yyss[];
extern int16_t *script_yyssp;
extern const int16_t script_yyrindex[];
extern const int16_t script_yysindex[];
extern const int16_t script_yytable[];
extern sval_u script_yyval;
extern sval_u script_yyvs[];
extern sval_u *script_yyvsp;
extern int32_t script_yynerrs;

enum {
    SCR_AST_KIND_ASSIGNMENT_STATEMENT = 2,
    SCR_AST_KIND_STRING_REF = 3,
    SCR_AST_KIND_PRIMITIVE_EXPRESSION = 4,
    SCR_AST_KIND_INTEGER_LITERAL = 5,
    SCR_AST_KIND_FLOAT_LITERAL = 6,
    SCR_AST_KIND_NEGATED_INTEGER_LITERAL = 7,
    SCR_AST_KIND_NEGATED_FLOAT_LITERAL = 8,
    SCR_AST_KIND_STRING_USAGE_A = 9,
    SCR_AST_KIND_STRING_USAGE_B = 0x0a,
    SCR_AST_KIND_OBJECT_INDEX_OBJECT_REF = 0x0b,
    SCR_AST_KIND_OBJECT_STRING_REF = 0x0c,
    SCR_AST_KIND_REFERENCE_EXPRESSION = 0x0d,
    SCR_AST_KIND_SCRIPT_FUNCTION_NAME = 0x0e,
    SCR_AST_KIND_CALL_VALUE = 0x0f,
    SCR_AST_KIND_FUNCTION_REF = 0x10,
    SCR_AST_KIND_SCRIPT_FUNCTION_REF = 0x11,
    SCR_AST_KIND_FUNCTION_POINTER_CALL = 0x12,
    SCR_AST_KIND_FUNCTION_CALL_VALUE = 0x13,
    SCR_AST_KIND_METHOD_CALL_VALUE = 0x14,
    SCR_AST_KIND_CALL_STATEMENT = 0x15,
    SCR_AST_KIND_FUNCTION_CALL = 0x16,
    SCR_AST_KIND_RETURN_VALUE_STATEMENT = 0x17,
    SCR_AST_KIND_RETURN_STATEMENT = 0x18,
    SCR_AST_KIND_WAIT_STATEMENT = 0x19,
    SCR_AST_KIND_METHOD_CALL = 0x1a,
    SCR_AST_KIND_DEFERRED_CHECK = 0x1b,
    SCR_AST_KIND_SELF_VALUE = 0x1c,
    SCR_AST_KIND_LEVEL_VALUE = 0x1d,
    SCR_AST_KIND_GAME_VALUE = 0x1e,
    SCR_AST_KIND_ANIM_VALUE = 0x1f,
    SCR_AST_KIND_IF_STATEMENT = 0x20,
    SCR_AST_KIND_IF_ELSE_STATEMENT = 0x21,
    SCR_AST_KIND_WHILE_STATEMENT = 0x22,
    SCR_AST_KIND_DO_WHILE_STATEMENT = 0x23,
    SCR_AST_KIND_FOR_STATEMENT = 0x24,
    SCR_AST_KIND_INC_STATEMENT = 0x25,
    SCR_AST_KIND_DEC_STATEMENT = 0x26,
    SCR_AST_KIND_REF_ASSIGNMENT_STATEMENT = 0x27,
    SCR_AST_KIND_STATEMENT_BLOCK = 0x28,
    SCR_AST_KIND_DEVELOPER_STATEMENT_BLOCK = 0x29,
    SCR_AST_KIND_WAITTILL_STATEMENT = 0x36,
    SCR_AST_KIND_WAITTILLMATCH_STATEMENT = 0x37,
    SCR_AST_KIND_NOTIFY_STATEMENT = 0x38,
    SCR_AST_KIND_ENDON_STATEMENT = 0x39,
    SCR_AST_KIND_SWITCH_STATEMENT = 0x3a,
    SCR_AST_KIND_CASE_STATEMENT = 0x3b,
    SCR_AST_KIND_DEFAULT_STATEMENT = 0x3c,
    SCR_AST_KIND_BREAK_STATEMENT = 0x3d,
    SCR_AST_KIND_CONTINUE_STATEMENT = 0x3e,
    SCR_AST_KIND_FOR_CONDITION = 0x3f,
    SCR_AST_KIND_EXPRESSION_LIST_VALUE = 0x2a,
    SCR_AST_KIND_SHORT_CIRCUIT_38 = 0x2b,
    SCR_AST_KIND_SHORT_CIRCUIT_37 = 0x2c,
    SCR_AST_KIND_BINARY_OPCODE = 0x2d,
    SCR_AST_KIND_SOURCE_MARKED_2F = 0x2e,
    SCR_AST_KIND_SOURCE_MARKED_30 = 0x2f,
    SCR_AST_KIND_SOURCE_MARKED_31 = 0x30,
    SCR_AST_KIND_SOURCE_MARKED_32 = 0x31,
    SCR_AST_KIND_SOURCE_MARKED_33 = 0x32,
    SCR_AST_KIND_SOURCE_MARKED_34 = 0x33,
    SCR_AST_KIND_SOURCE_MARKED_4D = 0x34,
    SCR_AST_KIND_OPCODE_17_VALUE = 0x40,
    SCR_AST_KIND_ANIM_STRING_VALUE = 0x41,
    SCR_AST_KIND_FUNCTION_DEFINITION = 0x42,
    SCR_AST_KIND_DEVELOPER_FUNCTION_DEFINITION = 0x43,
    SCR_AST_KIND_USING_ANIMTREE = 0x44,
    SCR_AST_KIND_LITERAL_ZERO = 0x45,
    SCR_AST_KIND_LITERAL_ONE = 0x46,
    SCR_AST_KIND_ANIMTREE_VALUE = 0x47
};

struct coduo_scr_ast_node_s {
    int32_t kind;
    union {
        coduo_script_yystype_word_t words[6];
        struct {
            uint32_t rawValue;
        } literal;
        struct {
            coduo_scr_ast_node_t *node;
        } child;
        struct {
            coduo_scr_ast_node_t *node;
            uint32_t sourcePos;
        } sourceChild;
        struct {
            coduo_script_yystype_word_t string;
            coduo_script_yystype_word_t sourcePos;
        } sourceString;
        struct {
            coduo_scr_ast_script_entry_block_t *entries;
        } scriptRoot;
        struct {
            coduo_script_yystype_word_t name;
            coduo_scr_ast_list_t *parameters;
            coduo_scr_ast_statement_block_t *body;
            uint32_t sourcePos;
        } functionDefinition;
        struct {
            coduo_script_yystype_word_t name;
            coduo_script_yystype_word_t sourcePos;
        } usingAnimTree;
        struct {
            coduo_scr_ast_node_t *left;
            uint32_t leftSourcePos;
            coduo_scr_ast_node_t *right;
            uint32_t rightSourcePos;
        } shortCircuit;
        struct {
            coduo_scr_ast_node_t *left;
            coduo_scr_ast_node_t *right;
            coduo_script_yystype_word_t opcode;
            coduo_script_yystype_word_t sourcePos;
        } binaryOpcode;
        struct {
            coduo_scr_ast_list_t *list;
            uint32_t sourcePos;
        } expressionList;
        struct {
            coduo_scr_ast_node_t *objectNode;
            coduo_scr_ast_node_t *indexNode;
            uint32_t objectSourcePos;
            coduo_script_yystype_word_t indexSourcePos;
        } objectIndexObjectRef;
        struct {
            coduo_script_yystype_word_t string;
        } stringRef;
        struct {
            coduo_scr_ast_node_t *objectNode;
            coduo_script_yystype_word_t string;
            coduo_script_yystype_word_t sourcePos;
            coduo_script_yystype_word_t opcodeSourcePos;
        } objectStringRef;
        struct {
            coduo_scr_ast_node_t *refNode;
            coduo_scr_ast_node_t *valueNode;
            coduo_script_yystype_word_t opcode;
            coduo_script_yystype_word_t sourcePos;
        } assignmentStatement;
        struct {
            coduo_scr_ast_node_t *valueNode;
        } returnValueStatement;
        struct {
            coduo_scr_ast_node_t *timeNode;
            uint32_t timeSourcePos;
            coduo_script_yystype_word_t opcodeSourcePos;
        } waitStatement;
        struct {
            coduo_scr_ast_node_t *conditionNode;
            coduo_scr_ast_node_t *bodyNode;
            uint32_t sourcePos;
        } ifStatement;
        struct {
            coduo_scr_ast_node_t *conditionNode;
            coduo_scr_ast_node_t *thenNode;
            coduo_scr_ast_node_t *elseNode;
            uint32_t sourcePos;
        } ifElseStatement;
        struct {
            coduo_scr_ast_node_t *conditionNode;
            coduo_scr_ast_node_t *bodyNode;
            uint32_t conditionSourcePos;
            coduo_script_yystype_word_t loopSourcePos;
        } whileStatement;
        struct {
            coduo_scr_ast_node_t *bodyNode;
            coduo_scr_ast_node_t *conditionNode;
            uint32_t conditionSourcePos;
            coduo_script_yystype_word_t loopSourcePos;
        } doWhileStatement;
        struct {
            coduo_scr_ast_node_t *initNode;
            coduo_scr_ast_node_t *conditionNode;
            coduo_scr_ast_node_t *incrementNode;
            coduo_scr_ast_node_t *bodyNode;
            uint32_t conditionSourcePos;
            coduo_script_yystype_word_t loopSourcePos;
        } forStatement;
        struct {
            coduo_scr_ast_node_t *refNode;
            uint32_t sourcePos;
        } incDecStatement;
        struct {
            coduo_scr_ast_statement_block_t *block;
        } statementBlock;
        struct {
            coduo_scr_ast_statement_block_t *block;
            uint32_t sourcePos;
        } developerStatementBlock;
        struct {
            coduo_scr_ast_node_t *objectNode;
            coduo_scr_ast_list_t *list;
            uint32_t objectSourcePos;
            coduo_script_yystype_word_t opcodeSourcePos;
        } waittillStatement;
        struct {
            coduo_scr_ast_node_t *objectNode;
            coduo_scr_ast_list_t *list;
            uint32_t objectSourcePos;
            coduo_script_yystype_word_t opcodeSourcePos;
        } notifyStatement;
        struct {
            coduo_scr_ast_node_t *objectNode;
            coduo_scr_ast_node_t *eventNode;
            uint32_t objectSourcePos;
            coduo_script_yystype_word_t opcodeSourcePos;
        } endOnStatement;
        struct {
            coduo_scr_ast_node_t *valueNode;
            coduo_scr_ast_node_t *bodyNode;
            uint32_t sourcePos;
        } switchStatement;
        struct {
            coduo_scr_ast_node_t *valueNode;
            uint32_t sourcePos;
        } caseStatement;
        struct {
            uint32_t sourcePos;
        } sourceOnlyStatement;
        struct {
            coduo_script_yystype_word_t name;
            coduo_script_yystype_word_t sourcePos;
        } functionRef;
        struct {
            coduo_script_yystype_word_t filename;
            coduo_script_yystype_word_t name;
            coduo_script_yystype_word_t sourcePos;
        } scriptFunctionRef;
        struct {
            coduo_scr_ast_node_t *nameNode;
            uint32_t sourcePos;
        } namedCall;
        struct {
            coduo_scr_ast_node_t *objectNode;
            uint32_t sourcePos;
        } pointerCall;
        struct {
            coduo_scr_ast_node_t *callee;
            coduo_script_yystype_word_t sourcePos;
            coduo_script_yystype_word_t methodSourcePos;
        } call;
        struct {
            coduo_scr_ast_node_t *callee;
            coduo_scr_ast_list_t *args;
            uint32_t sourcePos;
        } functionCallValue;
        struct {
            coduo_scr_ast_node_t *objectNode;
            coduo_scr_ast_node_t *callee;
            coduo_scr_ast_list_t *args;
            coduo_script_yystype_word_t methodSourcePos;
            coduo_script_yystype_word_t objectSourcePos;
        } methodCallValue;
    } payload;
};

uint8_t *TempMalloc(size_t size);
void TempMemoryReset(void);
void TempMemorySetPos(uint8_t *pos);
void CompileRemoveRefToString(uint16_t string);
void CompileTransferRefToString(uint16_t string,
                                uint8_t usage);
void EmitCanonicalString(uint16_t string);
void EmitOpcode(uint8_t opcode, int32_t stackDelta,
                int32_t localDepthMode);
void EmitByte(uint8_t value);
void EmitShort(int16_t value);
void EmitInteger(int32_t value);
void EmitFloat(float value);
void EmitString(uint16_t value);
void EmitBlankPos(void);
void coduomp_emit_blank_value_payload(void);
void EmitCodepos(uint32_t i386CodePos);
void coduomp_emit_value_payload(coduo_script_value_payload_t value);
void EmitBuiltinFunction(uint32_t i386FunctionBits);
void EmitBuiltinMethod(uint32_t i386MethodBits);
void coduomp_emit_builtin_function_payload(
    coduo_script_function_callback_fn function);
void coduomp_emit_builtin_method_payload(
    coduo_script_method_callback_fn method);
void EmitDecTop(void);
void EmitIncTop(void);
void EmitGetInteger(int32_t value);
void EmitGetFloat(float value);
void EmitFalse(void);
void EmitTrue(void);
void EmitAnimTree(uint32_t sourcePos);
void EmitNOP(void);
void EmitGetString(uint16_t string);
void EmitGetIString(uint16_t string);
void EmitLocalVariable(uint16_t string);
void EmitLocalVariableRef(uint16_t string);
void EmitSelf(void);
void EmitLevel(void);
void EmitGame(void);
void EmitAnim(void);
void EmitSelfObject(void);
void EmitLevelObject(void);
void EmitAnimObject(void);
void EmitGameRef(void);
void EmitEmptyArray(void);
void EmitCastFieldObject(uint32_t sourcePos);
void EmitEvalArray(uint32_t firstSourcePos,
                   uint32_t secondSourcePos);
void EmitEvalArrayRef(uint32_t firstSourcePos,
                      uint32_t secondSourcePos);
void EmitClearArray(uint32_t firstSourcePos,
                    uint32_t secondSourcePos);
void EmitFieldVariable(
    coduo_scr_ast_node_t *objectNode, uint16_t string,
    uint32_t sourcePos);
void EmitFieldVariableRef(
    coduo_scr_ast_node_t *objectNode, uint16_t string,
    uint32_t sourcePos);
void EmitSetVariableField(uint32_t sourcePos);
void EmitSafeSetVariableField(uint16_t string,
                              uint32_t sourcePos);
void EmitSafeSetWaittillVariableField(uint16_t string,
                                      uint32_t sourcePos);
void EmitClearLocalVariable(uint16_t string);
void EmitAnimation(
    uint16_t string, uint32_t sourcePos);
void EmitClearFieldVariable(
    coduo_scr_ast_node_t *objectNode, uint16_t string,
    uint32_t objectSourcePos,
    uint32_t opcodeSourcePos);
void EmitCallRef(coduo_scr_ast_node_t *nameNode,
                 coduo_scr_ast_list_t *argsNode,
                 uint32_t sourcePos);
void EmitMethodRef(
    coduo_scr_ast_node_t *objectNode, coduo_scr_ast_node_t *nameNode,
    coduo_scr_ast_list_t *argsNode, uint32_t sourcePos);
void EmitCastBool(uint32_t sourcePos);
void EmitCastInt(uint32_t sourcePos);
void EmitCastFloat(uint32_t sourcePos);
void EmitCastString(uint32_t sourcePos);
void EmitBoolNot(uint32_t sourcePos);
void EmitBoolComplement(uint32_t sourcePos);
void EmitSize(coduo_scr_ast_node_t *node,
              uint32_t sourcePos);
void CompileError(uint32_t sourcePos,
                  const char *message, ...);
int32_t yylex(void);
int32_t yyparse(void);
int32_t yyerror(void);
void yy_init_buffer(coduo_script_yy_buffer_t *buffer, FILE *inputFile);
sval_u *
node1_(sval_u *out,
       coduo_script_yystype_word_t word);
sval_u *
node_pos(sval_u *out,
         coduo_script_yystype_word_t word);
sval_u *
node0(sval_u *out,
                      coduo_script_yystype_word_t word0);
sval_u *
node1(sval_u *out,
                   coduo_script_yystype_word_t word0,
                   coduo_script_yystype_word_t word1);
sval_u *
node2(sval_u *out,
                   coduo_script_yystype_word_t word0,
                   coduo_script_yystype_word_t word1,
                   coduo_script_yystype_word_t word2);
sval_u *
node2_(sval_u *out,
                  coduo_script_yystype_word_t word0,
                  coduo_script_yystype_word_t word1);
sval_u *
node3(sval_u *out,
                   coduo_script_yystype_word_t word0,
                   coduo_script_yystype_word_t word1,
                   coduo_script_yystype_word_t word2,
                   coduo_script_yystype_word_t word3);
sval_u *
node4(sval_u *out,
                   coduo_script_yystype_word_t word0,
                   coduo_script_yystype_word_t word1,
                   coduo_script_yystype_word_t word2,
                   coduo_script_yystype_word_t word3,
                   coduo_script_yystype_word_t word4);
sval_u *
node5(sval_u *out,
                   coduo_script_yystype_word_t word0,
                   coduo_script_yystype_word_t word1,
                   coduo_script_yystype_word_t word2,
                   coduo_script_yystype_word_t word3,
                   coduo_script_yystype_word_t word4,
                   coduo_script_yystype_word_t word5);
sval_u *
node6(sval_u *out,
                   coduo_script_yystype_word_t word0,
                   coduo_script_yystype_word_t word1,
                   coduo_script_yystype_word_t word2,
                   coduo_script_yystype_word_t word3,
                   coduo_script_yystype_word_t word4,
                   coduo_script_yystype_word_t word5,
                   coduo_script_yystype_word_t word6);
sval_u *
linked_list_end(sval_u *out,
                      coduo_script_yystype_word_t value);
sval_u *
prepend_node(sval_u *out,
                         coduo_script_yystype_word_t value,
                         coduo_script_yystype_word_t headValue);
sval_u *
append_node(sval_u *out,
                        coduo_script_yystype_word_t listValue,
                        coduo_script_yystype_word_t value);
void ScriptYy_SetLowercaseStringToken(const char *text, int32_t length);
void ScriptYy_SetEscapedStringToken(const char *text, int32_t length);
void ScriptYy_SetIntToken(const char *text);
void ScriptYy_SetFloatToken(const char *text);
void Scr_InitDeveloperOpcodes(void);
void Scr_InsertDeveloperOpcodes(void);
void Scr_ShutdownDeveloperOpcodes(void);
void EmitStatement(coduo_scr_ast_node_t *node);
void EmitStatementList(coduo_scr_ast_statement_block_t *block);
void Scr_TransferToDeveloperBuffer(void);
void EmitPrimitiveExpression(coduo_scr_ast_node_t *node);
void EmitExpression(coduo_scr_ast_node_t *node);
void EmitArrayExpressionRef(
    coduo_scr_ast_node_t *node, uint32_t sourcePos);
void Scr_TransferStatementListToDeveloperBuffer(void);
void ConnectBreakStatements(void);
void ConnectContinueStatements(void);
void EmitPrimitiveExpressionFieldObject(coduo_scr_ast_node_t *node,
                                        uint32_t sourcePos);
void EmitFunction(coduo_scr_ast_node_t *node,
                  uint32_t sourcePos);
void AdjustFunctionAddresses(void);
void SpecifyThreadPosition(uint16_t functionObject,
                           uint32_t sourcePos);
void SpecifyDeveloperThreadPosition(uint16_t functionObject,
                                    uint32_t sourcePos);
void SetThreadPosition(uint16_t functionObject,
                       uint32_t sourcePos);
void SetDeveloperThreadPosition(
    uint16_t functionObject,
    uint32_t sourcePos);
void EmitVariableExpression(coduo_scr_ast_node_t *node);
void EmitGetFunction(coduo_scr_ast_node_t *nameNode,
                     uint32_t sourcePos);
int32_t EmitExpressionList(coduo_scr_ast_list_t *list);
coduo_scr_ast_list_item_t *
GetSingleParameter(coduo_scr_ast_list_t *list);
void AddExpressionListOpcodePos(coduo_scr_ast_list_t *list);
void EmitFormalParameterListRefInternal(coduo_scr_ast_list_item_t *item);
void EmitDeveloperStatementList(coduo_scr_ast_statement_block_t *block,
                                uint32_t sourcePos);
void EmitArrayVariableRef(coduo_scr_ast_node_t *arrayNode,
                          coduo_scr_ast_node_t *indexNode,
                          uint32_t arraySourcePos,
                          uint32_t indexSourcePos);
void EmitClearArrayVariable(
    coduo_scr_ast_node_t *arrayNode, coduo_scr_ast_node_t *indexNode,
    uint32_t arraySourcePos,
    uint32_t indexSourcePos);
void EmitVariableExpressionRef(coduo_scr_ast_node_t *node);
void EmitBinaryEqualsOperatorExpression(coduo_scr_ast_node_t *refNode,
                                        coduo_scr_ast_node_t *valueNode,
                                        uint8_t opcode,
                                        uint32_t sourcePos);
void EmitCallExpression(coduo_scr_ast_node_t *node, qboolean emitDropTop);
void EmitPreFunctionCall(coduo_scr_ast_node_t *callNode);
void EmitPostFunctionCall(coduo_scr_ast_node_t *callNode,
                          int32_t argumentCount,
                          qboolean hasMethodContext);
void EmitCall(coduo_scr_ast_node_t *nameNode,
              coduo_scr_ast_list_t *argsNode,
              qboolean emitDropTop);
void EmitMethod(coduo_scr_ast_node_t *objectNode,
                coduo_scr_ast_node_t *nameNode,
                coduo_scr_ast_list_t *argsNode,
                uint32_t sourcePos,
                qboolean emitDropTop);
qboolean Scr_IsIdentifier(const char *text);
void Scr_BeginLoadAnimTrees(void);
void Scr_EndLoadAnimTrees(void);
void Scr_EndLoadScripts(void);
qboolean Scr_LoadScript(const char *filename);
void Scr_EmitAnimation(char *animRef, uint16_t string,
                       uint32_t sourcePos);
void Scr_EmitAnimationInternal(char *animRef, uint16_t animHandle,
                               uint16_t treeHandle, uint32_t sourcePos);

#endif
