#ifndef SCRIPT_H
#define SCRIPT_H

#include <stdbool.h>

#include "vm/Arrays.h"
#include "vm/ByteCode.h"

#define SCRIPT_STACK_SIZE 1000
#define SCRIPT_ERROR_SIZE 256

typedef struct {
    char error[SCRIPT_ERROR_SIZE];
    ByteCode* code;
    int readIndex;
    char stack[SCRIPT_STACK_SIZE];
    int stackIndex;
    int stackVarIndex;
    int line;
    Arrays arrays;
} Script;

Script* sInit(ByteCode* code);
void sDelete(Script* sc);

void sRun(Script* sc);

void sError(Script* sc, const char* format, ...);
bool sPopInt(Script* sc, int* i);
bool sPushInt(Script* sc, int i);
bool sPopLong(Script* sc, long* l);
bool sPushLong(Script* sc, long l);
bool sPopFloat(Script* sc, float* f);
bool sPushFloat(Script* sc, float f);
bool sPopBool(Script* sc, bool* b);
bool sPushBool(Script* sc, bool b);

typedef void (*IntPrinter)(int);
void sSetIntPrinter(IntPrinter p);
typedef void (*LongPrinter)(long);
void sSetLongPrinter(LongPrinter p);
typedef void (*FloatPrinter)(float);
void sSetFloatPrinter(FloatPrinter p);
typedef void (*BoolPrinter)(bool);
void sSetBoolPrinter(BoolPrinter p);
typedef void (*PointerPrinter)(Pointer*);
void sSetPointerPrinter(PointerPrinter p);

#endif