LIBCMT - A cross platform embedded DSL for C Language
LIBCMT is a small cross-platform, header-only DSL implemented through macros, providing standardized higher-level constructs for the C language.
TL;DR: A header-only macro-based DSL for C that provides higher-level constructs (OOP-style objects, try-catch blocks, inline-assembly helpers, etc.) using portable and architecture-specific preprocessor expansions.
Tested as far back as GCC 3.2 on Windows 2000. Planned support includes additional legacy platforms such as TRS-OS and OS/2.
I'm aware the documentation needs improvement and will expand it. For now, I'm looking for syntax ideas and architecture/compiler details to help extend the library to more platforms. Critical feedbacks are welcome.
Here's a short example demonstrating several of the provided features:
#include <stdio.h> /* For printf() */#define INCL__OBJECT#define INCL__TRY_CATCH#include "LIBCMT/LIBCMT.h"/* or without INCL__#:#include "LIBCMT/LIBCMT.h" // Defines everything automaticallyor#include "LIBCMT/OBJECT.h"#include "LIBCMT/KEYWORDS/TRY_CATCH.h"*/// User MUST use different commands depends on the CPU type.// For architectures, RCX or RAX like registers automatically downs to ECX or EAX but no alterantive exist,// compiler will throw an error when an unexisting command is used on a certain CPU architecture, type, or version.#include "LIBCMT/ASM/PUSH.h"#if defined(__unix__)SECTION (ASD) ADD64(RDI, RSI) MOV64(RAX, RDI) RETEND#elif defined(_WIN64)SECTION (ASD) ADD64(RCX, RDX) MOV64(RAX, RCX) RETEND#endif#include "LIBCMT/ASM/POP.h"extern int ASD(int, int);object o_object // Can be also "struct" too{ i_am_an_object; // Necessary and must be at the top void (*print)(); void (*add)(int); int value; void (*throw)(int);};void print(){ object__connect (o_object); // Needed for defining "this" printf("[%d]\n", this->value); throw (this->value); // Will do nothing if it's not inside a try {...};}void object_throw(int value) // Not used but still wanted to show an exmaple at the bottom{ object__connect (o_object); throw (value);}void add(int value){ object__connect (o_object); this->value += value;}void o_object(int start_value) // Constructor. Automatically works if object is created{ object__connect (o_object); object__inject (add); object__inject_2 (throw, object_throw); // this->throw = object_throw object__inject (print); // As you see, manual injection is needed for per function in the object. // Because, You may need to detect if a needed DLL file exist, and then get the needed function from it and use it in here. // Otherwise, you can just use your default function. this->value = start_value;}
#include <stdio.h> /* For printf() */#define INCL__OBJECT#define INCL__TRY_CATCH#include "LIBCMT/LIBCMT.h"/* or without INCL__#:#include "LIBCMT/LIBCMT.h" // Defines everything automaticallyor#include "LIBCMT/OBJECT.h"#include "LIBCMT/KEYWORDS/TRY_CATCH.h"*/// User MUST use different commands depends on the CPU type.// For architectures, RCX or RAX like registers automatically downs to ECX or EAX but no alterantive exist,// compiler will throw an error when an unexisting command is used on a certain CPU architecture, type, or version.#include "LIBCMT/ASM/PUSH.h"#if defined(__unix__)SECTION (ASD) ADD64(RDI, RSI) MOV64(RAX, RDI) RETEND#elif defined(_WIN64)SECTION (ASD) ADD64(RCX, RDX) MOV64(RAX, RCX) RETEND#endif#include "LIBCMT/ASM/POP.h"extern int ASD(int, int);object o_object // Can be also "struct" too{ i_am_an_object; // Necessary and must be at the top void (*print)(); void (*add)(int); int value; void (*throw)(int);};void print(){ object__connect (o_object); // Needed for defining "this" printf("[%d]\n", this->value); throw (this->value); // Will do nothing if it's not inside a try {...};}void object_throw(int value) // Not used but still wanted to show an exmaple at the bottom{ object__connect (o_object); throw (value);}void add(int value){ object__connect (o_object); this->value += value;}void o_object(int start_value) // Constructor. Automatically works if object is created{ object__connect (o_object); object__inject (add); object__inject_2 (throw, object_throw); // this->throw = object_throw object__inject (print); // As you see, manual injection is needed for per function in the object. // Because, You may need to detect if a needed DLL file exist, and then get the needed function from it and use it in here. // Otherwise, you can just use your default function. this->value = start_value;}
Your main script will look like that:
int main(void){ new (o_object, asd) (42); new (o_object, asd2) (0);/* or instead, you can also do: #define test(object_name) new (o_object, object_name) so you can use it as: test (asd) (42); which works like namespace in C++ or smthing idk*/ asd.add(33); // asd.value is now 84 try { int error; try { asd.print(); } catch (error) { printf("ERROR_1: %d\n", error); throw (-2); } } catch (int error2) // May create error on older compilers, so create error2 at the top like I did in the top try-catch { printf("ERROR_2: %d\n", error2); } asd2.print(); destroy (asd); destroy (asd2); // destroys are needed printf("Testing ASD function (Windows only btw because of the ABI rules): %d\n", ASD(42, 12)); return (0);}
int main(void){ new (o_object, asd) (42); new (o_object, asd2) (0);/* or instead, you can also do: #define test(object_name) new (o_object, object_name) so you can use it as: test (asd) (42); which works like namespace in C++ or smthing idk*/ asd.add(33); // asd.value is now 84 try { int error; try { asd.print(); } catch (error) { printf("ERROR_1: %d\n", error); throw (-2); } } catch (int error2) // May create error on older compilers, so create error2 at the top like I did in the top try-catch { printf("ERROR_2: %d\n", error2); } asd2.print(); destroy (asd); destroy (asd2); // destroys are needed printf("Testing ASD function (Windows only btw because of the ABI rules): %d\n", ASD(42, 12)); return (0);}
LIBCMT - A group of tools that you can use with all the features that the C programming language should have, within standard libraries, based on all compilers, CPUs, and operating systems. - Teoma...