Reduce regex for perf, reduce globals for CT

This commit is contained in:
Ganesh Viswanathan 2020-05-18 16:39:18 -05:00
commit 6f96437f39
8 changed files with 128 additions and 115 deletions

View file

@ -30,15 +30,15 @@ proc execTest(test: string, flags = "", runDocs = true) =
mkDir docPath mkDir docPath
buildDocs(@[test], docPath, nimArgs = "--hints:off " & flags) buildDocs(@[test], docPath, nimArgs = "--hints:off " & flags)
task buildToast, "build toast":
execCmd("nim c --hints:off nimterop/toast.nim")
task buildTimeit, "build timer": task buildTimeit, "build timer":
exec "nim c --hints:off -d:danger tests/timeit" exec "nim c --hints:off -d:danger tests/timeit"
task bt, "build toast": task buildToast, "build toast":
execCmd("nim c --hints:off -d:danger nimterop/toast.nim") execCmd("nim c --hints:off -d:danger nimterop/toast.nim")
task bt, "build toast":
buildToastTask()
task btd, "build toast": task btd, "build toast":
execCmd("nim c -g nimterop/toast.nim") execCmd("nim c -g nimterop/toast.nim")

View file

@ -2,8 +2,6 @@ import hashes, macros, osproc, sets, strformat, strutils, tables
import os except findExe, sleep import os except findExe, sleep
import regex
type type
BuildType* = enum BuildType* = enum
btAutoconf, btCmake btAutoconf, btCmake
@ -995,7 +993,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta
## prior to the build process. ## prior to the build process.
var var
origname = header.extractFilename().split(".")[0] origname = header.extractFilename().split(".")[0]
name = origname.replace(re"[[:^alnum:]]", "") name = origname.split(seps = AllChars-Letters-Digits).join()
# -d:xxx for this header # -d:xxx for this header
stdStr = name & "Std" stdStr = name & "Std"

View file

@ -17,8 +17,6 @@ All `{.compileTime.}` procs must be used in a compile time context, e.g. using:
import hashes, macros, os, strformat, strutils import hashes, macros, os, strformat, strutils
import regex
import "."/[build, globals, paths, types] import "."/[build, globals, paths, types]
export types export types
@ -684,7 +682,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib:
hash = output.hash().abs() hash = output.hash().abs()
hpath = getProjectCacheDir("c2nimCache", forceClean = false) / "nimterop_" & $hash & ".h" hpath = getProjectCacheDir("c2nimCache", forceClean = false) / "nimterop_" & $hash & ".h"
npath = hpath[0 .. hpath.rfind('.')] & "nim" npath = hpath[0 .. hpath.rfind('.')] & "nim"
header = ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) header = "header" & fullpath.splitFile().name.split(seps = {'-', '.'}).join()
if not fileExists(hpath) or gStateCT.nocache or compileOption("forceBuild"): if not fileExists(hpath) or gStateCT.nocache or compileOption("forceBuild"):
mkDir(hpath.parentDir()) mkDir(hpath.parentDir())
@ -715,10 +713,6 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib:
var var
nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath) nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath)
nimout = nimout.
replace(re"([u]?int[\d]+)_t", "$1").
replace(re"([u]?int)ptr_t", "ptr $1")
if gStateCT.debug: if gStateCT.debug:
echo nimout echo nimout

View file

@ -227,7 +227,7 @@ proc getOverride*(gState: State, name: string, kind: NimSymKind): string =
result = sym.override result = sym.override
if kind != nskProc: if kind != nskProc:
result = result.replace(re"(?m)^(.*?)$", " $1") result = " " & result.replace("\n", "\n ")
proc getOverrideFinal*(gState: State, kind: NimSymKind): string = proc getOverrideFinal*(gState: State, kind: NimSymKind): string =
# Get all unused cOverride symbols of `kind` # Get all unused cOverride symbols of `kind`

View file

@ -1,14 +1,92 @@
import sequtils, sets, tables, strutils import tables
when defined(TOAST):
import sets, sequtils, strutils
import regex import regex
import "."/plugin import "."/plugin
when defined(TOAST):
import compiler/[ast, idents, modulegraphs, options] import compiler/[ast, idents, modulegraphs, options]
import "."/treesitter/api import "."/treesitter/api
type
Feature* = enum
ast1, ast2
State* = ref object
# Command line arguments to toast - some forwarded from cimport.nim
convention*: string # `--convention | -C` to change calling convention from cdecl default
debug*: bool # `cDebug()` or `--debug | -d` to enable debug mode
defines*: seq[string] # Symbols added by `cDefine()` and `--define | -D` for C/C++ preprocessor/compiler
dynlib*: string # `cImport(dynlib)` or `--dynlib | -l` to specify variable containing library name
feature*: seq[Feature] # `--feature | -f` feature flags enabled
includeDirs*: seq[string] # Paths added by `cIncludeDir()` and `--includeDirs | -I` for C/C++ preprocessor/compiler
mode*: string # `cImport(mode)` or `--mode | -m` to override detected compiler mode - c or cpp
nim*: string # `--nim` to specify full path to Nim compiler
noComments*: bool # `--noComments | -c` to disable rendering comments in wrappers
noHeader*: bool # `--noHeader | -H` to skip {.header.} pragma in wrapper
past*: bool # `--past | -a` to print tree-sitter AST of code
pluginSourcePath*: string # `--pluginSourcePath` specified path to plugin file to compile and load
pnim*: bool # `--pnim | -n` to render Nim wrapper for header
preprocess*: bool # `--preprocess | -p` to enable preprocessing of code before wrapping
prefix*: seq[string] # `--prefix` strings to strip from start of identifiers
recurse*: bool # `--recurse | -r` to recurse into #include files in headers specified
replace*: OrderedTableRef[string, string]
# `--replace | -G` replacement rules for identifiers
suffix*: seq[string] # `--suffix` strings to strip from end of identifiers
symOverride*: seq[string] # `cSkipSymbol()`, `cOverride()` and `--symOverride | -O` symbols to skip during wrapping
typeMap*: TableRef[string, string]
# `--typeMap | -T` to map instances of type X to Y - e.g. ABC=cint
when defined(TOAST):
# Data fields
code*: string # Contents of header file currently being processed
currentHeader*: string # Const name of header being currently processed
impShort*: string # Short base name for pragma in output
outputHandle*: File # `--output | -o` open file handle
sourceFile*: string # Full path of header being currently processed
# Plugin callbacks
onSymbol*, onSymbolOverride*: OnSymbol
onSymbolOverrideFinal*: OnSymbolOverrideFinal
# Symbol tables
constIdentifiers*: HashSet[string] # Const names for enum casting
identifiers*: TableRef[string, string] # Symbols that have been declared so far indexed by nimName
skippedSyms*: HashSet[string] # Symbols that have been skipped due to being unwrappable or
# the user provided override is blank
# Nim compiler objects
constSection*, enumSection*, pragmaSection*, procSection*, typeSection*, varSection*: PNode
identCache*: IdentCache
config*: ConfigRef
graph*: ModuleGraph
# Table of symbols to generated AST PNode - used to implement forward declarations
identifierNodes*: TableRef[string, PNode]
# Used for the exprparser.nim module
currentExpr*, currentTyCastName*: string
# Controls whether or not the current expression
# should validate idents against currently defined idents
skipIdentValidation*: bool
# Legacy AST fields, remove when ast2 becomes default
constStr*, enumStr*, procStr*, typeStr*: string
commentStr*, debugStr*, skipStr*: string
data*: seq[tuple[name, val: string]]
nodeBranch*: seq[string]
else:
# cimport.nim specific
compile*: seq[string] # `cCompile()` list of files already processed
nocache*: bool # `cDisableCaching()` to disable caching of artifacts
overrides*: string # `cOverride()` code which gets added to `cPlugin()` output
pluginSource*: string # `cPlugin()` generated code to write to plugin file from
searchDirs*: seq[string] # `cSearchPath()` added directories for header search
when defined(TOAST):
const const
gAtoms* {.used.} = @[ gAtoms* {.used.} = @[
"field_identifier", "field_identifier",
@ -48,94 +126,11 @@ type
kind*: Kind kind*: Kind
recursive*: bool recursive*: bool
children*: seq[ref Ast] children*: seq[ref Ast]
when defined(TOAST):
tonim*: proc (ast: ref Ast, node: TSNode, gState: State) tonim*: proc (ast: ref Ast, node: TSNode, gState: State)
regex*: Regex regex*: Regex
AstTable* {.used.} = TableRef[string, seq[ref Ast]] AstTable* {.used.} = TableRef[string, seq[ref Ast]]
State* = ref object
# Command line arguments to toast - some forwarded from cimport.nim
convention*: string # `--convention | -C` to change calling convention from cdecl default
debug*: bool # `cDebug()` or `--debug | -d` to enable debug mode
defines*: seq[string] # Symbols added by `cDefine()` and `--define | -D` for C/C++ preprocessor/compiler
dynlib*: string # `cImport(dynlib)` or `--dynlib | -l` to specify variable containing library name
feature*: seq[Feature] # `--feature | -f` feature flags enabled
includeDirs*: seq[string] # Paths added by `cIncludeDir()` and `--includeDirs | -I` for C/C++ preprocessor/compiler
mode*: string # `cImport(mode)` or `--mode | -m` to override detected compiler mode - c or cpp
nim*: string # `--nim` to specify full path to Nim compiler
noComments*: bool # `--noComments | -c` to disable rendering comments in wrappers
noHeader*: bool # `--noHeader | -H` to skip {.header.} pragma in wrapper
past*: bool # `--past | -a` to print tree-sitter AST of code
pluginSourcePath*: string # `--pluginSourcePath` specified path to plugin file to compile and load
pnim*: bool # `--pnim | -n` to render Nim wrapper for header
preprocess*: bool # `--preprocess | -p` to enable preprocessing of code before wrapping
prefix*: seq[string] # `--prefix` strings to strip from start of identifiers
recurse*: bool # `--recurse | -r` to recurse into #include files in headers specified
replace*: OrderedTableRef[string, string]
# `--replace | -G` replacement rules for identifiers
suffix*: seq[string] # `--suffix` strings to strip from end of identifiers
symOverride*: seq[string] # `cSkipSymbol()`, `cOverride()` and `--symOverride | -O` symbols to skip during wrapping
typeMap*: TableRef[string, string]
# `--typeMap | -T` to map instances of type X to Y - e.g. ABC=cint
# cimport.nim specific
compile*: seq[string] # `cCompile()` list of files already processed
nocache*: bool # `cDisableCaching()` to disable caching of artifacts
overrides*: string # `cOverride()` code which gets added to `cPlugin()` output
pluginSource*: string # `cPlugin()` generated code to write to plugin file from
searchDirs*: seq[string] # `cSearchPath()` added directories for header search
# Data fields
code*: string # Contents of header file currently being processed
currentHeader*: string # Const name of header being currently processed
impShort*: string # Short base name for pragma in output
outputHandle*: File # `--output | -o` open file handle
sourceFile*: string # Full path of header being currently processed
# Plugin callbacks
onSymbol*, onSymbolOverride*: OnSymbol
onSymbolOverrideFinal*: OnSymbolOverrideFinal
# Symbol tables
constIdentifiers*: HashSet[string] # Const names for enum casting
identifiers*: TableRef[string, string] # Symbols that have been declared so far indexed by nimName
skippedSyms*: HashSet[string] # Symbols that have been skipped due to being unwrappable or
# the user provided override is blank
# Nim compiler objects
when defined(TOAST):
constSection*, enumSection*, pragmaSection*, procSection*, typeSection*, varSection*: PNode
identCache*: IdentCache
config*: ConfigRef
graph*: ModuleGraph
# Table of symbols to generated AST PNode - used to implement forward declarations
identifierNodes*: TableRef[string, PNode]
# Used for the exprparser.nim module
currentExpr*, currentTyCastName*: string
# Controls whether or not the current expression
# should validate idents against currently defined idents
skipIdentValidation*: bool
# Legacy AST fields, remove when ast2 becomes default
constStr*, enumStr*, procStr*, typeStr*: string
commentStr*, debugStr*, skipStr*: string
data*: seq[tuple[name, val: string]]
nodeBranch*: seq[string]
Feature* = enum
ast1, ast2
var
gStateCT* {.compiletime, used.} = new(State)
template nBl*(s: typed): untyped {.used.} =
(s.len != 0)
template Bl*(s: typed): untyped {.used.} =
(s.len == 0)
# Redirect output to file when required # Redirect output to file when required
template gecho*(args: string) = template gecho*(args: string) =
if gState.outputHandle.isNil: if gState.outputHandle.isNil:
@ -146,3 +141,12 @@ template gecho*(args: string) =
template decho*(args: varargs[string, `$`]): untyped = template decho*(args: varargs[string, `$`]): untyped =
if gState.debug: if gState.debug:
gecho join(args, "").getCommented() gecho join(args, "").getCommented()
else:
var
gStateCT* {.compiletime, used.} = new(State)
template nBl*(s: typed): untyped {.used.} =
(s.len != 0)
template Bl*(s: typed): untyped {.used.} =
(s.len == 0)

View file

@ -4,8 +4,6 @@ import "."/treesitter/[api, c, cpp]
import "."/[ast, ast2, build, globals, getters, grammar, tshelp] import "."/[ast, ast2, build, globals, getters, grammar, tshelp]
{.passC: "-DNIMTEROP".}
proc process(gState: State, path: string, astTable: AstTable) = proc process(gState: State, path: string, astTable: AstTable) =
doAssert existsFile(path), &"Invalid path {path}" doAssert existsFile(path), &"Invalid path {path}"

View file

@ -79,6 +79,23 @@ proc getStartAtom*(node: TSNode): int =
else: else:
break break
proc getConstQualifier*(gState: State, node: TSNode): bool =
# Check if node siblings have type_qualifier = `const`
var
curr = node.tsNodePrevNamedSibling()
while not curr.isNil:
# Check previous siblings
if curr.getName() == "type_qualifier" and
gState.getNodeVal(curr) == "const":
return true
curr = curr.tsNodePrevNamedSibling()
# Check immediate next sibling
curr = node.tsNodePrevNamedSibling()
if curr.getName() == "type_qualifier" and
gState.getNodeVal(curr) == "const":
return true
proc getXCount*(node: TSNode, ntype: string, reverse = false): int = proc getXCount*(node: TSNode, ntype: string, reverse = false): int =
if not node.isNil: if not node.isNil:
# Get number of ntype nodes nested in tree # Get number of ntype nodes nested in tree

View file

@ -2,6 +2,8 @@ import macros, os, sets, strutils
import nimterop/[cimport] import nimterop/[cimport]
{.passC: "-DNIMTEROP".}
static: static:
# Skip casting on lower nim compilers because # Skip casting on lower nim compilers because
# the VM does not support it # the VM does not support it