Last active
April 17, 2017 20:36
-
-
Save jonas/fa7ada249afe5a7c9ebd67b44bf032e3 to your computer and use it in GitHub Desktop.
Scala Native bindgen WIP
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
> sandbox/run | |
[warn] Credentials file /Users/fonseca/.bintray/.credentials does not exist | |
[info] Compiling 1 Scala source to /opt/scala-native/sandbox/target/scala-2.11/classes... | |
[info] Linking (886 ms) | |
[info] Discovered 767 classes and 4541 methods | |
[info] Optimizing (1293 ms) | |
[info] Generating intermediate code (244 ms) | |
[info] Produced 34 files | |
[info] Compiling to native code (1115 ms) | |
[info] Linking native code (216 ms) | |
@extern | |
object X { | |
def ___runetype(: __darwin_ct_rune_t): unsigned long = extern | |
def ___tolower(: __darwin_ct_rune_t): __darwin_ct_rune_t = extern | |
def ___toupper(: __darwin_ct_rune_t): __darwin_ct_rune_t = extern | |
def isascii(_c: CInt): CInt = extern | |
def __maskrune(: __darwin_ct_rune_t, : unsigned long): CInt = extern | |
def __istype(_c: __darwin_ct_rune_t, _f: unsigned long): CInt = extern | |
def __isctype(_c: __darwin_ct_rune_t, _f: unsigned long): __darwin_ct_rune_t = extern | |
def __toupper(: __darwin_ct_rune_t): __darwin_ct_rune_t = extern | |
def __tolower(: __darwin_ct_rune_t): __darwin_ct_rune_t = extern | |
def __wcwidth(_c: __darwin_ct_rune_t): CInt = extern | |
def isalnum(_c: CInt): CInt = extern | |
def isalpha(_c: CInt): CInt = extern | |
def isblank(_c: CInt): CInt = extern | |
def iscntrl(_c: CInt): CInt = extern | |
def isdigit(_c: CInt): CInt = extern | |
def isgraph(_c: CInt): CInt = extern | |
def islower(_c: CInt): CInt = extern | |
def isprint(_c: CInt): CInt = extern | |
def ispunct(_c: CInt): CInt = extern | |
def isspace(_c: CInt): CInt = extern | |
def isupper(_c: CInt): CInt = extern | |
def isxdigit(_c: CInt): CInt = extern | |
def toascii(_c: CInt): CInt = extern | |
def tolower(_c: CInt): CInt = extern | |
def toupper(_c: CInt): CInt = extern | |
def digittoint(_c: CInt): CInt = extern | |
def ishexnumber(_c: CInt): CInt = extern | |
def isideogram(_c: CInt): CInt = extern | |
def isnumber(_c: CInt): CInt = extern | |
def isphonogram(_c: CInt): CInt = extern | |
def isrune(_c: CInt): CInt = extern | |
def isspecial(_c: CInt): CInt = extern | |
} |
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
import scalanative.native._, stdlib._, stdio._, string._ | |
import scalanative.runtime.bindgen._ | |
object Test { | |
import Bindgen._ | |
sealed trait Node | |
case class Function(name: String, returnType: String, args: List[Function.Arg]) extends Node | |
object Function { | |
case class Arg(name: String, tpe: String) | |
} | |
val buffer = scala.collection.mutable.ListBuffer[Node]() | |
def showArg(i: Int, parent: CXCursor) = { | |
val cursor = Cursor_getArgument(parent, i) | |
val tpe = getCursorType(cursor) | |
val name = getCursorSpelling(cursor) | |
val typeSpelling = getTypeSpelling(tpe) | |
Function.Arg(fromCString(name), fromCString(typeSpelling)) | |
} | |
def showArgs(cursor: CXCursor) = { | |
val argc = Cursor_getNumArguments(cursor) | |
var i = 0 | |
var args = List.empty[Function.Arg] | |
while (i < argc) { | |
args = args :+ showArg(i, cursor) | |
i += 1 | |
} | |
args | |
} | |
val visitor: Visitor = (cursor: CXCursor, parent: CXCursor, data: Data) => { | |
val kind: CXCursorKind = getCursorKind(cursor) | |
if (kind == CXCursor_FunctionDecl) { | |
val name = getCursorSpelling(cursor) | |
val cursorType = getCursorType(cursor) | |
val returnType = getResultType(cursorType) | |
val returnTypeSpelling = getTypeSpelling(returnType) | |
val argc = Cursor_getNumArguments(cursor) | |
buffer += Function(fromCString(name), fromCString(returnTypeSpelling), showArgs(cursor)) | |
} else { | |
val name = getCursorSpelling(cursor) | |
val kindSpelling = getCursorKindSpelling(kind) | |
printf(c"Unhandled cursor kind for %s: %s\n", name, kindSpelling) | |
} | |
CXChildVisit_Recurse | |
} | |
def cToScala(tpe: String) = { | |
tpe match { | |
case "const char *" | "char *" => "CString" | |
case "int" => "CInt" | |
case unknown => unknown | |
} | |
} | |
def main(args: Array[String]): Unit = { | |
// val path = c"/opt/scala-native/sandbox/test.h" | |
val path = c"/usr/include/ctype.h" | |
val index = createIndex(0, 0) | |
val unit = parseTranslationUnit(index, path, null, 0, null, 0, CXTranslationUnit_SkipFunctionBodies) | |
val cursor = getTranslationUnitCursor(unit) | |
visitChildren(cursor, visitor, null) | |
disposeTranslationUnit(unit) | |
disposeIndex(index) | |
println("@extern") | |
println("object X {") | |
buffer.foreach { | |
case Function(name, returnType, args) => | |
val argList = args.map(arg => s"${arg.name}: ${cToScala(arg.tpe)}").mkString(", ") | |
println(s" def $name($argList): ${cToScala(returnType)} = extern") | |
} | |
println("}") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment