Skip to content

Instantly share code, notes, and snippets.

@dunkfordyce
Created July 2, 2019 16:28
Show Gist options
  • Save dunkfordyce/03f0fa14e2ab5b026cfc9dea105b996a to your computer and use it in GitHub Desktop.
Save dunkfordyce/03f0fa14e2ab5b026cfc9dea105b996a to your computer and use it in GitHub Desktop.
// classes example
// g++ -static-libgcc -static-libstdc++ main.cpp -o main.exe
#include <iostream>
#include <map>
#include <vector>
using namespace std;
class Object {
static vector<Object*> all_objects;
int refcount = 0;
public:
Object() {
all_objects.push_back(this);
cout << "created " << typeid(this).name() << '\n';
}
void incRef() { refcount ++ ; }
void decRef() { refcount -- ; }
static void gc() {
for (const auto & t : all_objects) {
if( t->refcount == 0 ) {
cout << "free'ing obj\n";
delete t;
}
}
}
virtual string toString()=0;
virtual int toInt()=0;
virtual Object* add(Object* other)=0;
virtual float toDouble() {
throw "no toDouble";
}
};
vector<Object*> Object::all_objects;
class Float : public Object {
public:
float val;
static Float* create(float val) {
Float *ret = new Float(val);
return ret;
}
Float(float in_val) {
val = in_val;
}
string toString() {
return std::to_string(val);
}
int toInt() {
return int(val);
}
float toDouble() {
return val;
}
Object* add(Object* other) {
return new Float(this->val + other->toDouble());
}
};
class Int : public Object {
int val;
public:
static Int* create(int val) {
Int *ret = new Int(val);
return ret;
}
Int(int in_val) {
val = in_val;
}
string toString() {
return std::to_string(val);
}
int toInt() {
return val;
}
float toDouble() {
return float(val);
}
Object* add(Object* other) {
Float* other_is_float = dynamic_cast<Float*>(other);
if( other_is_float != NULL ) {
return new Float(this->val + other_is_float->toDouble());
}
int other_val = other->toInt();
return new Int(this->val + other_val);
}
};
class String : public Object {
string val;
public:
static String* create(string val) {
String* ret = new String(val);
return ret;
}
String(string in_val) {
val = in_val;
}
string toString() {
return val;
}
int toInt() {
throw "cant cast string to int";
}
Object* add(Object* other) {
return new String(val + (other->toString()));
}
};
class Stack {
std::map<string,Object*> objects;
Stack* parent = NULL;
public:
~Stack() {
std::map<string, Object*>::iterator it = objects.begin();
while (it != objects.end())
{
Object* object = it->second;
object->decRef();
it++;
}
}
Object* set(string name, Object* object) {
if( objects.count(name) > 0) {
objects[name]->decRef();
}
objects[name] = object;
object->incRef();
return object;
}
Object* get(string name) {
if( objects.count(name) == 0) {
if( parent != NULL ) {
return parent->get(name);
} else {
throw "no such object " + name;
}
}
return objects[name];
}
};
int main () {
try {
// Object* a = Int::create(2);
// Object* b = String::create("hello");
// Object* c = Int::create(5);
// Object* d = a->add(c);
// Object* e = b->add(a)->add(c)->add(d);
// cout << "a->toString() " << a->toString() << '\n';
// cout << "b->toString() " << b->toString() << '\n';
// cout << "c->toString() " << c->toString() << '\n';
// cout << "d->toString() " << d->toString() << '\n';
// cout << "e->toString() " << e->toString() << '\n';
Stack* stack = new Stack;
stack->set("i", Int::create(2));
stack->set("2", Int::create(1));
cout << "result " << stack->get("i")->add(stack->get("2"))->toString() << '\n';
delete stack;
Object::gc();
// Object* a = Float::create(1.0f);
// Object* b = Int::create(3);
// cout << a->add(b)->toString() << '\n';
// cout << b->add(a)->toString() << '\n';
// cout << b->add(b)->toString() << '\n';
} catch (const char *msg) {
cout << "errored with " << msg;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment