Skip to content

Using C's header files, make a bqn file containing all functions in the header as ffi functions.

Notifications You must be signed in to change notification settings

Brian-ED/c-header-to-bqn-ffi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

74 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C-headers to BQN FFI

parse.bqn is the main file, used on a header file to autogenerate bqn ffi code.

For how to use, you can look in examples. You may look at comments in parse.bqn for how each function works.

For documentation on FFI in BQN, look in https://mlochbaum.github.io/BQN/spec/system.html#foreign-function-interface

Output ffi file

The outputted bqn code has some special code alongside your ffi functions. First, it automatically terminates null-terminating strings (type "*i8:c8") with null. This is to make using c-strings more seamless and less error prone. The outputted ffi file also has error handling, and allows giving 𝕨 to the MakeImporter function, and if 𝕨 is 1 then it prints every use of an ffi function. Like super print debugging.

The functions may have some duplicates, with names ending with Ref or Raw. When a function name ends with Ref, and assuming no name collisions happened, the mutable pointers of the function are instead using &ptr in the decloration. In basic terms, you can give a bqn array instead of a pointer and the mutated result gets given instead of mutating input. There are plenty of reasons to use either version so both are left in the output. The Raw postfix means that a pointer's type was const, so type "*i8" can be used instead of a pointer, and you may want either option so both are left in.

Header file parsing

The parser scans input to get API information about defines, structs, aliases, enums, callbacks and functions. All data is divided into pieces, usually as strings.

CONSTRAINTS:

Functions are expected as a single line with the following structure:

  <retType> <name>(<paramType[0]> <paramName[0]>, <paramType[1]> <paramName[1]>);  <desc>

Be careful with functions broken into several lines, it breaks the process!

Structs are expected as several lines with the following form:

<desc>
typedef struct <name> {
    <fieldType[0]> <fieldName[0]>;  <fieldDesc[0]>
    <fieldType[1]> <fieldName[1]>;  <fieldDesc[1]>
    <fieldType[2]> <fieldName[2]>;  <fieldDesc[2]>
} <name>;

Enums are expected as several lines with the following form:

<desc>
typedef enum {
    <valueName[0]> = <valueInteger[0]>, <valueDesc[0]>
    <valueName[1]>,
    <valueName[2]>, <valueDesc[2]>
    <valueName[3]>  <valueDesc[3]>
} <name>;

NOTE: Multiple options are supported for enums:

  • If value is not provided, lastValue + 1 is assigned
  • Value description is optional

TODO list

  • Work on simplifying parse.bqn. It can be improved a ton.
  • Work on removing some constraints.
  • Work on inProgress/oneTimeUse.bqn, for users who may not know bqn and want to just make an ffi file right away.
  • progressively cut json handling out of ToFFI and ParseHeader and move it to ToPrettyJson, eventually being able to move ToPrettyJson to testing/test.bqn and cut it out entirely. Will cut code size by a ton.

Credits

  • raylib's raylib_parser.c was translated to bqn then modified. Without this, this project wouldn't exist. Big thanks to raylib!

About

Using C's header files, make a bqn file containing all functions in the header as ffi functions.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published