generated from treeform/nimtemplate
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from guzba/master
internal generation
- Loading branch information
Showing
12 changed files
with
499 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +0,0 @@ | ||
# You can use this nim template to jump start your nim library or project. | ||
|
||
This template includes: | ||
* MIT licence | ||
* src directory and a private common.nim | ||
* test directory | ||
* GitHub Actions to run the tests on GitHub | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
version = "0.1.0" | ||
author = "Andre von Houck and Ryan Oldenburg" | ||
description = "Generate a shared library and bindings for many languages." | ||
license = "MIT" | ||
|
||
srcDir = "src" | ||
|
||
requires "nim >= 1.4.8" |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
import bindy/internal, bindy/common, macros, strformat, tables | ||
|
||
proc toggleBasicOnly*() = | ||
discard | ||
|
||
macro exportEnums*(body: typed) = | ||
for statement in body: | ||
for sym in statement: | ||
if sym.getImpl()[2].kind != nnkEnumTy: | ||
error( | ||
&"Enum export entry of unexpected kind {sym.getImpl()[2].kind}", | ||
sym | ||
) | ||
|
||
exportEnumInternal(sym) | ||
|
||
macro exportProcs*(body: typed) = | ||
for statement in body: | ||
let exportName = statement[0].repr | ||
|
||
var exported: int | ||
for procedure in statement: | ||
let procType = procedure.getTypeInst() | ||
if procType.kind != nnkProcTy: | ||
error( | ||
&"Proc exports statement of unexpected kind {procType.kind}", | ||
statement | ||
) | ||
|
||
if procType[0].len > 1: | ||
# Filter out overloads that are owned by objects | ||
let firstParam = procType[0][1][1] | ||
if firstParam.kind == nnkBracketExpr: | ||
continue | ||
let firstParamImpl = firstParam.getImpl() | ||
if firstParamImpl.kind == nnkTypeDef and | ||
firstParamImpl[2].kind != nnkEnumTy: | ||
continue | ||
|
||
exportProcInternal(procedure) | ||
inc exported | ||
|
||
if exported == 0: | ||
error( | ||
&"Proc export statement {exportName} does not export anything", | ||
statement | ||
) | ||
|
||
macro exportObjects*(body: typed) = | ||
for statement in body: | ||
for sym in statement: | ||
let objImpl = sym.getImpl()[2] | ||
if objImpl.kind != nnkObjectTy: | ||
error(&"Unexpected export object impl kind {objImpl.kind}", statement) | ||
|
||
let objType = sym.getType() | ||
for property in objType[2]: | ||
if not property.isExported: | ||
error(&"Unexported property on {sym.repr}", objType) | ||
|
||
let propertyTypeImpl = property.getTypeImpl() | ||
if propertyTypeImpl.repr notin basicTypes: | ||
if propertyTypeImpl.kind notin {nnkEnumTy, nnkObjectTy}: | ||
error( | ||
&"Object cannot export property of type {property[^2].repr}", | ||
propertyTypeImpl | ||
) | ||
|
||
exportObjectInternal(sym) | ||
|
||
macro exportRefObject*( | ||
sym: typed, whitelist: static[openarray[string]], body: typed | ||
) = | ||
let refImpl = sym.getImpl()[2] | ||
if refImpl.kind != nnkRefTy: | ||
error( | ||
&"Unexpected export ref object impl kind {refImpl.kind}", | ||
sym | ||
) | ||
|
||
var | ||
exportProcs: seq[NimNode] | ||
basicOnly = false | ||
for statement in body: | ||
if statement.kind == nnkDiscardStmt: | ||
continue | ||
|
||
if statement.kind == nnkCall: | ||
if statement[0].repr == "toggleBasicOnly": | ||
basicOnly = not basicOnly | ||
continue | ||
|
||
for procedure in statement: | ||
let procType = procedure.getTypeInst() | ||
if procType.kind != nnkProcTy: | ||
error( | ||
&"Ref object exports statement of unexpected kind {procType.kind}", | ||
procType | ||
) | ||
|
||
if procType[0].len <= 1: | ||
continue | ||
|
||
if procType[0][1][1].repr != sym.repr: | ||
var found = false | ||
|
||
let procImpl = procedure.getImpl() | ||
if procImpl[3][1][1].kind == nnkInfix: | ||
for choice in procImpl[3][1][1][1 .. ^1]: | ||
if choice.repr == sym.repr: | ||
found = true | ||
|
||
if not found: | ||
continue | ||
|
||
if basicOnly: | ||
var skip = false | ||
for paramType in procType[0][2 .. ^1]: | ||
if paramType[1].repr == "bool": | ||
continue | ||
if paramType[1].getImpl().kind == nnkNilLit: | ||
continue | ||
if paramType[1].getImpl().kind == nnkTypeDef: | ||
if paramType[1].getImpl()[2].kind == nnkEnumTy: | ||
continue | ||
skip = true | ||
break | ||
if skip: | ||
continue | ||
|
||
exportProcs.add(procedure) | ||
|
||
if exportProcs.len == 0: | ||
error( | ||
&"Ref object export statement {statement[0].repr} does not export anything", | ||
statement | ||
) | ||
|
||
var entries: CountTable[string] | ||
for exportProc in exportProcs: | ||
entries.inc(exportProc.repr) | ||
|
||
exportRefObjectInternal(sym, whitelist) | ||
|
||
for procedure in exportProcs: | ||
var prefixes = @[sym] | ||
if entries[procedure.repr] > 1: | ||
# If there are more than one procs with this name, add a second prefix | ||
let procType = procedure.getTypeInst() | ||
if procType[0].len > 2: | ||
prefixes.add(procType[0][2][1]) | ||
exportProcInternal(procedure, prefixes) | ||
|
||
macro exportSeq*(sym: typed, body: typed) = | ||
var exportProcs: seq[NimNode] | ||
for statement in body: | ||
if statement.kind == nnkDiscardStmt: | ||
continue | ||
|
||
for procedure in statement: | ||
let procType = procedure.getTypeInst() | ||
if procType.kind != nnkProcTy: | ||
error( | ||
&"Ref object exports statement of unexpected kind {procType.kind}", | ||
procType | ||
) | ||
|
||
if procType[0].len <= 1: | ||
continue | ||
|
||
if procType[0][1][1].kind != nnkBracketExpr: | ||
continue | ||
|
||
if procType[0][1][1][1].getSeqName() == sym.getSeqName(): | ||
exportProcs.add(procedure) | ||
|
||
exportSeqInternal(sym) | ||
|
||
for procedure in exportProcs: | ||
exportProcInternal(procedure, [sym]) | ||
|
||
macro writeFiles*(dir, lib: static[string]) = | ||
writeInternal(dir, lib) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import macros, strformat, strutils | ||
|
||
const basicTypes* = [ | ||
"bool", | ||
"int8", | ||
"uint8", | ||
"int16", | ||
"uint16", | ||
"int32", | ||
"uint32", | ||
"int64", | ||
"uint64", | ||
"int", | ||
"uint", | ||
"float32", | ||
"float64", | ||
"float" | ||
] | ||
|
||
proc toSnakeCase*(s: string): string = | ||
## Converts NimType to nim_type. | ||
var prevCap = false | ||
for i, c in s: | ||
if c in {'A' .. 'Z'}: | ||
if result.len > 0 and result[^1] != '_' and not prevCap: | ||
result.add '_' | ||
prevCap = true | ||
result.add c.toLowerAscii() | ||
else: | ||
prevCap = false | ||
result.add c | ||
|
||
proc toCapSnakeCase*(s: string): string = | ||
## Converts NimType to NIM_TYPE. | ||
var prevCap = false | ||
for i, c in s: | ||
if c in {'A' .. 'Z'}: | ||
if result.len > 0 and result[^1] != '_' and not prevCap: | ||
result.add '_' | ||
prevCap = true | ||
else: | ||
prevCap = false | ||
result.add c.toUpperAscii() | ||
|
||
proc toVarCase*(s: string): string = | ||
## Converts NimType to nimType. | ||
var i = 0 | ||
while i < s.len: | ||
if s[i] notin {'A' .. 'Z'}: | ||
break | ||
|
||
result.add s[i].toLowerAscii() | ||
inc i | ||
|
||
if i < s.len: | ||
result.add s[i .. ^1] | ||
|
||
proc getSeqName*(sym: NimNode): string = | ||
if sym.kind == nnkBracketExpr: | ||
result = &"Seq{sym[1]}" | ||
else: | ||
result = &"Seq{sym}" | ||
result[3] = toUpperAscii(result[3]) | ||
|
||
proc getName*(sym: NimNode): string = | ||
if sym.kind == nnkBracketExpr: | ||
sym.getSeqName() | ||
else: | ||
sym.repr | ||
|
||
proc raises*(procSym: NimNode): bool = | ||
for pragma in procSym.getImpl()[4]: | ||
if pragma.kind == nnkExprColonExpr and pragma[0].repr == "raises": | ||
return pragma[1].len > 0 |
Oops, something went wrong.