Add documentation
This commit is contained in:
parent
6511145513
commit
8a4fb0faca
3 changed files with 82 additions and 19 deletions
10
README.md
10
README.md
|
|
@ -55,11 +55,11 @@ Detailed documentation is still forthcoming.
|
|||
|
||||
`cDebug()` - enable debug messages
|
||||
|
||||
`cDefine("XXX")` - `#define` an identifer that is forwarded to the C/C++ compiler using `{.passC: "-DXXX".}` as well as _eventually_ used in processing `#ifdef` statements
|
||||
`cDefine("XXX")` - `#define` an identifer that is forwarded to the C/C++ compiler using `{.passC: "-DXXX".}`
|
||||
|
||||
`cIncludeDir("XXX")` - add an include directory that is forwarded to the compiler using `{.passC: "-IXXX".}`
|
||||
`cIncludeDir("XXX")` - add an include directory that is forwarded to the C/C++ compiler using `{.passC: "-IXXX".}`
|
||||
|
||||
`cImport("header.h")` - import all supported definitions from header file. Output is cached in nimcache unless header.h changes or by using `nim -f`
|
||||
`cImport("header.h")` - Import all supported definitions from specified header file. Generated content is cached in `nimcache` until `header.h` changes. If files imported by `header.h` change and affect the generated content, use `nim -f` to force regeneration of Nim code.
|
||||
|
||||
`cImport("header.h", recurse=true)` - import all supported definitions from header file and #includes
|
||||
|
||||
|
|
@ -69,9 +69,9 @@ Detailed documentation is still forthcoming.
|
|||
|
||||
`cCompile("path/to/dir", "cpp")` - compile in all C++ files found recursively
|
||||
|
||||
`cAddSearchDir("XXX")` - add directory XXX to search path in calls to `cSearchPath()`
|
||||
`cAddSearchDir("XXX")` - add directory XXX to the search path used in calls to `cSearchPath()`
|
||||
|
||||
`cAddStdDir("XXX")` - add standard "c" [default] or "cpp" include paths to search path
|
||||
`cAddStdDir("XXX")` - add standard "c" [default] or "cpp" include paths to search path used in calls to `cSearchPath()`
|
||||
|
||||
`cSearchPath("header.h")` - return a file or directory found in search path configured using `cSearchPath()` - can be used in `cCompile()`, `cIncludeDir()` and `cImport()` calls
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ proc getToastError(output: string): string =
|
|||
# Filter out preprocessor errors
|
||||
for line in output.splitLines():
|
||||
if "fatal error:" in line.toLowerAscii:
|
||||
result &= &"\nERROR: {line.split(\"fatal error\")[1]}\n"
|
||||
result &= "\nERROR:$1\n" % line.split("fatal error:")[1]
|
||||
|
||||
# Toast error
|
||||
if result.len == 0:
|
||||
|
|
@ -100,7 +100,7 @@ proc getToast(fullpath: string, recurse: bool = false): string =
|
|||
(result, ret) = gorgeEx(cmd, cache=getFileDate(fullpath))
|
||||
doAssert ret == 0, getToastError(result)
|
||||
|
||||
proc getGccPaths*(mode = "c"): string =
|
||||
proc getGccPaths(mode = "c"): string =
|
||||
var
|
||||
ret = 0
|
||||
nul = when defined(Windows): "nul" else: "/dev/null"
|
||||
|
|
@ -109,6 +109,12 @@ proc getGccPaths*(mode = "c"): string =
|
|||
(result, ret) = gorgeEx("gcc -Wp,-v -x" & mmode & " " & nul)
|
||||
|
||||
proc cSearchPath*(path: string): string {.compileTime.}=
|
||||
## Return a file or directory found in search path configured using
|
||||
## ``cSearchPath()``
|
||||
##
|
||||
## This proc can be used to locate files or directories in calls to
|
||||
## ``cCompile()``, ``cIncludeDir()`` and ``cImport()``.
|
||||
|
||||
result = findPath(path, fail = false)
|
||||
if result.len == 0:
|
||||
var found = false
|
||||
|
|
@ -117,12 +123,18 @@ proc cSearchPath*(path: string): string {.compileTime.}=
|
|||
if fileExists(result) or dirExists(result):
|
||||
found = true
|
||||
break
|
||||
doAssert found, "File or directory not found: " & path & " gStateCT.searchDirs: " & $gStateCT.searchDirs
|
||||
doAssert found, "File or directory not found: " & path &
|
||||
" gStateCT.searchDirs: " & $gStateCT.searchDirs
|
||||
|
||||
macro cDebug*(): untyped =
|
||||
## Enable debug messages and display the generated Nim code
|
||||
|
||||
gStateCT.debug = true
|
||||
|
||||
macro cDefine*(name: static string, val: static string = ""): untyped =
|
||||
## ``#define`` an identifer that is forwarded to the C/C++ compiler
|
||||
## using ``{.passC: "-DXXX".}``
|
||||
|
||||
result = newNimNode(nnkStmtList)
|
||||
|
||||
var str = name
|
||||
|
|
@ -141,11 +153,24 @@ macro cDefine*(name: static string, val: static string = ""): untyped =
|
|||
echo result.repr
|
||||
|
||||
macro cAddSearchDir*(dir: static string): untyped =
|
||||
## Add directory ``dir`` to the search path used in calls to
|
||||
## ``cSearchPath()``
|
||||
##
|
||||
## This allows something like this:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## cAddSearchDir("path/to/includes")
|
||||
## cImport cSearchPath("file.h")
|
||||
|
||||
var dir = interpPath(dir)
|
||||
if dir notin gStateCT.searchDirs:
|
||||
gStateCT.searchDirs.add(dir)
|
||||
|
||||
macro cIncludeDir*(dir: static string): untyped =
|
||||
## Add an include directory that is forwarded to the C/C++ compiler
|
||||
## using ``{.passC: "-IXXX".}``
|
||||
|
||||
var dir = interpPath(dir)
|
||||
result = newNimNode(nnkStmtList)
|
||||
|
||||
|
|
@ -164,6 +189,16 @@ macro cIncludeDir*(dir: static string): untyped =
|
|||
echo result.repr
|
||||
|
||||
macro cAddStdDir*(mode = "c"): untyped =
|
||||
## Add the standard ``c`` [default] or ``cpp`` include paths to search
|
||||
## path used in calls to ``cSearchPath()``
|
||||
##
|
||||
## This allows something like this:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## cAddStdDir()
|
||||
## cImport cSearchPath("math.h")
|
||||
|
||||
result = newNimNode(nnkStmtList)
|
||||
|
||||
var
|
||||
|
|
@ -182,6 +217,22 @@ macro cAddStdDir*(mode = "c"): untyped =
|
|||
cAddSearchDir(`sline`)
|
||||
|
||||
macro cCompile*(path: static string, mode = "c"): untyped =
|
||||
## Compile and link C/C++ implementation into resulting binary using ``{.compile.}``
|
||||
##
|
||||
## ``path`` can be a specific file or contain wildcards:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## cCompile("file.c")
|
||||
## cCompile("path/to/*.c")
|
||||
##
|
||||
## ``mode`` can be ``c`` or ``cpp`` and recursively searches for code files in
|
||||
## specified path. ``c`` = ``*.c``, ``cpp`` = ``*.C``, ``*.cpp``, ``*.c++``, ``*.cc``, ``*.cxx``
|
||||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## cCompile("path/to/dir", "cpp")
|
||||
|
||||
result = newNimNode(nnkStmtList)
|
||||
|
||||
var
|
||||
|
|
@ -229,6 +280,15 @@ macro cCompile*(path: static string, mode = "c"): untyped =
|
|||
echo result.repr
|
||||
|
||||
macro cImport*(filename: static string, recurse: static bool = false): untyped =
|
||||
## Import all supported definitions from specified header file. Generated
|
||||
## content is cached in ``nimcache`` until ``filename`` changes. If files
|
||||
## imported by ``filename`` change and affect the generated content, use
|
||||
## ``nim -f`` to force regeneration of Nim code.
|
||||
##
|
||||
## ``recurse`` can be used to generate Nim wrappers from ``#include`` files
|
||||
## referenced in ``filename``. This is only done for files in the same
|
||||
## directory as ``filename`` or in a directory added using ``cIncludeDir()``.
|
||||
|
||||
result = newNimNode(nnkStmtList)
|
||||
|
||||
let
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ when not declared(CIMPORT):
|
|||
import "."/treesitter/runtime
|
||||
|
||||
const
|
||||
gAtoms* = @[
|
||||
gAtoms {.used.} = @[
|
||||
"field_identifier",
|
||||
"identifier",
|
||||
"number_literal",
|
||||
|
|
@ -16,27 +16,27 @@ const
|
|||
"type_identifier"
|
||||
].toSet()
|
||||
|
||||
gExpressions* = @[
|
||||
gExpressions {.used.} = @[
|
||||
"parenthesized_expression",
|
||||
"bitwise_expression",
|
||||
"shift_expression",
|
||||
"math_expression"
|
||||
].toSet()
|
||||
|
||||
gEnumVals* = @[
|
||||
gEnumVals {.used.} = @[
|
||||
"identifier",
|
||||
"number_literal"
|
||||
].concat(toSeq(gExpressions.items))
|
||||
|
||||
type
|
||||
Kind* = enum
|
||||
Kind = enum
|
||||
exactlyOne
|
||||
oneOrMore # +
|
||||
zeroOrMore # *
|
||||
zeroOrOne # ?
|
||||
orWithNext # !
|
||||
|
||||
Ast* = object
|
||||
Ast = object
|
||||
name*: string
|
||||
kind*: Kind
|
||||
recursive*: bool
|
||||
|
|
@ -45,7 +45,7 @@ type
|
|||
tonim*: proc (ast: ref Ast, node: TSNode)
|
||||
regex*: Regex
|
||||
|
||||
State* = object
|
||||
State = object
|
||||
compile*, defines*, headers*, includeDirs*, searchDirs*: seq[string]
|
||||
|
||||
debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool
|
||||
|
|
@ -61,15 +61,18 @@ type
|
|||
grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.nimcall.}]]
|
||||
|
||||
var
|
||||
gStateCT* {.compiletime.}: State
|
||||
gStateRT*: State
|
||||
gStateCT {.compiletime, used.}: State
|
||||
gStateRT {.used.}: State
|
||||
|
||||
template nBl*(s: typed): untyped =
|
||||
template nBl(s: typed): untyped {.used.} =
|
||||
(s.len != 0)
|
||||
|
||||
type CompileMode* = enum
|
||||
type CompileMode = enum
|
||||
c,
|
||||
cpp,
|
||||
|
||||
# TODO: can cligen accept enum instead of string?
|
||||
const modeDefault* = $cpp # TODO: USE this everywhere relevant
|
||||
const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant
|
||||
|
||||
when not declared(CIMPORT):
|
||||
export gAtoms, gExpressions, gEnumVals, Kind, Ast, State, gStateRT, nBl, CompileMode, modeDefault
|
||||
Loading…
Add table
Add a link
Reference in a new issue