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. It includes many components, so refer to the project documentation for the full list: https://github.com/TeomanDeniz/LIBCMT 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 automatically

or

#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)
RET
END
#elif defined(_WIN64)
SECTION (ASD)
ADD64(RCX, RDX)
MOV64(RAX, RCX)
RET
END
#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 automatically

or

#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)
RET
END
#elif defined(_WIN64)
SECTION (ASD)
ADD64(RCX, RDX)
MOV64(RAX, RCX)
RET
END
#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);
}
GitHub
GitHub - TeomanDeniz/LIBCMT: LIBCMT - A group of tools that you can...
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...
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?