haikal uses metaprogramming code gen to generate C code as a pre-build step.
haikal monomorphises C files and writes them to be included.
basically search & replace "TYPE" with your type.
Code should be easy to debug & works great with LSPs.
The i32
in this instance could be any data type:
// haikal@Array:i32:p
Array_i32 array = array_i32_create(12);
array.data[0] = 0x19;
array_i32_destroy(&array);
metatype_TYPE.h // public API
metatype_TYPE_internal.h // private API
metatype_TYPE.c // implementation
- Add
haikal
as a git submodule to your project and build the program. - Add
haikal.toml
to your project root. - Add
include_directories(extern/haikal/src/meta/gen)
to yourCMakeLists.txt
.
- To generate the files to
metapath
, build and invoke thehaikal
program from the your root directory. - To generate custom types, add a
// haikal@metatype:typename:s
in your code & simply include the headers. #include <Array.h>
to include all generatedhkArray
types public APIs.#include <Array.c>
to include all generatedhkArray
implementations preferably after yourmain()
.
Haikal uses toml for configuration. For example:
[core]
metapath = "extern/haikal/src/meta/"
mainpath = "src/main.c"
- Array: growable heap allocated array.
- List/hkNode: singly linked list.
- DList/hkBiNode: doubly linked list.
- Stack/hkNode: stack.
- Queue: queue.
- HashMap: hashtable.
- Cannot instantiate pointer types to
metatype
s unlesstypedef
ed.
For example:
int *
will becometypedef int *intptr
and then you can generateArray_intptr
.
Possible Solution:
Could automate the process by detecting the pointer and autotypedef
ing it. - In the instatiation declaration, you must hint to
haikal
the type you want to instantiate:
s
for structe
for enump
for primitives or pointersu
for union.
Possible Solution:
Detect the type being instantiated, this is non trivial unless we include the compiler to get type information.
For containers that have value types eg T
:
- the type must be included before the generated header.
- this is because the container expects to know the type in it's struct.
- Warning: cannot be recursive type
For containers that have pointer types eg T *
:
- the type can be included before or after the generated header.
- this is because the container has
T
forward declared. - Warning: can be recursive type
For types that include a container of themselves eg struct T { Array_T arr; };
:
- the type must be included after the generated header.
- this is because the type needs to know the container definition.
- Warning: can be recursive type with
T *
but notT
Possible Solition: Automate header placement, will probably need the compiler to scan the types being instantiated.