From d126e9944fee992f46bd51d2f65f3db752249163 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 24 Jun 2020 10:37:38 -0500 Subject: [PATCH] Remove legacy backend --- CHANGES.md | 2 + README.md | 9 +- nimterop.nimble | 13 +- nimterop/build.nim | 8 +- nimterop/build/getheader.nim | 3 +- nimterop/build/shell.nim | 3 +- nimterop/build/tools.nim | 9 +- nimterop/globals.nim | 27 +- nimterop/toast.nim | 39 +- nimterop/toastlib/ast.nim | 253 ----------- nimterop/toastlib/getters.nim | 125 ------ nimterop/toastlib/grammar.nim | 768 ---------------------------------- nimterop/toastlib/lisp.nim | 60 --- nimterop/toastlib/tshelp.nim | 1 - tests/getheader.nims | 2 +- tests/libssh2.nim | 4 +- tests/rsa.nim | 2 +- 17 files changed, 33 insertions(+), 1295 deletions(-) delete mode 100644 nimterop/toastlib/ast.nim delete mode 100644 nimterop/toastlib/grammar.nim delete mode 100644 nimterop/toastlib/lisp.nim diff --git a/CHANGES.md b/CHANGES.md index bf4b50a..93bb8af 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,8 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.0 ### Breaking changes +- The legacy algorithm has been removed as promised. `ast2` is now the default and wrappers no longer need to explicitly specify `-f:ast2` in order to use it. + - All shared libraries installed by `getHeader()` will now get copied into the `libdir` parameter specified. If left blank, `libdir` will default to the directory where the executable binary gets created (outdir). While this is not really a breaking change, it is a change in behavior compared to older versions of nimterop. Note that `Std` libraries are not copied over. [#154](i154) - `git.nim` has been removed. This module was an artifact from the early days and was renamed to `build.nim` back in v0.2.0. diff --git a/README.md b/README.md index af8501a..b054d97 100644 --- a/README.md +++ b/README.md @@ -177,13 +177,13 @@ Now that this is understood, a user might want any combination of the above in t - By default, generated wrappers will include the `{.header, importc.}` pragmas for types and procs. This can be disabled with the `--noHeader | -H` flag to `toast` or `flags = "-H"` param to `cImport()` which will remove `{.header}` for both and `{.importc.}` for types only. - By default, generated wrappers will assume that the user will link the library implementation themselves. The `--dynlib | -l` flag to `toast` or `dynlib = "headerLPath"` param to `cImport()` will configure the wrapper to generate `{.dynlib.}` pragmas for procs. -This results in four cases: +This results in four supported cases: 1. Default: `{.header, importc.}` for both types and procs 2. With `--noHeader`, types will be pure Nim and procs will be just `{.importc.}` 3. With `--dynlib`, types will still be `{.header, importc.}` but procs will be `{.dynlib, importc.}` 4. With `--dynlib` and `--noHeader`, types will be pure Nim, procs will be `{.dynlib, importc.}` -While `ast2` supports all these modes, the legacy backend does not support the third mixed case and will infer `--noHeader` when `--dynlib` is specified (case 4). Creation of a standalone wrapper (case 4) which does not require the header or library at compile time will require an explicit `--noHeader` and `--dynlib` for `ast2`. +Creation of a standalone wrapper (case 4) which does not require the header or library at compile time will require an explicit `--noHeader` and `--dynlib`. More documentation on on these pragmas can be found in the Nim manual: - [{.importc.}](https://nim-lang.org/docs/manual.html#foreign-function-interface-importc-pragma) @@ -218,7 +218,7 @@ Options: -d, --debug bool false enable debug output -D=, --defines= strings {} definitions to pass to preprocessor -l=, --dynlib= string "" {.dynlib.} pragma to import symbols - Nim const string or file path - -f=, --feature= Features ast1 flags to enable experimental features + -f=, --feature= Features {} flags to enable experimental features -I=, --includeDirs= strings {} include directory to pass to preprocessor -m=, --mode= string "" language parser: c or cpp --nim= string "nim" use a particular Nim executable @@ -226,12 +226,11 @@ Options: -H, --noHeader bool false skip {.header.} pragma in wrapper -o=, --output= string "" file to output content - default: stdout -a, --past bool false print AST output - -g, --pgrammar bool false print grammar --pluginSourcePath= string "" nim file to build and load as a plugin -n, --pnim bool false print Nim output -E=, --prefix= strings {} strip prefix from identifiers -p, --preprocess bool false run preprocessor on header - -r, --recurse bool false process #include files, implies --preprocess + -r, --recurse bool false process #include files - implies --preprocess -G=, --replace= strings {} replace X with Y in identifiers, X1=Y1,X2=Y2, @X for regex -s, --stub bool false stub out undefined type references as objects -F=, --suffix= strings {} strip suffix from identifiers diff --git a/nimterop.nimble b/nimterop.nimble index 1657aed..7be89c6 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.9" +version = "0.6.0" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" @@ -55,15 +55,12 @@ task test, "Test": execTest "tests/tast2.nim", "-d:NOHEADER" execTest "tests/tnimterop_c.nim" - execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2\"" - execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2 -H\"" + execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-H\"" execCmd "nim cpp --hints:off -f -r tests/tnimterop_cpp.nim" execCmd "./nimterop/toast tests/toast.cfg tests/include/toast.h" - execCmd "./nimterop/toast tests/toast.cfg -f:ast2 tests/include/toast.h" execTest "tests/tpcre.nim" - execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" when defined(Linux): execTest "tests/rsa.nim" @@ -72,12 +69,10 @@ task test, "Test": # Platform specific tests when defined(Windows): execTest "tests/tmath.nim" - execTest "tests/tmath.nim", "-d:FLAGS=\"-f:ast2\"" - execTest "tests/tmath.nim", "-d:FLAGS=\"-f:ast2 -H\"" + execTest "tests/tmath.nim", "-d:FLAGS=\"-H\"" if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): execTest "tests/tsoloud.nim" - execTest "tests/tsoloud.nim", "-d:FLAGS=\"-f:ast2\"" - execTest "tests/tsoloud.nim", "-d:FLAGS=\"-f:ast2 -H\"" + execTest "tests/tsoloud.nim", "-d:FLAGS=\"-H\"" # getHeader tests withDir("tests"): diff --git a/nimterop/build.nim b/nimterop/build.nim index 0754615..672cb58 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -14,12 +14,6 @@ var gNimExe* = "" # Misc helpers -proc echoDebug(str: string) = - let str = "\n# " & str.strip().replace("\n", "\n# ") - when nimvm: - if gDebugCT: echo str - else: - if gDebug: echo str proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)]) @@ -34,7 +28,7 @@ proc getCurrentNimCompiler*(): string = else: result = gNimExe -template fixOutDir() {.dirty.} = +template fixOutDir() {.dirty, used.} = let outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index 69741b0..216b599 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -178,7 +178,6 @@ proc getLocalPath(header, outdir: string): string = proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildTypes: openArray[BuildType]): string = var lpath = findFile(lname, outdir, regex = true) - makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" makePath = outdir if lpath.len != 0: @@ -200,7 +199,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT let libraryExists = findFile(lname, buildStatus.buildPath, regex = true).len > 0 if not libraryExists and fileExists(buildStatus.buildPath / "Makefile"): - make(buildStatus.buildPath, lname, makeFlagsProc, regex = true) + make(buildStatus.buildPath, lname, makeFlags, regex = true) buildStatus.built = true let error = if buildStatus.error.len > 0: buildStatus.error else: "No build files found in " & outdir diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index 5179798..bc07285 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -455,7 +455,8 @@ proc linkLibs*(names: openArray[string], staticLink = true): string = for res in resSet: result &= " " & res -proc getNumProcs(): string = +proc getNumProcs*(): string = + ## Get number of processors when defined(Windows): getEnv("NUMBER_OF_PROCESSORS").strip() elif defined(linux): diff --git a/nimterop/build/tools.nim b/nimterop/build/tools.nim index 772c48b..c6a4283 100644 --- a/nimterop/build/tools.nim +++ b/nimterop/build/tools.nim @@ -9,6 +9,13 @@ type buildPath: string error: string +proc echoDebug(str: string) = + let str = "\n# " & str.strip().replace("\n", "\n# ") + when nimvm: + if gDebugCT: echo str + else: + if gDebug: echo str + proc configure*(path, check: string, flags = "") = ## Run the GNU `configure` command to generate all Makefiles or other ## build scripts in the specified path @@ -193,7 +200,7 @@ proc make*(path, check: string, flags = "", regex = false) = cpFile(cmd, cmd.replace("mingw32-make", "make")) doAssert cmd.len != 0, "Make not found" - cmd = &"cd {path.sanitizePath} && make" + cmd = &"cd {path.sanitizePath} && make -j {getNumProcs()}" if flags.len != 0: cmd &= &" {flags}" diff --git a/nimterop/globals.nim b/nimterop/globals.nim index c79f4a5..fa8f8de 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -3,8 +3,6 @@ import tables when defined(TOAST): import sets, sequtils, strutils - import regex - import "."/plugin import compiler/[ast, idents, modulegraphs, options] @@ -13,7 +11,7 @@ when defined(TOAST): type Feature* = enum - ast1, ast2 + ast2 State* = ref object # Command line arguments to toast - some forwarded from cimport.nim @@ -72,12 +70,6 @@ type # 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 @@ -114,23 +106,6 @@ when defined(TOAST): ].concat(toSeq(gExpressions.items)) type - Kind* = enum - exactlyOne - oneOrMore # + - zeroOrMore # * - zeroOrOne # ? - orWithNext # ! - - Ast* = object - name*: string - kind*: Kind - recursive*: bool - children*: seq[ref Ast] - tonim*: proc (ast: ref Ast, node: TSNode, gState: State) - regex*: Regex - - AstTable* {.used.} = TableRef[string, seq[ref Ast]] - Status* = enum success, unknown, error diff --git a/nimterop/toast.nim b/nimterop/toast.nim index e8e14cc..b7a993a 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -4,9 +4,9 @@ import "."/treesitter/[api, c, cpp] import "."/[build, globals] -import "."/toastlib/[ast, ast2, getters, grammar, tshelp] +import "."/toastlib/[ast2, getters, tshelp] -proc process(gState: State, path: string, astTable: AstTable) = +proc process(gState: State, path: string) = doAssert existsFile(path), &"Invalid path {path}" if gState.mode.Bl: @@ -21,10 +21,7 @@ proc process(gState: State, path: string, astTable: AstTable) = if gState.past: gecho gState.printLisp(root) elif gState.pnim: - if Feature.ast2 in gState.feature: - ast2.parseNim(gState, path, root) - elif Feature.ast1 in gState.feature: - ast.parseNim(gState, path, root, astTable) + parseNim(gState, path, root) elif gState.preprocess: gecho gState.code @@ -43,7 +40,6 @@ proc main( noHeader = false, output = "", past = false, - pgrammar = false, pluginSourcePath: string = "", pnim = false, prefix: seq[string] = @[], @@ -84,10 +80,6 @@ proc main( build.gDebug = gState.debug build.gNimExe = gState.nim - # Default `ast` mode - if gState.feature.Bl: - gState.feature.add Feature.ast1 - # Split some arguments with , gState.symOverride = gState.symOverride.getSplitComma() gState.prefix = gState.prefix.getSplitComma() @@ -137,31 +129,14 @@ proc main( if gState.debug: echo &"# Writing output to {outputFile}\n" - # Process grammar into AST - let - astTable = - if Feature.ast1 in gState.feature: - parseGrammar() - else: - nil - - if pgrammar: - if Feature.ast1 in gState.feature: - # Print AST of grammar - gState.printGrammar(astTable) - elif source.nBl: + if source.nBl: # Print source after preprocess or Nim output if gState.pnim: gState.initNim() for src in source: - gState.process(src.expandSymlinkAbs(), astTable) + gState.process(src.expandSymlinkAbs()) if gState.pnim: - if Feature.ast2 in gState.feature: - ast2.printNim(gState) - elif Feature.ast1 in gState.feature: - ast.printNim(gState) - gecho """{.hint: "The legacy wrapper generation algorithm is deprecated and will be removed in the next release of Nimterop.".}""" - gecho """{.hint: "Refer to CHANGES.md for details on migrating to the new backend.".}""" + printNim(gState) # Close outputFile if outputFile.len != 0: @@ -249,7 +224,6 @@ when isMainModule: "noHeader": "skip {.header.} pragma in wrapper", "output": "file to output content - default: stdout", "past": "print AST output", - "pgrammar": "print grammar", "pluginSourcePath": "nim file to build and load as a plugin", "pnim": "print Nim output", "prefix": "strip prefix from identifiers", @@ -273,7 +247,6 @@ when isMainModule: "noHeader": 'H', "output": 'o', "past": 'a', - "pgrammar": 'g', "pnim": 'n', "prefix": 'E', "preprocess": 'p', diff --git a/nimterop/toastlib/ast.nim b/nimterop/toastlib/ast.nim deleted file mode 100644 index 0b62a34..0000000 --- a/nimterop/toastlib/ast.nim +++ /dev/null @@ -1,253 +0,0 @@ -import hashes, macros, os, sets, strformat, strutils, tables - -import regex - -import ".."/[globals, treesitter/api] -import "."/[getters, tshelp] - -proc getHeaderPragma*(gState: State): string = - result = - if not gState.noHeader and gState.dynlib.Bl: - &", header: {gState.currentHeader}" - else: - "" - -proc getDynlib*(gState: State): string = - result = - if gState.dynlib.nBl: - &", dynlib: {gState.dynlib}" - else: - "" - -proc getImportC*(gState: State, origName, nimName: string): string = - if nimName != origName: - result = &"importc: \"{origName}\"{gState.getHeaderPragma()}" - else: - result = gState.impShort - -proc getPragma*(gState: State, pragmas: varargs[string]): string = - result = "" - for pragma in pragmas.items(): - if pragma.nBl: - result &= pragma & ", " - if result.nBl: - result = " {." & result[0 .. ^3] & ".}" - - result = result.replace(gState.impShort & ", cdecl", gState.impShort & "C") - - let - dy = gState.getDynlib() - - if ", cdecl" in result and dy.nBl: - result = result.replace(".}", dy & ".}") - -proc saveNodeData(node: TSNode, gState: State): bool = - let name = $node.tsNodeType() - - # Atoms are nodes whose values are to be saved - if name in gAtoms: - let - pname = node.getPxName(1) - ppname = node.getPxName(2) - pppname = node.getPxName(3) - ppppname = node.getPxName(4) - - var - val = gState.getNodeVal(node) - - # Skip since value already obtained from parent atom - if name == "primitive_type" and pname == "sized_type_specifier": - return true - - # Skip since value already obtained from parent expression - if name in ["number_literal", "identifier"] and pname in gExpressions: - return true - - # Add reference point in saved data for bitfield_clause - if name in ["number_literal"] and pname == "bitfield_clause": - gState.data.add(("bitfield_clause", val)) - return true - - # Process value as a type - if name in ["primitive_type", "sized_type_specifier"]: - val = val.getType() - - if node.tsNodePrevNamedSibling().tsNodeIsNull(): - if pname == "pointer_declarator": - if ppname notin ["function_declarator", "array_declarator"]: - gState.data.add(("pointer_declarator", "")) - elif ppname == "array_declarator": - gState.data.add(("array_pointer_declarator", "")) - - # Double pointer - if ppname == "pointer_declarator": - gState.data.add(("pointer_declarator", "")) - elif pname in ["function_declarator", "array_declarator"]: - if ppname == "pointer_declarator": - gState.data.add(("pointer_declarator", "")) - if pppname == "pointer_declarator": - gState.data.add(("pointer_declarator", "")) - - gState.data.add((name, val)) - - if pname == "pointer_declarator" and - ppname == "function_declarator": - if name == "field_identifier": - if pppname == "pointer_declarator": - gState.data.insert(("pointer_declarator", ""), gState.data.len-1) - if ppppname == "pointer_declarator": - gState.data.insert(("pointer_declarator", ""), gState.data.len-1) - gState.data.add(("function_declarator", "")) - elif name == "identifier": - gState.data.add(("pointer_declarator", "")) - - # Save node value for a top-level expression - elif name in gExpressions and name != "escape_sequence": - if $node.tsNodeParent.tsNodeType() notin gExpressions: - gState.data.add((name, gState.getNodeVal(node))) - - elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: - gState.data.add((name.replace("abstract_", ""), "")) - - return true - -proc searchAstForNode(ast: ref Ast, node: TSNode, gState: State): bool = - let - childNames = node.getTSNodeNamedChildNames().join() - - if ast.isNil: - return - - if gState.debug: - gState.nodeBranch.add $node.tsNodeType() - gecho "#" & spaces(gState.nodeBranch.len * 2) & gState.nodeBranch[^1] - - if ast.children.nBl: - if childNames.contains(ast.regex) or - (childNames.Bl and ast.recursive): - if node.getTSNodeNamedChildCountSansComments() != 0: - var flag = true - - for i in 0 .. node.tsNodeNamedChildCount()-1: - if $node.tsNodeNamedChild(i).tsNodeType() != "comment": - let - nodeChild = node.tsNodeNamedChild(i) - astChild = - if not ast.recursive: - ast.getAstChildByName($nodeChild.tsNodeType()) - else: - ast - - if not searchAstForNode(astChild, nodeChild, gState): - flag = false - break - - if flag: - result = node.saveNodeData(gState) - else: - result = node.saveNodeData(gState) - else: - if gState.debug: - gecho "#" & spaces(gState.nodeBranch.len * 2) & &" {ast.getRegexForAstChildren()} !=~ {childNames}" - elif node.getTSNodeNamedChildCountSansComments() == 0: - result = node.saveNodeData(gState) - - if gState.debug: - discard gState.nodeBranch.pop() - if gState.nodeBranch.Bl: - gecho "" - -proc searchAst(root: TSNode, astTable: AstTable, gState: State) = - var - node = root - nextnode: TSNode - depth = 0 - - while true: - if not node.tsNodeIsNull() and depth > -1: - let - name = $node.tsNodeType() - if name in astTable: - for ast in astTable[name]: - if gState.debug: - gecho "\n# " & gState.getNodeVal(node).replace("\n", "\n# ") & "\n" - if searchAstForNode(ast, node, gState): - ast.tonim(ast, node, gState) - if gState.debug: - gState.debugStr &= "\n# " & gState.data.join("\n# ") & "\n" - break - gState.data = @[] - else: - break - - if $node.tsNodeType() notin astTable and node.tsNodeNamedChildCount() != 0: - nextnode = node.tsNodeNamedChild(0) - depth += 1 - else: - nextnode = node.tsNodeNextNamedSibling() - - if nextnode.tsNodeIsNull(): - while true: - node = node.tsNodeParent() - depth -= 1 - if depth == -1: - break - if node == root: - break - if not node.tsNodeNextNamedSibling().tsNodeIsNull(): - node = node.tsNodeNextNamedSibling() - break - else: - node = nextnode - - if node == root: - break - -proc parseNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable) = - # Generate Nim from tree-sitter AST root node - var - fp = fullpath.replace("\\", "/") - - gState.currentHeader = getCurrentHeader(fullpath) - gState.impShort = gState.currentHeader.replace("header", "imp") - gState.sourceFile = fullpath - - if not gState.noHeader and gState.dynlib.Bl: - gState.constStr &= &"\n {gState.currentHeader} {{.used.}} = \"{fp}\"" - - root.searchAst(astTable, gState) - -proc printNim*(gState: State) = - # Print Nim generated by parseNim() - if gState.enumStr.nBl: - gecho &"{gState.enumStr}\n" - - gState.constStr = gState.getOverrideFinal(nskConst) & gState.constStr - if gState.constStr.nBl: - gecho &"const{gState.constStr}\n" - - gecho &""" -{{.pragma: {gState.impShort}, importc{gState.getHeaderPragma()}.}} -{{.pragma: {gState.impShort}C, {gState.impShort}, cdecl{gState.getDynlib()}.}} -""" - - gState.typeStr = gState.getOverrideFinal(nskType) & gState.typeStr - if gState.typeStr.nBl: - gecho &"type{gState.typeStr}\n" - - gState.procStr = gState.getOverrideFinal(nskProc) & gState.procStr - if gState.procStr.nBl: - gecho &"{gState.procStr}\n" - - gecho "{.pop.}" - - if gState.debug: - if gState.debugStr.nBl: - gecho gState.debugStr - - if gState.skipStr.nBl: - let - hash = gState.skipStr.hash().abs() - sname = getTempDir() / &"nimterop_{$hash}.h" - gecho &"# Writing skipped definitions to {sname}\n" - writeFile(sname, gState.skipStr) diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index b4070f3..0c1b784 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -304,131 +304,6 @@ proc getPreprocessor*(gState: State, fullpath: string) = rdata.add line gState.code = rdata.join("\n") -converter toString*(kind: Kind): string = - return case kind: - of exactlyOne: - "" - of oneOrMore: - "+" - of zeroOrMore: - "*" - of zeroOrOne: - "?" - of orWithNext: - "!" - -converter toKind*(kind: string): Kind = - return case kind: - of "+": - oneOrMore - of "*": - zeroOrMore - of "?": - zeroOrOne - of "!": - orWithNext - else: - exactlyOne - -proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool] = - if name[0] == '^': - result.recursive = true - result.name = name[1 .. ^1] - else: - result.name = name - result.kind = $name[^1] - - if result.kind != exactlyOne: - result.name = result.name[0 .. ^2] - -proc getRegexForAstChildren*(ast: ref Ast): string = - result = "^" - for i in 0 .. ast.children.len-1: - let - kind: string = ast.children[i].kind - begin = if result[^1] == '|': "" else: "(?:" - case kind: - of "!": - result &= &"{begin}{ast.children[i].name}|" - else: - result &= &"{begin}{ast.children[i].name}){kind}" - result &= "$" - -proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = - for i in 0 .. ast.children.len-1: - if name in ast.children[i].name.split("|"): - return ast.children[i] - - if ast.children.len == 1 and ast.children[0].name == ".": - return ast.children[0] - -proc getNimExpression*(gState: State, expr: string, name = ""): string = - # Convert C/C++ expression into Nim - cast identifiers to `name` if specified - var - clean = expr.multiReplace([("\n", " "), ("\r", "")]) - ident = "" - gen = "" - hex = false - - for i in 0 .. clean.len: - if i != clean.len: - if clean[i] in IdentChars: - if clean[i] in Digits and ident.Bl: - # Identifiers cannot start with digits - gen = $clean[i] - elif clean[i] in HexDigits and hex == true: - # Part of a hex number - gen = $clean[i] - elif i > 0 and i < clean.len-1 and clean[i] in ['x', 'X'] and - clean[i-1] == '0' and clean[i+1] in HexDigits: - # Found a hex number - gen = $clean[i] - hex = true - else: - # Part of an identifier - ident &= clean[i] - hex = false - else: - gen = (block: - if (i == 0 or clean[i-1] != '\'') or - (i == clean.len - 1 or clean[i+1] != '\''): - # If unquoted, convert logical ops to Nim - case clean[i] - of '^': " xor " - of '&': " and " - of '|': " or " - of '~': " not " - else: $clean[i] - else: - $clean[i] - ) - hex = false - - if i == clean.len or gen.nBl: - # Process identifier - if ident.nBl: - # Issue #178 - if ident != "_": - ident = gState.getIdentifier(ident, nskConst, name) - if name.nBl and ident in gState.constIdentifiers: - ident = ident & "." & name - result &= ident - ident = "" - result &= gen - gen = "" - - # Convert shift ops to Nim - result = result.multiReplace([ - ("<<", " shl "), (">>", " shr ") - ]) - -proc getComments*(gState: State, strip = false): string = - if not gState.noComments and gState.commentStr.nBl: - result = "\n" & gState.commentStr - if strip: - result = result.replace("\n ", "\n") - gState.commentStr = "" - # Plugin related proc dll*(path: string): string = diff --git a/nimterop/toastlib/grammar.nim b/nimterop/toastlib/grammar.nim deleted file mode 100644 index 52b19e7..0000000 --- a/nimterop/toastlib/grammar.nim +++ /dev/null @@ -1,768 +0,0 @@ -import macros, strformat, strutils, tables - -import regex - -import ".."/[globals, treesitter/api] -import "."/[ast, getters, lisp, tshelp] - -type - Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, gState: State) {.nimcall.}]] - -proc getPtrType(str: string): string = - result = case str: - of "ptr cchar": - "cstring" - of "ptr ptr cchar": - "ptr cstring" - of "ptr object": - "pointer" - of "ptr ptr object": - "ptr pointer" - of "ptr FILE": - "File" - else: - str - -proc getLit(str: string): string = - # Used to convert #define literals into const - let - str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() - - if str.contains(re"^[\-]?[\d]*[.]?[\d]+$") or # decimal - str.contains(re"^0x[\da-fA-F]+$") or # hexadecimal - str.contains(re"^'[[:ascii:]]'$") or # char - str.contains(re"""^"[[:ascii:]]+"$"""): # char * - return str - -proc initGrammar(): Grammar = - # #define X Y - result.add((""" - (preproc_def - (identifier) - (preproc_arg) - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# define X Y" - - let - name = gState.data[0].val - nname = gState.getIdentifier(name, nskConst) - val = gState.data[1].val.getLit() - - if not nname.nBl: - let - override = gState.getOverride(name, nskConst) - if override.nBl: - gState.constStr &= &"{gState.getComments()}\n{override}" - else: - gState.constStr &= &"{gState.getComments()}\n # Const '{name}' skipped" - if gState.debug: - gState.skipStr &= &"\n{gState.getNodeVal(node)}" - elif val.nBl and gState.addNewIdentifer(nname): - gState.constStr &= &"{gState.getComments()}\n {nname}* = {val}" - )) - - let - typeGrammar = """ - (type_qualifier?) - (primitive_type|type_identifier?) - (type_qualifier?) - (sized_type_specifier? - (primitive_type?) - ) - (struct_specifier|union_specifier|enum_specifier? - (type_identifier) - ) - """ - - arrGrammar = &""" - (array_declarator! - (pointer_declarator! - (pointer_declarator! - (type_identifier) - ) - (type_identifier) - ) - (type_identifier|identifier) - (identifier|number_literal) - ) - """ - - paramListGrammar = &""" - (parameter_list - (parameter_declaration* - {typeGrammar} - (identifier|type_identifier?) - (pointer_declarator? - (type_qualifier?) - (pointer_declarator! - (type_qualifier?) - {arrGrammar} - (identifier|type_identifier) - ) - {arrGrammar} - (identifier|type_identifier) - ) - {arrGrammar} - (abstract_pointer_declarator? - (abstract_pointer_declarator?) - ) - ) - ) - """ - - funcGrammar = &""" - (function_declarator* - (identifier|type_identifier!) - (pointer_declarator - (pointer_declarator! - (type_identifier) - ) - (type_identifier|identifier) - ) - {paramListGrammar} - (noexcept|throw_specifier?) - ) - """ - - template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen: untyped): untyped = - ptyp = gState.getIdentifier(gState.data[i].val, nskType, fname).getType() - - pptr = "" - while i+1 < gState.data.len and gState.data[i+1].name == "pointer_declarator": - pptr &= "ptr " - i += 1 - - if i+1 < gState.data.len and gState.data[i+1].name == "identifier": - pname = gState.getIdentifier(gState.data[i+1].val, nskParam, fname) - i += 2 - else: - pname = "a" & $count - count += 1 - i += 1 - - if i < gState.data.len and gState.data[i].name in ["identifier", "number_literal"]: - flen = gState.data[i].val - if gState.data[i].name == "identifier": - flen = gState.getIdentifier(flen, nskConst, fname) - - pout &= &"{pname}: array[{flen}, {getPtrType(pptr&ptyp)}], " - i += 1 - elif pptr.nBl or ptyp != "object": - pout &= &"{pname}: {getPtrType(pptr&ptyp)}, " - - # typedef int X - # typedef X Y - # typedef struct X Y - # typedef ?* Y - result.add((&""" - (type_definition - {typeGrammar} - (type_identifier!) - {arrGrammar} - (pointer_declarator! - (pointer_declarator! - (type_identifier!) - {arrGrammar} - {funcGrammar} - ) - (type_identifier!) - {arrGrammar} - {funcGrammar} - ) - {funcGrammar} - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# typedef X Y" - - var - i = 0 - typ = gState.getIdentifier(gState.data[i].val, nskType, "IgnoreSkipSymbol").getType() - name = "" - nname = "" - tptr = "" - aptr = "" - pragmas: seq[string] = @[] - - i += 1 - while i < gState.data.len and "pointer" in gState.data[i].name: - case gState.data[i].name: - of "pointer_declarator": - tptr &= "ptr " - i += 1 - of "array_pointer_declarator": - aptr &= "ptr " - i += 1 - - if i < gState.data.len: - name = gState.data[i].val - nname = gState.getIdentifier(name, nskType) - i += 1 - - if not gState.noHeader and gState.dynlib.Bl: - pragmas.add gState.getImportC(name, nname) - - let - pragma = gState.getPragma(pragmas) - - if not nname.nBl: - let - override = gState.getOverride(name, nskType) - if override.nBl: - gState.typeStr &= &"{gState.getComments()}\n{override}" - elif nname notin gTypeMap and typ.nBl and gState.addNewIdentifer(nname): - if i < gState.data.len and gState.data[^1].name == "function_declarator": - var - fname = nname - pout, pname, ptyp, pptr = "" - count = 1 - flen = "" - - while i < gState.data.len: - if gState.data[i].name == "function_declarator": - break - - funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) - - if pout.nBl and pout[^2 .. ^1] == ", ": - pout = pout[0 .. ^3] - - if tptr.nBl or typ != "object": - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}" - else: - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}" - else: - if i < gState.data.len and gState.data[i].name in ["identifier", "number_literal"]: - var - flen = gState.data[i].val - if gState.data[i].name == "identifier": - flen = gState.getIdentifier(flen, nskConst, nname) - - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" - else: - if nname == typ: - pragmas.add "incompleteStruct" - let - pragma = gState.getPragma(pragmas) - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = object" - else: - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = {getPtrType(tptr&typ)}" - )) - - proc pDupTypeCommon(nname: string, fend: int, gState: State, isEnum=false) = - if gState.debug: - gState.debugStr &= "\n# pDupTypeCommon()" - - var - dname = gState.data[^1].val - ndname = gState.getIdentifier(dname, nskType) - dptr = - if fend == 2: - "ptr " - else: - "" - - if ndname.nBl and ndname != nname: - if isEnum: - if gState.addNewIdentifer(ndname): - gState.enumStr &= &"{gState.getComments(true)}\ntype {ndname}* = {dptr}{nname}" - else: - if gState.addNewIdentifer(ndname): - let - pragma = gState.getPragma(gState.getImportc(dname, ndname), "bycopy") - gState.typeStr &= - &"{gState.getComments()}\n {ndname}*{pragma} = {dptr}{nname}" - - proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, gState: State) = - if gState.debug: - gState.debugStr &= "\n# pStructCommon" - - var - nname = gState.getIdentifier(name, nskType) - prefix = "" - union = "" - - case $node.tsNodeType(): - of "struct_specifier": - prefix = "struct " - of "union_specifier": - prefix = "union " - union = ", union" - of "type_definition": - if node.getTSNodeNamedChildCountSansComments() != 0: - for i in 0 .. node.tsNodeNamedChildCount()-1: - let - nchild = $node.tsNodeNamedChild(i).tsNodeType() - if nchild != "comment": - case nchild: - of "struct_specifier": - if fstart == 1: - prefix = "struct " - of "union_specifier": - if fstart == 1: - prefix = "union " - union = ", union" - break - - if not nname.nBl: - let - override = gState.getOverride(name, nskType) - if override.nBl: - gState.typeStr &= &"{gState.getComments()}\n{override}" - elif gState.addNewIdentifer(nname): - if gState.data.len == 1: - gState.typeStr &= &"{gState.getComments()}\n {nname}* {{.bycopy{union}.}} = object" - else: - var - pragmas: seq[string] = @[] - if not gState.noHeader and gState.dynlib.Bl: - pragmas.add gState.getImportC(prefix & name, nname) - pragmas.add "bycopy" - if union.nBl: - pragmas.add "union" - - let - pragma = gState.getPragma(pragmas) - - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = object" - - var - i = fstart - ftyp, fname: string - fptr = "" - aptr = "" - flen = "" - while i < gState.data.len-fend: - fptr = "" - aptr = "" - if gState.data[i].name == "field_declaration": - i += 1 - continue - - if gState.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]: - ftyp = gState.getIdentifier(gState.data[i].val, nskType, nname).getType() - i += 1 - - while i < gState.data.len-fend and "pointer" in gState.data[i].name: - case gState.data[i].name: - of "pointer_declarator": - fptr &= "ptr " - i += 1 - of "array_pointer_declarator": - aptr &= "ptr " - i += 1 - - fname = gState.getIdentifier(gState.data[i].val, nskField, nname) - - if i+1 < gState.data.len-fend and gState.data[i+1].name in gEnumVals: - # Struct field is an array where size is an expression - var - flen = gState.getNimExpression(gState.data[i+1].val) - if "/" in flen: - flen = &"({flen}).int" - gState.typeStr &= &"{gState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" - i += 2 - elif i+1 < gState.data.len-fend and gState.data[i+1].name == "bitfield_clause": - let - size = gState.data[i+1].val - gState.typeStr &= &"{gState.getComments()}\n {fname}* {{.bitsize: {size}.}} : {getPtrType(fptr&ftyp)} " - i += 2 - elif i+1 < gState.data.len-fend and gState.data[i+1].name == "function_declarator": - var - pout, pname, ptyp, pptr = "" - count = 1 - - i += 2 - while i < gState.data.len-fend: - if gState.data[i].name == "function_declarator": - i += 1 - continue - - if gState.data[i].name == "field_declaration": - break - - funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) - - if pout.nBl and pout[^2 .. ^1] == ", ": - pout = pout[0 .. ^3] - if fptr.nBl or ftyp != "object": - gState.typeStr &= &"{gState.getComments()}\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}" - else: - gState.typeStr &= &"{gState.getComments()}\n {fname}*: proc({pout}) {{.cdecl.}}" - i += 1 - else: - if ftyp == "object": - gState.typeStr &= &"{gState.getComments()}\n {fname}*: pointer" - else: - gState.typeStr &= &"{gState.getComments()}\n {fname}*: {getPtrType(fptr&ftyp)}" - i += 1 - - if node.tsNodeType() == "type_definition" and - gState.data[^1].name == "type_identifier" and gState.data[^1].val.nBl: - pDupTypeCommon(nname, fend, gState, false) - - let - fieldGrammar = &""" - (field_identifier!) - (bitfield_clause! - (number_literal) - ) - (array_declarator! - (field_identifier!) - (pointer_declarator - (pointer_declarator! - (field_identifier) - ) - (field_identifier) - ) - (^$1+) - ) - (function_declarator+ - (pointer_declarator - (pointer_declarator! - (field_identifier) - ) - (field_identifier) - ) - {paramListGrammar} - ) - """ % gEnumVals.join("|") - - fieldListGrammar = &""" - (field_declaration_list? - (field_declaration+ - {typeGrammar} - (pointer_declarator! - (pointer_declarator! - {fieldGrammar} - ) - {fieldGrammar} - ) - {fieldGrammar} - ) - ) - """ - - # struct X {} - result.add((&""" - (struct_specifier|union_specifier - (type_identifier) - {fieldListGrammar} - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# struct X {}" - - pStructCommon(ast, node, gState.data[0].val, 1, 1, gState) - )) - - # typedef struct X {} - result.add((&""" - (type_definition - (struct_specifier|union_specifier - (type_identifier?) - {fieldListGrammar} - ) - (type_identifier!) - (pointer_declarator - (pointer_declarator! - (type_identifier) - ) - (type_identifier) - ) - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# typedef struct X {}" - - var - fstart = 0 - fend = 1 - - if gState.data[^2].name == "pointer_declarator": - fend = 2 - - if gState.data.len > 1 and - gState.data[0].name == "type_identifier" and - gState.data[1].name notin ["field_identifier", "pointer_declarator"]: - - fstart = 1 - pStructCommon(ast, node, gState.data[0].val, fstart, fend, gState) - else: - pStructCommon(ast, node, gState.data[^1].val, fstart, fend, gState) - )) - - proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, gState: State) = - if gState.debug: - gState.debugStr &= "\n# pEnumCommon()" - - let nname = - if name.Bl: - getUniqueIdentifier(gState, "Enum") - else: - gState.getIdentifier(name, nskType) - - if nname.nBl and gState.addNewIdentifer(nname): - gState.enumStr &= &"{gState.getComments(true)}\ndefineEnum({nname})" - - var - i = fstart - count = 0 - while i < gState.data.len-fend: - if gState.data[i].name == "enumerator": - i += 1 - continue - - let - fname = gState.getIdentifier(gState.data[i].val, nskEnumField) - - if i+1 < gState.data.len-fend and - gState.data[i+1].name in gEnumVals: - if fname.nBl and gState.addNewIdentifer(fname): - gState.constStr &= &"{gState.getComments()}\n {fname}* = ({gState.getNimExpression(gState.data[i+1].val)}).{nname}" - try: - count = gState.data[i+1].val.parseInt() + 1 - except: - count += 1 - i += 2 - else: - if fname.nBl and gState.addNewIdentifer(fname): - gState.constStr &= &"{gState.getComments()}\n {fname}* = {count}.{nname}" - i += 1 - count += 1 - - if node.tsNodeType() == "type_definition" and - gState.data[^1].name == "type_identifier" and gState.data[^1].val.nBl: - pDupTypeCommon(nname, fend, gState, true) - - # enum X {} - result.add((""" - (enum_specifier - (type_identifier?) - (enumerator_list - (enumerator+ - (identifier?) - (^$1+) - ) - ) - ) - """ % gEnumVals.join("|"), - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# enum X {}" - - var - name = "" - offset = 0 - - if gState.data[0].name == "type_identifier": - name = gState.data[0].val - offset = 1 - - pEnumCommon(ast, node, name, offset, 0, gState) - )) - - # typedef enum {} X - result.add((&""" - (type_definition - {result[^1].grammar} - (type_identifier!) - (pointer_declarator - (pointer_declarator! - (type_identifier) - ) - (type_identifier) - ) - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# typedef enum {}" - - var - fstart = 0 - fend = 1 - - if gState.data[^2].name == "pointer_declarator": - fend = 2 - - if gState.data[0].name == "type_identifier": - fstart = 1 - - pEnumCommon(ast, node, gState.data[0].val, fstart, fend, gState) - else: - pEnumCommon(ast, node, gState.data[^1].val, fstart, fend, gState) - )) - - # typ function(typ param1, ...) - result.add((&""" - (declaration - (storage_class_specifier?) - {typeGrammar} - (pointer_declarator! - (pointer_declarator! - {funcGrammar} - ) - {funcGrammar} - ) - {funcGrammar} - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# typ function" - - var - fptr = "" - i = 1 - - while i < gState.data.len: - if gState.data[i].name == "function_declarator": - i += 1 - continue - - fptr = "" - while i < gState.data.len and gState.data[i].name == "pointer_declarator": - fptr &= "ptr " - i += 1 - - var - fname = gState.data[i].val - fnname = gState.getIdentifier(fname, nskProc) - pout, pname, ptyp, pptr = "" - count = 1 - flen = "" - fVar = false - - i += 1 - if i < gState.data.len and gState.data[i].name == "pointer_declarator": - fVar = true - i += 1 - - while i < gState.data.len: - if gState.data[i].name == "function_declarator": - break - - funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i, flen) - - if pout.nBl and pout[^2 .. ^1] == ", ": - pout = pout[0 .. ^3] - - if not fnname.nBl: - let - override = gState.getOverride(fname, nskProc) - if override.nBl: - gState.typeStr &= &"{gState.getComments()}\n{override}" - elif gState.addNewIdentifer(fnname): - let - ftyp = gState.getIdentifier(gState.data[0].val, nskType, fnname).getType() - pragma = gState.getPragma(gState.getImportC(fname, fnname), "cdecl") - - if fptr.nBl or ftyp != "object": - if fVar: - gState.procStr &= &"{gState.getComments(true)}\nvar {fnname}*: proc ({pout}): {getPtrType(fptr&ftyp)}{{.cdecl.}}" - else: - gState.procStr &= &"{gState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" - else: - if fVar: - gState.procStr &= &"{gState.getComments(true)}\nvar {fnname}*: proc ({pout}){{.cdecl.}}" - else: - gState.procStr &= &"{gState.getComments(true)}\nproc {fnname}*({pout}){pragma}" - )) - - # // comment - result.add((&""" - (comment - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - let - cmt = $gState.getNodeVal(node) - - for line in cmt.splitLines(): - let - line = line.multiReplace([("//", ""), ("/*", ""), ("*/", "")]) - - gState.commentStr &= &"\n # {line.strip(leading=false)}" - )) - - # // unknown - result.add((&""" - (type_definition|struct_specifier|union_specifier|enum_specifier|declaration - (^.*) - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - var - done = false - for i in gState.data: - case $node.tsNodeType() - of "declaration": - if i.name == "identifier": - let - override = gState.getOverride(i.val, nskProc) - - if override.nBl: - gState.procStr &= &"{gState.getComments(true)}\n{override}" - done = true - break - else: - gState.procStr &= &"{gState.getComments(true)}\n# Declaration '{i.val}' skipped" - - else: - if i.name == "type_identifier": - let - override = gState.getOverride(i.val, nskType) - - if override.nBl: - gState.typeStr &= &"{gState.getComments()}\n{override}" - done = true - break - else: - gState.typeStr &= &"{gState.getComments()}\n # Type '{i.val}' skipped" - - if gState.debug and not done: - gState.skipStr &= &"\n{gState.getNodeVal(node)}" - )) - -proc initRegex(ast: ref Ast) = - if ast.children.nBl: - if not ast.recursive: - for child in ast.children: - child.initRegex() - - var - reg: string - try: - reg = ast.getRegexForAstChildren() - ast.regex = reg.re() - except: - echo reg - raise newException(Exception, getCurrentExceptionMsg()) - -proc parseGrammar*(): AstTable = - const grammars = initGrammar() - - result = newTable[string, seq[ref Ast]]() - for i in 0 .. grammars.len-1: - var - ast = grammars[i].grammar.parseLisp() - - ast.tonim = grammars[i].call - ast.initRegex() - for n in ast.name.split("|"): - if n notin result: - result[n] = @[ast] - else: - result[n].add(ast) - -proc printGrammar*(gState: State, astTable: AstTable) = - for name in astTable.keys(): - for ast in astTable[name]: - gecho ast.printAst() diff --git a/nimterop/toastlib/lisp.nim b/nimterop/toastlib/lisp.nim deleted file mode 100644 index 57d71a1..0000000 --- a/nimterop/toastlib/lisp.nim +++ /dev/null @@ -1,60 +0,0 @@ -import ".."/globals -import "."/getters - -var - gTokens: seq[string] - idx = 0 - -proc tokenize(tree: string) = - var collect = "" - - gTokens = @[] - idx = 0 - for i in tree: - case i: - of ' ', '\n', '\r', '(', ')': - if collect.nBl: - gTokens.add(collect) - collect = "" - if i in ['(', ')']: - gTokens.add($i) - else: - collect &= $i - -proc readFromTokens(): ref Ast = - if idx == gTokens.len: - doAssert false, "Bad AST " & $(idx: idx) - - if gTokens[idx] == "(": - if gTokens.len - idx < 2: - doAssert false, "Corrupt AST " & $(gTokensLen: gTokens.len, idx: idx) - result = new(Ast) - (result.name, result.kind, result.recursive) = gTokens[idx+1].getNameKind() - result.children = @[] - if result.recursive: - result.children.add(result) - idx += 2 - while gTokens[idx] != ")": - var res = readFromTokens() - if not res.isNil: - result.children.add(res) - elif gTokens[idx] == ")": - doAssert false, "Poor AST " & $(idx: idx) - - idx += 1 - -proc printAst*(node: ref Ast, offset=""): string = - result = offset & "(" & (if node.recursive: "^" else: "") & node.name & node.kind.toString() - - if node.children.nBl and not node.recursive: - result &= "\n" - for child in node.children: - result &= printAst(child, offset & " ") - result &= offset & ")\n" - else: - result &= ")\n" - -proc parseLisp*(tree: string): ref Ast = - tokenize(tree) - - return readFromTokens() diff --git a/nimterop/toastlib/tshelp.nim b/nimterop/toastlib/tshelp.nim index e7e8d75..9310cf7 100644 --- a/nimterop/toastlib/tshelp.nim +++ b/nimterop/toastlib/tshelp.nim @@ -2,7 +2,6 @@ import sets, strformat, strutils import ".."/treesitter/[api, c, cpp] import ".."/globals -import "."/getters template withCodeAst*(code: string, mode: string, body: untyped): untyped = ## A simple template to inject the TSNode into a body of code diff --git a/tests/getheader.nims b/tests/getheader.nims index 916abcf..e5d964c 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -14,7 +14,7 @@ proc testCall(cmd, output: string, exitCode: int, delete = true) = doAssert outp.contains(output), outp var - cmd = "nim c -f --hints:off -d:FLAGS=\"-f:ast2\" -d:checkAbi" + cmd = "nim c -f --hints:off -d:checkAbi" lrcmd = " -r lzma.nim" zrcmd = " -r zlib.nim" sshcmd = " -r libssh2.nim" diff --git a/tests/libssh2.nim b/tests/libssh2.nim index 172f6ae..09343bc 100644 --- a/tests/libssh2.nim +++ b/tests/libssh2.nim @@ -17,12 +17,12 @@ cOverride: SOCKET = object when not libssh2Static: - cImport(libssh2Path, recurse = true, dynlib = "libssh2LPath", flags = "-f:ast2 -c -E_ -F_") + cImport(libssh2Path, recurse = true, dynlib = "libssh2LPath", flags = "-c -E_ -F_") when not defined(Windows) and not isDefined(libssh2JBB): proc zlibVersion(): cstring {.importc, dynlib: libssh2LPath.} else: - cImport(libssh2Path, recurse = true, flags = "-f:ast2 -c -E_ -F_") + cImport(libssh2Path, recurse = true, flags = "-c -E_ -F_") when not defined(Windows) and not isDefined(libssh2JBB): proc zlibVersion(): cstring {.importc.} diff --git a/tests/rsa.nim b/tests/rsa.nim index a4aa64b..f5c343c 100644 --- a/tests/rsa.nim +++ b/tests/rsa.nim @@ -39,7 +39,7 @@ cOverride: cImport(@[ basePath / "rsa.h", basePath / "err.h", -], recurse = true, flags = "-f:ast2 -s -c " & FLAGS) +], recurse = true, flags = "-s -c " & FLAGS) {.passL: cryptoLPath.}