I'm fairly new to C++. Currently I'm trying to contend with a myriad of compiler errors. I couldn't find the root cause nor could do I understand why/how they were invoked. I'd also like to know how to avoid or better handle this kind of situation in the future.
This is for an interpreter I'm writing, though I'm only finished with the garbage collection/variable handling portions.
garbage.h
#pragma once
#ifndef GARBAGE
#define GARBAGE
#include <stack>
#include "value.h"
#include "runtime.h"
class garbage_collector {
public:
garbage_collector();
~garbage_collector();
//initializes a new garbage collection frame
void new_frame();
//creates a new variable apartment within the garbage collector
variable_apartment* new_apartment(value* initial_value, bool reference_once=false);
//de-allocates unused variable appartments within the current garbage collection frame
unsigned int sweep();
private:
unsigned int size;
variable_apartment* head;
variable_apartment* tail;
std::stack<variable_apartment*> sweep_frames;
};
#endif // !GARBAGE
garbage.cpp
#include "garbage.h"
garbage_collector::garbage_collector() {
this->size = 0;
this->head = nullptr;
this->sweep_frames = std::stack<variable_apartment*>();
}
garbage_collector::~garbage_collector() {
while (size > 0)
{
sweep();
}
}
void garbage_collector::new_frame() {
this->sweep_frames.push(tail);
}
variable_apartment* garbage_collector::new_apartment(value* initial_value, bool reference_once) {
if (size == 0) {
size++;
return (tail = (head = new variable_apartment(initial_value, reference_once ? 1 : 0)));
}
else {
size++;
tail->next_apartment = new variable_apartment(initial_value, reference_once ? 1 : 0);
tail = tail->next_apartment;
return tail;
}
}
unsigned int garbage_collector::sweep() {
unsigned int destroyed_values = 0;
variable_apartment* current = sweep_frames.empty() ? head : sweep_frames.top()->next_apartment;
variable_apartment* previous = sweep_frames.empty() ? nullptr : sweep_frames.top();
while (current != nullptr)
{
if (current->references == 0) {
variable_apartment* to_delete = current;
current = current->next_apartment;
if (previous == nullptr)
head = current;
else
previous->next_apartment = current;
delete to_delete;
size--;
destroyed_values++;
}
else {
previous = current;
current = current->next_apartment;
}
}
if (!sweep_frames.empty())
sweep_frames.pop();
return destroyed_values;
}
runtime.h
#pragma once
#ifndef RUNTIME_H
#define RUNTIME_H
#include "value.h"
#include "garbage.h"
//handles initialization and disposal of all program values
class variable_apartment {
public:
value* value;
unsigned int references;
variable_apartment(class value* value, unsigned int references = 0, variable_apartment* next_apartment = nullptr);
~variable_apartment();
variable_apartment* next_apartment;
};
class variable_bucket {
public:
unsigned long id_hash;
variable_apartment* apartment;
variable_bucket(unsigned long id_hash, variable_apartment* apartment, variable_bucket* next_bucket = nullptr);
variable_bucket* next_bucket;
};
#define VARIABLE_HASH_BUCKET_SIZE 200
class variable_manager {
public:
variable_manager(garbage_collector* garbage_collector);
~variable_manager();
variable_apartment* declare_var(unsigned long id_hash, value* value);
void remove_var(unsigned long id_hash);
private:
unsigned int size;
garbage_collector* garbage_collector;
variable_bucket* hash_buckets[VARIABLE_HASH_BUCKET_SIZE];
};
#endif // !RUNTIME_H
runtime.cpp
#include "runtime.h"
#include "errors.h"
#include "hash.h"
variable_apartment::variable_apartment(class value* value, unsigned int references, variable_apartment* next_apartment) {
this->value = value;
this->references = references;
this->next_apartment = next_apartment;
}
variable_apartment::~variable_apartment() {
delete value;
}
variable_bucket::variable_bucket(unsigned long id_hash, variable_apartment* apartment, variable_bucket* next_bucket) {
this->id_hash = id_hash;
this->apartment = apartment;
this->next_bucket = next_bucket;
}
variable_manager::variable_manager(class garbage_collector* garbage_collector) {
this->size = 0;
this->garbage_collector = garbage_collector;
for (size_t i = 0; i < VARIABLE_HASH_BUCKET_SIZE; i++)
{
hash_buckets[i] = nullptr;
}
}
variable_manager::~variable_manager() {
for (size_t i = 0; i < VARIABLE_HASH_BUCKET_SIZE; i++)
{
if (hash_buckets[i] != nullptr) {
variable_bucket* current = hash_buckets[i];
while (current != nullptr)
{
variable_bucket* to_delete = current;
to_delete->apartment--;
delete to_delete;
current = current->next_bucket;
}
}
}
}
variable_apartment* variable_manager::declare_var(unsigned long id_hash, value* value) {
variable_bucket* bucket = hash_buckets[id_hash % VARIABLE_HASH_BUCKET_SIZE];
variable_bucket* parent = nullptr;
while (bucket != nullptr) {
if (bucket->id_hash == id_hash)
throw ERROR_VARIABLE_ALREADY_DEFINED;
parent = bucket;
bucket = bucket->next_bucket;
}
if (parent == nullptr)
return (hash_buckets[id_hash % VARIABLE_HASH_BUCKET_SIZE] = new variable_bucket(id_hash, garbage_collector->new_apartment(value, true)))->apartment;
else
return (parent->next_bucket = new variable_bucket(id_hash, garbage_collector->new_apartment(value, true)))->apartment;
}
void variable_manager::remove_var(unsigned long id_hash) {
variable_bucket* bucket = hash_buckets[id_hash % VARIABLE_HASH_BUCKET_SIZE];
variable_bucket* parent = nullptr;
while (bucket != nullptr)
{
if (bucket->id_hash == id_hash) {
break;
}
parent = bucket;
bucket = bucket->next_bucket;
}
if (bucket == nullptr)
throw ERROR_VARIABLE_NOT_DEFINED;
if (parent == nullptr)
hash_buckets[id_hash % VARIABLE_HASH_BUCKET_SIZE] = bucket->next_bucket;
else
parent->next_bucket = bucket->next_bucket;
bucket->apartment->references--;
delete bucket;
}
value.h, though I'm think this portion doesn't have any actual errors.
#pragma once
#ifndef VALUE_H
#define VALUE_H
#define VALUE_TYPE_NULL 0
#define VALUE_TYPE_CHAR 1
#define VALUE_TYPE_NUMERICAL 2
#define VALUE_TYPE_COLLECTION 3
class value {
public:
char type;
void* ptr;
value(const value& value);
value(char type, void* ptr);
~value();
};
class collection {
public:
unsigned long size;
value** inner_collection;
collection(const collection& collection);
collection(unsigned long size);
~collection();
};
#endif // !VALUE_H
value.cpp
#include "errors.h"
#include "value.h"
#include "runtime.h"
#define MAX_VALUE_TYPE 3
value::value(const value& value) {
this->type = value.type;
switch (this->type)
{
case VALUE_TYPE_NULL:
this->ptr = nullptr;
break;
case VALUE_TYPE_CHAR:
this->ptr = new char(*(char*)value.ptr);
break;
case VALUE_TYPE_NUMERICAL:
this->ptr = new double(*(double*)value.ptr);
break;
case VALUE_TYPE_COLLECTION:
this->ptr = new double(*(double*)value.ptr);
break;
default:
throw ERROR_INVALID_VALUE_TYPE;
}
}
value::value(char type, void* ptr) {
if (type > MAX_VALUE_TYPE) {
throw ERROR_INVALID_VALUE_TYPE;
}
this->type = type;
this->ptr = ptr;
}
value::~value() {
switch (this->type)
{
case VALUE_TYPE_CHAR:
delete ((char*)this->ptr);
break;
case VALUE_TYPE_NUMERICAL:
delete ((double*)this->ptr);
break;
case VALUE_TYPE_COLLECTION:
delete ((collection*)this->ptr);
break;
default:
throw ERROR_INVALID_VALUE_TYPE;
}
}
collection::collection(const collection& collection) {
this->size = collection.size;
this->inner_collection = new value * [this->size];
for (unsigned long i = 0; i < collection.size; i++)
{
this->inner_collection[i] = collection.inner_collection[i];
}
}
collection::collection(unsigned long size) {
this->size = size;
this->inner_collection = new value * [size];
}
collection::~collection() {
delete this->inner_collection;
}
And here are the 41 compiler errors I'm getting
Severity Code Description Project File Line Suppression State
Error C2061 syntax error: identifier 'garbage_collector' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\runtime.h 32
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\runtime.h 38
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\runtime.h 38
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\runtime.h 38
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 19
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 19
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 19
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 25
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 25
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 25
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 26
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 26
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 26
Error C2065 'variable_apartment': undeclared identifier quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 27
Error C2059 syntax error: '>' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 27
Error C2039 'new_apartment': is not a member of 'garbage_collector' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\runtime.cpp 56
Error C2664 'variable_bucket::variable_bucket(const variable_bucket &)': cannot convert argument 1 from 'unsigned long' to 'const variable_bucket &' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\runtime.cpp 56
Error C2039 'new_apartment': is not a member of 'garbage_collector' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\runtime.cpp 58
Error C2664 'variable_bucket::variable_bucket(const variable_bucket &)': cannot convert argument 1 from 'unsigned long' to 'const variable_bucket &' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\runtime.cpp 58
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 19
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 19
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 19
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 25
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 25
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 25
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 26
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 26
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 26
Error C2065 'variable_apartment': undeclared identifier quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 27
Error C2059 syntax error: '>' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 27
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 19
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 19
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 19
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 25
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 25
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 25
Error C2143 syntax error: missing ';' before '*' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 26
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 26
Error C2238 unexpected token(s) preceding ';' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 26
Error C2065 'variable_apartment': undeclared identifier quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 27
Error C2059 syntax error: '>' quickscript C:\Users\Micha\source\repos\quickscript\quickscript\garbage.h 27