seeya

Search:
Group by:
Source   Edit  

This module implements a primitive API to expose Nim code as a C header. It makes many assumptions based off my understanding of Nim's ABI. To use it simply annotate a procedure or global variable with {.exportc, dynlib, expose.} Most Nim builtin types are supported with the default hooks. If a type you want to use does not work create a proc toTypeDefs(T: typedesc[YourType]): string. This type populates the typedefs and adds any required headers In the case you need headers you should include them by doing headers.incl theHeader. For all children fields call addType(ChildType). That will append that type and add it to a type cache to prevent it from adding the typedef again. Next you likely also will need to write your own proc toCtype(T: typedesc[YourType], name: string, procArg: bool): string. That callback should return the C type for your type. name is the name of the parameter or variable that it was told to generate. procArg indicates whether it is a proc argument, this is important for things like Nim's implicit pass by reference. Finally when done you can do makeHeader("/path/to/header.h") this will concatenate and make the final header.

Example:

import seeya
when defined(genHeader):
  {.warning[UnsafeDefault]: off.}

const nameStr = "your_lib_prefix_$1"

static:
  setFormatter(nameStr)

{.pragma: exporter, cdecl, dynlib, exportc: nameStr.}
{.pragma: exporterVar, dynlib, exportc: nameStr.}

proc print_int_arr(oa: openArray[int]) {.exporter, expose.} =
  echo oa

proc add_int(a, b: int): int {.exporter, expose.} =
  a + b

var my_int {.exporterVar, expose.} = 100

type
  MyEnum = enum
    a
    b
    c

proc toTypeDefs(_: typedesc[MyEnum]): string =
  headers.incl "<stdio.h>" # Pretend it requires a specific header
  seeya.toTypeDefs(MyEnum) # call the original enum generator

proc toCType(_: typedesc[MyEnum], name: string, isProcArg: bool): string =
  # We're also pretending we need to make our own C type proc
  result = "enum "
  result.add ($MyEnum).formatName()
  result.add " "
  result.add name

makeHeader("mylib.h")
when defined(genHeader):
  static:
    discard staticExec("clang-format -i mylib.h")

Types

OpaqueRef[T] {.borrow: `.`.} = distinct T
Opaque refs do not emit any fields just a typedef void*. Source   Edit  
OpaqueSeq[T] = distinct seq[T]
Opaque seqs do not emit their entire struct, just the top level one. Source   Edit  
OpaqueString = distinct string
Opaque seqs do not emit their entire struct, just the top level one. Source   Edit  
Passes = enum
  Inferred, PassesByRef, PassesByCopy
Source   Edit  
TypedNimNode = NimNode
Source   Edit  

Vars

headers {.compileTime, used.}: HashSet[string]
Source   Edit  

Procs

proc addType(T: typedesc)
Source   Edit  
proc formatName(s: string): string {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc passesByRef(T: typedesc[object]): bool
Source   Edit  
proc setFormatter(formatter: static string) {.compileTime.}
Source   Edit  
proc toCName(s: string): string {....raises: [], tags: [], forbids: [].}
Converts a Nim type to a "valid" C identifier Uses simple replace dumb as hell Source   Edit  
proc toCType(__536871190: typedesc[cstring]; name: string; procArg: bool): string
Source   Edit  
proc toCType(__536871258: typedesc[string]; name: string; procArg: bool): string
Source   Edit  
proc toCType(__536871271: typedesc[float32]; name: string; procArg: bool): string
Source   Edit  
proc toCType(__536871277: typedesc[bool]; name: string; procArg: bool): string
Source   Edit  
proc toCType(__536871283: typedesc[char]; name: string; procArg: bool): string
Source   Edit  
proc toCType(__536871305: typedesc[OpaqueString]; name: string; isProcArg: bool): string
Source   Edit  
proc toCType(T: typedesc[object]; name: string; procArg: bool): string
Source   Edit  
proc toCType(T: typedesc[proc]; name: string; procArg: bool): string
Source   Edit  
proc toCType[Idx, T](__536871198: typedesc[array[Idx, T]]; name: string;
                     procArg: bool): string
Source   Edit  
proc toCType[T: distinct](__536871168: typedesc[T]; name: string; procArg: bool): string
Source   Edit  
proc toCType[T: enum](__536871356: typedesc[T]; name: string; procArg: bool): string
Source   Edit  
proc toCType[T: float or float64](__536871265: typedesc[T]; name: string;
                                  procArg: bool): string
Source   Edit  
proc toCType[T: range](__536871225: typedesc[T]; name: string; procArg: bool): string
Source   Edit  
proc toCType[T: SomeInteger](__536871213: typedesc[T]; name: string;
                             procArg: bool): string
Source   Edit  
proc toCType[T: tuple](t: typedesc[T]; name: string; procArg: bool): string
Source   Edit  
proc toCType[T](__536871184: typedesc[PtrOrRef[T]]; name: string; procArg: bool): string
Source   Edit  
proc toCType[T](__536871205: typedesc[set[T]]; name: string; procArg: bool): string
Source   Edit  
proc toCType[T](__536871232: typedesc[openArray[T]]; name: string; procArg: bool): string
Source   Edit  
proc toCType[T](__536871246: typedesc[seq[T]]; name: string; procArg: bool): string
Source   Edit  
proc toCType[T](__536871295: typedesc[OpaqueRef[T]]; name: string;
                isProcArg: bool): string
Source   Edit  
proc toCType[T](__536871317: typedesc[OpaqueSeq[T]]; name: string;
                isProcArg: bool): string
Source   Edit  
proc toTypeDefs(__536871252: typedesc[string]): string
Source   Edit  
proc toTypeDefs(__536871301: typedesc[OpaqueString]): string
Source   Edit  
proc toTypeDefs(T: typedesc[object]): string
Source   Edit  
proc toTypeDefs(T: typedesc[proc]): string
Source   Edit  
proc toTypeDefs(T: typedesc[tuple]): string
Source   Edit  
proc toTypeDefs[T: distinct](__536871163: typedesc[T]): string
Source   Edit  
proc toTypeDefs[T: enum](__536871347: typedesc[T]): string
Source   Edit  
proc toTypeDefs[T: not (object or distinct or tuple or enum)](__536871158: typedesc[
    T]): string
Source   Edit  
proc toTypeDefs[T](__536871239: typedesc[seq[T]]): string
Source   Edit  
proc toTypeDefs[T](__536871290: typedesc[OpaqueRef[T]]): string
Source   Edit  
proc toTypeDefs[T](__536871312: typedesc[OpaqueSeq[T]]): string
Source   Edit  

Macros

macro expose(t: untyped): untyped
Source   Edit  
macro makeHeader(location: static string)
Source   Edit