From 35d4e5159ad65dcfec163d3bfcb18450836df97a Mon Sep 17 00:00:00 2001 From: overflowerror Date: Sat, 15 Apr 2017 01:21:58 +0200 Subject: [PATCH] beginning of the readme --- README.md | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..adbec35 --- /dev/null +++ b/README.md @@ -0,0 +1,171 @@ +# CRAP-Libs +## C RApid Programming Libraries + +### What is this sh*t? +Some C-libraries that provide stuff like OOP or try-catch-constructions. + +## Wait... OOP in C? You mean C++, right? +Nope. Thanks to structs and preprocessor macros I managed to create a Java-like object-oriented environment with classes, superclasses and even interfaces (although interfaces are merely shortcuts for declaring all methods in the interface by hand). + +## Wow. Does that work on every system with every compiler? +Probably not. I used the GCC-specific function attributes and the pragma function to implement things like multiple catch blocks (I had to keep track of which classes are defined.) or interfaces which are not instance-able. + +### So, how can I use this... thing? +## oop.h +Well, using (defined) classes is really easy: + +```c +LinkedList_t list = new (LinkedList)(); +list->add(list, "Hello World"); +list->get(list, 0); +list->destruct(list); +``` + +The first parameter of every method call has to be the object itself. (Because the methods are basically function pointers which don't know where the original object is.) + +Each object should be destructed if it's no longer used. (I am going to implement a basic garbage collector someday.) + +Note the parentheses around the class name in the first line. I once had a version in which they were not necessary, but unfortunately there was something that prevented me from keeping that feature: C + +(For interested fellows: The `construct(class)` macro has to be called in order to construct an object. This macro evaluates to the name of the construct method of that class. Furthermore each class defined a 0-ary macro with the name of the class (e.g. `LinkedList`) which evaluated to `construct(class)`. But that approach handicapped debugging, because on errors (and some warnings) the class name macro gets evaluated in contexts it should not, e.g. function arguments.) + + +Defining classes is a bit more tricky. + +First the header file: +```c +// The following line registers the class. +extern class(TestClass, Object_class, (interfaces) {1 namely {Cloneable_class} }, true) { + // The name of the class is TestClass, it extends Object_class + // and has one interface (Cloneable_class). + // The last parameter (true) indicates that this class is instanceable. + + // Now let's define the datastructure. + // First (!) we need the super-object. + extends(Object_t); + + // Next we add the definitions from the interface. + implements(Cloneable); + + // At last the fields and methods of the class itself: + + const char* string; + + void (*set)(defclass TestClass*, const char* string); + const char* (*get)(defclass TestClass*); + + void (*destruct)(defclass TestClass*); +} + +// The following methods need to be "static": + +// the constructor +TestClass_t* method(TestClass, construct)(void); + +// the populate method (see source file) +void method(TestClass, populate)(TestClass_t*, class_t); +``` + +The source file: +```c +// The class itself should be defined in the source file. +// This is why in the header file the class is defined extern. +class_t TestClass_class; + +// Let's define the constructor. +TestClass_t* method(TestClass, construct)(void) { + throws(OutOfMemoryException_t); + // This method might throw a exception. See above. + + + // We now have to allocate the memory for the object. + // On how this works: See later (try.h). + sr_(TestClass_t* test = allocate_object(TestClass), NULL); + + // Call populate of TestClass on the object. + populate(TestClass)(test, TestClass_class); + + return test; +} + +// The clone method inherited from Cloneable. +// You might have to look up the interface definitions. +void* method(TestClass, clone)(void* this) { + throws(IllegalArgumentException_t, NullPointerException_t, OutOfMemoryException_t); + + // Check for NULL. + if (this == NULL) { + throwr(new (NullPointerException)(), NULL); + } + + // Check for class type. + // This will not fail if `this` is an object of an child class of TestClass. + if (!instanceof(this, TestClass_class)) { + throwr(new (IllegalArgumentException)("Argument is not of type TestClass."), NULL) + } + + TestClass_t* test = (TestClass_t*) this; + + sr_(TestClass_t* clone = new (TestClass)(), NULL); + + clone->string = test->string; + + return clone; +} + +// The following two methods are trivial. +void method(TestClass, set)(TestClass_t* this, const char* string) { + throws(NullPointerException_t); + + if (this == NULL) { + throw(new (NullPointerException)()); + } + + this->string = string; +} +const char* method(TestClass, get)(TestClass_t* this) { + throws(NullPointerException_t); + + if (this == NULL) { + throw(new (NullPointerException)()); + } + + return this->string; +} + +// The destructor: +void method(TestClass, destruct)(TestClass_t* this) { + throws(NullPointerException_t); + + if (this == NULL) { + throw(new (NullPointerException)()); + } + + // We don't have anything to destruct. + + // Call super destructor. + this->super.destruct((Object_t*) this); +} + +// Now the interesting part: The populate method. +void method(TestClass, populate)(TestClass_t* obj, class_t c) { + // This method basically does the setup of the object. + + // First of all we have to populate the super object. + // (In this case of type Object_t) + populate(Object)((Object_t*) obj, c); + + // Let's set up all fields and methods. + + obj->string = NULL; + + add_method(obj, TestClass, destruct); + add_method(obj, TestClass, clone); + add_method(obj, TestClass, set); + add_method(obj, TestClass, get); + + // Done. +} +``` + +TODO: the remaining 90 % of the readme (Don't judge me, it's half past 1 am and I have to get up early tomorrow.)