#pragma once

#include "toy_common.h"
#include "toy_ast.h"

//the 'escapes' are lists of data used for processing the 'break' and 'continue' keywords
typedef struct Toy_private_EscapeEntry_t {
	unsigned int addr; //the address to write *to*
	unsigned int depth; //the current depth
} Toy_private_EscapeEntry_t;

typedef struct Toy_private_EscapeArray {
	unsigned int capacity;
	unsigned int count;
	Toy_private_EscapeEntry_t data[];
} Toy_private_EscapeArray;

//not needed at runtime, so they can be bigger
#ifndef TOY_ESCAPE_INITIAL_CAPACITY
#define TOY_ESCAPE_INITIAL_CAPACITY 32
#endif

#ifndef TOY_ESCAPE_EXPANSION_RATE
#define TOY_ESCAPE_EXPANSION_RATE 4
#endif

Toy_private_EscapeArray* Toy_private_resizeEscapeArray(Toy_private_EscapeArray* ptr, unsigned int capacity);

//structure for holding the bytecode during compilation
typedef struct Toy_Bytecode {
	unsigned char* code; //the instruction set
	unsigned int codeCapacity;
	unsigned int codeCount;

	unsigned char* jumps; //each 'jump' is the starting address of an element within 'data'
	unsigned int jumpsCapacity;
	unsigned int jumpsCount;

	unsigned char* param; //each 'param' is the starting address of a name string within 'data'
	unsigned int paramCapacity;
	unsigned int paramCount;

	unsigned char* data; //a block of read-only data
	unsigned int dataCapacity;
	unsigned int dataCount;

	unsigned char* subs; //subroutines etc, built recursively
	unsigned int subsCapacity;
	unsigned int subsCount;

	//tools for handling the build process
	unsigned int currentScopeDepth;
	Toy_private_EscapeArray* breakEscapes;
	Toy_private_EscapeArray* continueEscapes;

	//compilation errors
	bool panic;
} Toy_Bytecode;

TOY_API unsigned char* Toy_compileToBytecode(Toy_Ast* ast);
