<commit_before>#include "memory.h"
#include <string.h>
#include "error.h"
#include <stdio.h>
#include <stdlib.h>
#include "macros.h"

// Memory.c, provides functions for the interpreter to manipulate the local 
//   WendyScript memory

// A TOKEN IS 1032 BYTES, we allow 128mb of Memory
// 128mb * 1024kb/mb * 1024b/kb = 134217728 bytes = 129055.5 Tokens in 128 MB
// Lets choose an arbitrary closest prime because why not: 129061
address frame_pointer = 0;
address stack_pointer = 0;
address memory_pointer = 0;
address arg_pointer = 0;
address closure_list_pointer = 0;

static const char FUNCTION_START_CHAR = '>';
static const char AUTOFRAME_START_CHAR = '<';
static const char RA_START_CHAR = '#';
bool enable_gc = true;

// pointer to the end of the main frame
address main_end_pointer = 0; 

bool garbage_collect(int size) {
	if (!enable_gc) { return has_memory(size); }
	// Garbage! We'll implement the most basic mark and sweep algo.
	bool *marked = calloc(MEMORY_SIZE, sizeof(bool));
	for (int i = 0; i < RESERVED_MEMORY; i++) {
		// Don't delete the reserved ones!
		marked[i] = true;
	}
	for (int i = 0; i < stack_pointer; i++) {
		if (call_stack[i].id[0] != FUNCTION_START_CHAR && 
			call_stack[i].id[0] != AUTOFRAME_START_CHAR) {

			address a = call_stack[i].val;
			// Check for array header because we need to mark all of the size.
			int block_size = 1;
			if (memory[a].t_type == LIST || memory[a].t_type == STRUCT) {
				marked[a] = true;
				// Traverse to list header.
				a = memory[a].t_data.number;
				block_size += memory[a].t_data.number;
			}
			else if (memory[a].t_type == STRUCT_INSTANCE) {
				marked[a] = true;
				// This means that the original struct metadata must also
				//   persist as well as the corresponding fields.
				address metadata = memory[a].t_data.number;
				/* TODO */
			}
			// We'll mark the location it points to. If it's an address, we'll
			//   recursively mark that one too.
			for (int j = 0; j < block_size; j++) marked[a + j] = true;
			while (memory[a].t_type == ADDRESS) {
				a = memory[a].t_data.number;
				marked[a] = true;
			}
		}
	}

	for (int i = 0; i < MEMORY_SIZE; i++) {
		if (!marked[i]) {
			here_u_go(i, 1);
		}
	}
//	print_free_memory();
	free(marked);
	return has_memory(size);
}

address create_closure() {
	address location = closure_list_pointer;
	// Things to reserve.
	size_t size = stack_pointer - main_end_pointer;	
	if (size <= 0) return -1;
	stack_entry* closure = malloc(sizeof(stack_entry) * size);
	size_t actual_size = 0;
	for (int i = main_end_pointer; i < stack_pointer; i++) {
		if (call_stack[i].id[0] == FUNCTION_START_CHAR ||
			call_stack[i].id[0] == AUTOFRAME_START_CHAR ||
			call_stack[i].id[0] == RA_START_CHAR) {
		}
		else {
			strcpy(closure[actual_size].id, call_stack[i].id);
			closure[actual_size].val = call_stack[i].val;
			actual_size++;
			//memcpy(&closure[actual_size++], 
			//	&call_stack[i], sizeof(stack_entry));
		}
	}
	stack_entry* reallocated_closure = realloc(closure, 
		actual_size * sizeof(stack_entry));
	if (reallocated_closure) {
		closure = reallocated_closure;
	}
	else {
		w_error(REALLOC_ERROR);
	}
	closure_list[closure_list_pointer] = closure;
	closure_list_sizes[closure_list_pointer] = actual_size;
	closure_list_pointer++;
	return location;
}

bool has_memory(int size) {
	// Do we have memory?? 
	mem_block* c = free_memory;
	mem_block* p = 0;
	while (c) {
		if (c->size >= size) {
			// Enough Room!
			return true;
		}
		else {
			if (c->size == 0) {
				// What is this free block doing here with size 0? Atrocious!
				if (p) p->next = c->next;
				else free_memory = c->next;  

				// Remove that memory block!
				free(c);<commit_msg>fixed realloc error on uwaterloo server<commit_after>#include "memory.h"
#include <string.h>
#include "error.h"
#include <stdio.h>
#include <stdlib.h>
#include "macros.h"

// Memory.c, provides functions for the interpreter to manipulate the local 
//   WendyScript memory

// A TOKEN IS 1032 BYTES, we allow 128mb of Memory
// 128mb * 1024kb/mb * 1024b/kb = 134217728 bytes = 129055.5 Tokens in 128 MB
// Lets choose an arbitrary closest prime because why not: 129061
address frame_pointer = 0;
address stack_pointer = 0;
address memory_pointer = 0;
address arg_pointer = 0;
address closure_list_pointer = 0;

static const char FUNCTION_START_CHAR = '>';
static const char AUTOFRAME_START_CHAR = '<';
static const char RA_START_CHAR = '#';
bool enable_gc = true;

// pointer to the end of the main frame
address main_end_pointer = 0; 

bool garbage_collect(int size) {
	if (!enable_gc) { return has_memory(size); }
	// Garbage! We'll implement the most basic mark and sweep algo.
	bool *marked = calloc(MEMORY_SIZE, sizeof(bool));
	for (int i = 0; i < RESERVED_MEMORY; i++) {
		// Don't delete the reserved ones!
		marked[i] = true;
	}
	for (int i = 0; i < stack_pointer; i++) {
		if (call_stack[i].id[0] != FUNCTION_START_CHAR && 
			call_stack[i].id[0] != AUTOFRAME_START_CHAR) {

			address a = call_stack[i].val;
			// Check for array header because we need to mark all of the size.
			int block_size = 1;
			if (memory[a].t_type == LIST || memory[a].t_type == STRUCT) {
				marked[a] = true;
				// Traverse to list header.
				a = memory[a].t_data.number;
				block_size += memory[a].t_data.number;
			}
			else if (memory[a].t_type == STRUCT_INSTANCE) {
				marked[a] = true;
				// This means that the original struct metadata must also
				//   persist as well as the corresponding fields.
				address metadata = memory[a].t_data.number;
				/* TODO */
			}
			// We'll mark the location it points to. If it's an address, we'll
			//   recursively mark that one too.
			for (int j = 0; j < block_size; j++) marked[a + j] = true;
			while (memory[a].t_type == ADDRESS) {
				a = memory[a].t_data.number;
				marked[a] = true;
			}
		}
	}

	for (int i = 0; i < MEMORY_SIZE; i++) {
		if (!marked[i]) {
			here_u_go(i, 1);
		}
	}
//	print_free_memory();
	free(marked);
	return has_memory(size);
}

address create_closure() {
	address location = closure_list_pointer;
	// Things to reserve.
	size_t size = stack_pointer - main_end_pointer;	
	
	stack_entry* closure = malloc(sizeof(stack_entry) * size);
	size_t actual_size = 0;
	for (int i = main_end_pointer; i < stack_pointer; i++) {
		if (call_stack[i].id[0] == FUNCTION_START_CHAR ||
			call_stack[i].id[0] == AUTOFRAME_START_CHAR ||
			call_stack[i].id[0] == RA_START_CHAR) {
		}
		else {
			strcpy(closure[actual_size].id, call_stack[i].id);
			closure[actual_size].val = call_stack[i].val;
			actual_size++;
			//memcpy(&closure[actual_size++], 
			//	&call_stack[i], sizeof(stack_entry));
		}
	}
	if (actual_size <= 0) return -1;
	stack_entry* reallocated_closure = realloc(closure, 
		actual_size * sizeof(stack_entry));
	if (reallocated_closure) {
		closure = reallocated_closure;
	}
	else {
		w_error(REALLOC_ERROR);
	}
	closure_list[closure_list_pointer] = closure;
	closure_list_sizes[closure_list_pointer] = actual_size;
	closure_list_pointer++;
	return location;
}

bool has_memory(int size) {
	// Do we have memory?? 
	mem_block* c = free_memory;
	mem_block* p = 0;
	while (c) {
		if (c->size >= size) {
			// Enough Room!
			return true;
		}
		else {
			if (c->size == 0) {
				// What is this free block doing here with size 0? Atrocious!
				if (p) p->next = c->next;
				else free_memory = c->next;  

				// Remove that memory block!
				free(c);
{'fraction_non_alphanumeric': 0.13470103927655555, 'fraction_numerical': 0.017816169523552437, 'mean_word_length': 3.5293398533007334, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2915138', 'n_tokens_mistral': 3048, 'n_tokens_neox': 2662, 'n_words': 734}