More pointer support, cpp mode default in toast, cleanup

This commit is contained in:
Ganesh Viswanathan 2018-11-21 23:45:12 -06:00
commit b9b5174759
11 changed files with 132 additions and 89 deletions

View file

@ -65,6 +65,8 @@ Detailed documentation is still forthcoming.
`cAddSearchDir("XXX")` - add directory XXX to search path in calls to `cSearchPath()` `cAddSearchDir("XXX")` - add directory XXX to search path in calls to `cSearchPath()`
`cAddStdDir("XXX")` - add standard "c" [default] or "cpp" include paths to search path
`cSearchPath("header.h")` - return a file or directory found in search path configured using `cSearchPath()` - can be used in `cCompile()`, `cIncludeDir()` and `cImport()` calls `cSearchPath("header.h")` - return a file or directory found in search path configured using `cSearchPath()` - can be used in `cCompile()`, `cIncludeDir()` and `cImport()` calls
`gitPull()` - pull a git repository prior to C/C++ interop `gitPull()` - pull a git repository prior to C/C++ interop

View file

@ -21,7 +21,7 @@ proc addHeader*(fullpath: string) =
# #
proc pPreprocDef(node: ref Ast) = proc pPreprocDef(node: ref Ast) =
if node.children.len() == 2: if node.children.len == 2:
let let
name = getNodeValIf(node.children[0], identifier) name = getNodeValIf(node.children[0], identifier)
val = getNodeValIf(node.children[1], preproc_arg) val = getNodeValIf(node.children[1], preproc_arg)
@ -37,30 +37,42 @@ proc pPreprocDef(node: ref Ast) =
# #
proc typeScan(node: ref Ast, sym, id: Sym, offset: string): string = proc typeScan(node: ref Ast, sym, id: Sym, offset: string): string =
if node.sym != sym or node.children.len() != 2: if node.sym != sym or node.children.len != 2:
return return
let var
pname = getNodeValIf(node.children[1], id) name = getNodeValIf(node.children[1], id)
ptyp = getNodeValIf(node.children[0], primitive_type) ptyp = getNodeValIf(node.children[0], primitive_type)
ttyp = getNodeValIf(node.children[0], type_identifier) ttyp = getNodeValIf(node.children[0], type_identifier)
ptrname = false
if pname.len() == 0: if name.len == 0 and node.children[1].sym == pointer_declarator and node.children[1].children.len == 1:
name = getNodeValIf(node.children[1].children[0], id)
ptrname = true
if name.len == 0:
return return
elif ptyp.nBl: elif ptyp.nBl:
result = &"{offset}{pname.getIdentifier()}: {ptyp.getType()}" ptyp = ptyp.getType()
if ptyp != "object" and ptrname:
ptyp = &"ptr {ptyp}"
result = &"{offset}{name.getIdentifier()}: {ptyp}"
elif ttyp.nBl: elif ttyp.nBl:
result = &"{offset}{pname.getIdentifier()}: {ttyp}" if ptrname:
elif node.children[0].sym in [struct_specifier, enum_specifier] and node.children[0].children.len() == 1: ttyp = &"ptr {ttyp}"
let styp = getNodeValIf(node.children[0].children[0], type_identifier) result = &"{offset}{name.getIdentifier()}: {ttyp}"
elif node.children[0].sym in [struct_specifier, enum_specifier] and node.children[0].children.len == 1:
var styp = getNodeValIf(node.children[0].children[0], type_identifier)
if styp.nBl: if styp.nBl:
result = &"{offset}{pname.getIdentifier()}: {styp}" if ptrname:
styp = &"ptr {styp}"
result = &"{offset}{name.getIdentifier()}: {styp}"
else: else:
return return
proc pStructSpecifier(node: ref Ast, name = "") = proc pStructSpecifier(node: ref Ast, name = "") =
var stmt: string var stmt: string
if node.children.len() == 1 and name notin gTypes: if node.children.len == 1 and name notin gTypes:
case node.children[0].sym: case node.children[0].sym:
of type_identifier: of type_identifier:
let typ = getNodeValIf(node.children[0], type_identifier) let typ = getNodeValIf(node.children[0], type_identifier)
@ -68,18 +80,18 @@ proc pStructSpecifier(node: ref Ast, name = "") =
gTypes.add(name) gTypes.add(name)
if name != typ: if name != typ:
# typedef struct X Y # typedef struct X Y
gTypeStr &= &" {name}* = {typ} #1 pStructSpecifier()\n" gTypeStr &= &" {name.getIdentifier()}* = {typ} #1 pStructSpecifier()\n"
else: else:
# typedef struct X X # typedef struct X X
gTypeStr &= &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 pStructSpecifier()\n" gTypeStr &= &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 pStructSpecifier()\n"
of field_declaration_list: of field_declaration_list:
# typedef struct { fields } X # typedef struct { fields } X
stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 pStructSpecifier()\n" stmt = &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 pStructSpecifier()\n"
for field in node.children[0].children: for field in node.children[0].children:
let ts = typeScan(field, field_declaration, field_identifier, " ") let ts = typeScan(field, field_declaration, field_identifier, " ")
if ts.len() == 0: if ts.len == 0:
return return
stmt &= ts & "\n" stmt &= ts & "\n"
@ -88,7 +100,7 @@ proc pStructSpecifier(node: ref Ast, name = "") =
else: else:
discard discard
elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == field_declaration_list: elif name.len == 0 and node.children.len == 2 and node.children[1].sym == field_declaration_list:
let ename = getNodeValIf(node.children[0], type_identifier) let ename = getNodeValIf(node.children[0], type_identifier)
if ename.nBl and ename notin gTypes: if ename.nBl and ename notin gTypes:
# struct X { fields } # struct X { fields }
@ -96,7 +108,7 @@ proc pStructSpecifier(node: ref Ast, name = "") =
for field in node.children[1].children: for field in node.children[1].children:
let ts = typeScan(field, field_declaration, field_identifier, " ") let ts = typeScan(field, field_declaration, field_identifier, " ")
if ts.len() == 0: if ts.len == 0:
return return
stmt &= ts & "\n" stmt &= ts & "\n"
@ -109,12 +121,12 @@ proc pEnumSpecifier(node: ref Ast, name = "") =
elid: int elid: int
stmt: string stmt: string
if node.children.len() == 1 and node.children[0].sym == enumerator_list: if node.children.len == 1 and node.children[0].sym == enumerator_list:
# typedef enum { fields } X # typedef enum { fields } X
ename = name ename = name
elid = 0 elid = 0
stmt = &" {name}* = enum #1 pEnumSpecifier()\n" stmt = &" {name.getIdentifier()}* = enum #1 pEnumSpecifier()\n"
elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == enumerator_list: elif name.len == 0 and node.children.len == 2 and node.children[1].sym == enumerator_list:
ename = getNodeValIf(node.children[0], type_identifier) ename = getNodeValIf(node.children[0], type_identifier)
elid = 1 elid = 1
if ename.nBl: if ename.nBl:
@ -126,9 +138,9 @@ proc pEnumSpecifier(node: ref Ast, name = "") =
for field in node.children[elid].children: for field in node.children[elid].children:
if field.sym == enumerator: if field.sym == enumerator:
let fname = getNodeValIf(field.children[0], identifier) let fname = getNodeValIf(field.children[0], identifier)
if field.children.len() == 1: if field.children.len == 1:
stmt &= &" {fname}\n" stmt &= &" {fname}\n"
elif field.children.len() == 2 and field.children[1].sym == number_literal: elif field.children.len == 2 and field.children[1].sym == number_literal:
let num = getNodeValIf(field.children[1], number_literal) let num = getNodeValIf(field.children[1], number_literal)
stmt &= &" {fname} = {num}\n" stmt &= &" {fname} = {num}\n"
else: else:
@ -139,25 +151,31 @@ proc pEnumSpecifier(node: ref Ast, name = "") =
gTypeStr &= stmt gTypeStr &= stmt
proc pTypeDefinition(node: ref Ast) = proc pTypeDefinition(node: ref Ast) =
if node.children.len() == 2: if node.children.len == 2:
var var
name = getNodeValIf(node.children[1], type_identifier) name = getNodeValIf(node.children[1], type_identifier)
pname = getNodeValIf(node.children[1], pointer_declarator)
ptyp = getNodeValIf(node.children[0], primitive_type) ptyp = getNodeValIf(node.children[0], primitive_type)
ttyp = getNodeValIf(node.children[0], type_identifier) ttyp = getNodeValIf(node.children[0], type_identifier)
ptrname = false
if name.len() == 0 and node.children[1].sym == pointer_declarator and node.children[1].children.len() == 1: if name.len == 0 and node.children[1].sym == pointer_declarator and node.children[1].children.len == 1:
name = getNodeValIf(node.children[1].children[0], type_identifier) name = getNodeValIf(node.children[1].children[0], type_identifier)
ptrname = true
if name.nBl and name notin gTypes: if name.nBl and name notin gTypes:
if ptyp.nBl: if ptyp.nBl:
# typedef int X # typedef int X
gTypes.add(name) gTypes.add(name)
gTypeStr &= &" {name}* = {ptyp.getType()} #1 pTypeDefinition()\n" ptyp = ptyp.getType()
if ptyp != "object" and ptrname:
ptyp = &"ptr {ptyp}"
gTypeStr &= &" {name.getIdentifier()}* = {ptyp} #1 pTypeDefinition()\n"
elif ttyp.nBl: elif ttyp.nBl:
# typedef X Y # typedef X Y
gTypes.add(name) gTypes.add(name)
gTypeStr &= &" {name}* = {ttyp} #2 pTypeDefinition()\n" if ptrname:
ttyp = &"ptr {ttyp}"
gTypeStr &= &" {name.getIdentifier()}* = {ttyp} #2 pTypeDefinition()\n"
else: else:
case node.children[0].sym: case node.children[0].sym:
of struct_specifier: of struct_specifier:
@ -168,20 +186,20 @@ proc pTypeDefinition(node: ref Ast) =
discard discard
proc pFunctionDeclarator(node: ref Ast, typ: string) = proc pFunctionDeclarator(node: ref Ast, typ: string) =
if node.children.len() == 2: if node.children.len == 2:
let let
name = getNodeValIf(node.children[0], identifier) name = getNodeValIf(node.children[0], identifier)
if name.nBl and name notin gProcs and node.children[1].sym == parameter_list: if name.nBl and name notin gProcs and node.children[1].sym == parameter_list:
# typ function(typ param1, ...) # typ function(typ param1, ...)
var stmt = &"# pFunctionDeclarator()\nproc {name}*(" var stmt = &"# pFunctionDeclarator()\nproc {name.getIdentifier()}*("
for i in 0 .. node.children[1].children.len()-1: for i in 0 .. node.children[1].children.len-1:
let ts = typeScan(node.children[1].children[i], parameter_declaration, identifier, "") let ts = typeScan(node.children[1].children[i], parameter_declaration, identifier, "")
if ts.len() == 0: if ts.len == 0:
return return
stmt &= ts stmt &= ts
if i != node.children[1].children.len()-1: if i != node.children[1].children.len-1:
stmt &= ", " stmt &= ", "
if typ != "void": if typ != "void":
@ -195,7 +213,7 @@ proc pFunctionDeclarator(node: ref Ast, typ: string) =
gProcStr &= stmt gProcStr &= stmt
proc pDeclaration*(node: ref Ast) = proc pDeclaration*(node: ref Ast) =
if node.children.len() == 2 and node.children[1].sym == function_declarator: if node.children.len == 2 and node.children[1].sym == function_declarator:
let let
ptyp = getNodeValIf(node.children[0], primitive_type) ptyp = getNodeValIf(node.children[0], primitive_type)
ttyp = getNodeValIf(node.children[0], type_identifier) ttyp = getNodeValIf(node.children[0], type_identifier)
@ -204,7 +222,7 @@ proc pDeclaration*(node: ref Ast) =
pFunctionDeclarator(node.children[1], ptyp.getType()) pFunctionDeclarator(node.children[1], ptyp.getType())
elif ttyp.nBl: elif ttyp.nBl:
pFunctionDeclarator(node.children[1], ttyp) pFunctionDeclarator(node.children[1], ttyp)
elif node.children[0].sym == struct_specifier and node.children[0].children.len() == 1: elif node.children[0].sym == struct_specifier and node.children[0].children.len == 1:
let styp = getNodeValIf(node.children[0].children[0], type_identifier) let styp = getNodeValIf(node.children[0].children[0], type_identifier)
if styp.nBl: if styp.nBl:
pFunctionDeclarator(node.children[1], styp) pFunctionDeclarator(node.children[1], styp)

View file

@ -17,7 +17,7 @@ proc findPath(path: string, fail = true): string =
proc cSearchPath*(path: string): string = proc cSearchPath*(path: string): string =
result = findPath(path, fail = false) result = findPath(path, fail = false)
if result.len() == 0: if result.len == 0:
var found = false var found = false
for inc in gSearchDirs: for inc in gSearchDirs:
result = (inc & "/" & path).replace("\\", "/") result = (inc & "/" & path).replace("\\", "/")
@ -31,12 +31,12 @@ proc cSearchPath*(path: string): string =
macro cDebug*(): untyped = macro cDebug*(): untyped =
gDebug = true gDebug = true
macro cDefine*(name: static[string], val: static[string] = ""): untyped = macro cDefine*(name: static string, val: static string = ""): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
var str = "-D" & name var str = "-D" & name
if val.nBl: if val.nBl:
str &= "=\"" & val & "\"" str &= &"=\"{val}\""
result.add(quote do: result.add(quote do:
{.passC: `str`.} {.passC: `str`.}
@ -45,36 +45,37 @@ macro cDefine*(name: static[string], val: static[string] = ""): untyped =
if gDebug: if gDebug:
echo result.repr echo result.repr
macro cAddSearchDir*(dir: static[string]): untyped = macro cAddSearchDir*(dir: static string): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
let fullpath = cSearchPath(dir) let fullpath = cSearchPath(dir)
if fullpath notin gSearchDirs: if fullpath notin gSearchDirs:
gSearchDirs.add(fullpath) gSearchDirs.add(fullpath)
macro cIncludeDir*(dir: static[string]): untyped = macro cIncludeDir*(dir: static string): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
let let
fullpath = findPath(dir) fullpath = findPath(dir)
str = "-I\"" & fullpath & "\"" str = &"-I\"{fullpath}\""
if fullpath notin gIncludeDirs: if fullpath notin gIncludeDirs:
gIncludeDirs.add(fullpath) gIncludeDirs.add(fullpath)
result.add(quote do: result.add(quote do:
{.passC: `str`.} {.passC: `str`.}
) )
if gDebug: if gDebug:
echo result.repr echo result.repr
macro cIncludeC*(): untyped = macro cAddStdDir*(mode = "c"): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
var var
inc = false inc = false
for line in getGccPaths().splitLines():
for line in getGccPaths(mode.strVal()).splitLines():
if "#include <...> search starts here" in line: if "#include <...> search starts here" in line:
inc = true inc = true
continue continue
@ -82,10 +83,11 @@ macro cIncludeC*(): untyped =
break break
if inc: if inc:
result = quote do: let sline = line.strip()
cIncludeDir(line) result.add quote do:
cAddSearchDir(`sline`)
macro cCompile*(path: static[string]): untyped = macro cCompile*(path: static string): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
var var
@ -129,7 +131,7 @@ macro cCompile*(path: static[string]): untyped =
if gDebug: if gDebug:
echo result.repr echo result.repr
macro cImport*(filename: static[string]): untyped = macro cImport*(filename: static string): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
result.add addReorder() result.add addReorder()

View file

@ -23,10 +23,11 @@ proc getNodeValIf*(node: ref Ast, esym: Sym): string =
return gCode[node.start .. node.stop-1].strip() return gCode[node.start .. node.stop-1].strip()
proc getGccPaths*(mode = "c"): string = proc getGccPaths*(mode = "c"): string =
let var
nul = when defined(Windows): "nul" else: "/dev/null" nul = when defined(Windows): "nul" else: "/dev/null"
mmode = if mode == "cpp": "c++" else: mode
return staticExec("gcc -Wp,-v -x" & mode & " " & nul) return staticExec("gcc -Wp,-v -x" & mmode & " " & nul)
proc getLineCol*(node: ref Ast): tuple[line, col: int] = proc getLineCol*(node: ref Ast): tuple[line, col: int] =
result.line = 1 result.line = 1

View file

@ -18,7 +18,7 @@ proc execAction*(cmd: string): string =
echo result echo result
quit(1) quit(1)
macro extractZip*(zipfile, outdir: static[string]): untyped = macro extractZip*(zipfile, outdir: static string): untyped =
var cmd = "unzip -o $#" var cmd = "unzip -o $#"
if defined(Windows): if defined(Windows):
cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " &
@ -28,7 +28,7 @@ macro extractZip*(zipfile, outdir: static[string]): untyped =
echo "Extracting " & zipfile echo "Extracting " & zipfile
discard execAction(&"cd \"{getProjectPath()/outdir}\" && " & cmd % zipfile) discard execAction(&"cd \"{getProjectPath()/outdir}\" && " & cmd % zipfile)
macro downloadUrl*(url, outdir: static[string]): untyped = macro downloadUrl*(url, outdir: static string): untyped =
let let
file = url.extractFilename() file = url.extractFilename()
ext = file.splitFile().ext.toLowerAscii() ext = file.splitFile().ext.toLowerAscii()
@ -45,7 +45,7 @@ macro downloadUrl*(url, outdir: static[string]): untyped =
discard quote do: discard quote do:
extractZip(`file`, `outdir`) extractZip(`file`, `outdir`)
macro gitReset*(outdir: static[string]): untyped = macro gitReset*(outdir: static string): untyped =
echo "Resetting " & outdir echo "Resetting " & outdir
let cmd = &"cd \"{getProjectPath()/outdir}\" && git reset --hard" let cmd = &"cd \"{getProjectPath()/outdir}\" && git reset --hard"
@ -53,7 +53,7 @@ macro gitReset*(outdir: static[string]): untyped =
sleep(1000) sleep(1000)
echo " Retrying ..." echo " Retrying ..."
macro gitCheckout*(file, outdir: static[string]): untyped = macro gitCheckout*(file, outdir: static string): untyped =
echo "Resetting " & file echo "Resetting " & file
let cmd = &"cd \"{getProjectPath()/outdir}\" && git checkout $#" % file.replace(outdir & "/", "") let cmd = &"cd \"{getProjectPath()/outdir}\" && git checkout $#" % file.replace(outdir & "/", "")
@ -61,7 +61,7 @@ macro gitCheckout*(file, outdir: static[string]): untyped =
sleep(500) sleep(500)
echo " Retrying ..." echo " Retrying ..."
macro gitPull*(url: static[string], outdirN = "", plistN = "", checkoutN = ""): untyped = macro gitPull*(url: static string, outdirN = "", plistN = "", checkoutN = ""): untyped =
let let
outdir = getProjectPath()/outdirN.strVal() outdir = getProjectPath()/outdirN.strVal()
plist = plistN.strVal() plist = plistN.strVal()
@ -78,14 +78,14 @@ macro gitPull*(url: static[string], outdirN = "", plistN = "", checkoutN = ""):
discard execAction(&"cd \"{outdir}\" && git init .") discard execAction(&"cd \"{outdir}\" && git init .")
discard execAction(&"cd \"{outdir}\" && git remote add origin " & url) discard execAction(&"cd \"{outdir}\" && git remote add origin " & url)
if plist.len() != 0: if plist.len != 0:
let sparsefile = &"{outdir}/.git/info/sparse-checkout" let sparsefile = &"{outdir}/.git/info/sparse-checkout"
discard execAction(&"cd \"{outdir}\" && git config core.sparsecheckout true") discard execAction(&"cd \"{outdir}\" && git config core.sparsecheckout true")
writeFile(sparsefile, plist) writeFile(sparsefile, plist)
echo "Wrote" echo "Wrote"
if checkout.len() != 0: if checkout.len != 0:
echo "Checking out " & checkout echo "Checking out " & checkout
discard execAction(&"cd \"{outdir}\" && git pull --tags origin master") discard execAction(&"cd \"{outdir}\" && git pull --tags origin master")
discard execAction(&"cd \"{outdir}\" && git checkout {checkout}") discard execAction(&"cd \"{outdir}\" && git checkout {checkout}")

View file

@ -37,4 +37,4 @@ var
gTypeStr* {.compiletime.}: string gTypeStr* {.compiletime.}: string
template nBl*(s: untyped): untyped = template nBl*(s: untyped): untyped =
(s.len() != 0) (s.len != 0)

View file

@ -13,7 +13,7 @@ proc tokenize(fullpath: string) =
gTokens = @[] gTokens = @[]
idx = 0 idx = 0
for i in staticExec("toast -u " & fullpath): for i in staticExec("toast -m " & fullpath):
case i: case i:
of ' ', '\n', '\r', '(', ')': of ' ', '\n', '\r', '(', ')':
if collect.nBl: if collect.nBl:
@ -24,17 +24,17 @@ proc tokenize(fullpath: string) =
else: else:
collect &= $i collect &= $i
if gTokens.len() == 0: if gTokens.len == 0:
echo "toast binary not installed - nimble install nimterop to force build" echo "toast binary not installed - nimble install nimterop to force build"
quit(1) quit(1)
proc readFromTokens(): ref Ast = proc readFromTokens(): ref Ast =
if idx == gTokens.len(): if idx == gTokens.len:
echo "Bad AST" echo "Bad AST"
quit(1) quit(1)
if gTokens[idx] == "(": if gTokens[idx] == "(":
if gTokens.len() - idx < 2: if gTokens.len - idx < 2:
echo "Corrupt AST" echo "Corrupt AST"
quit(1) quit(1)
if gTokens[idx+1] != "comment": if gTokens[idx+1] != "comment":
@ -60,7 +60,7 @@ proc readFromTokens(): ref Ast =
proc printAst*(node: ref Ast, offset=""): string = proc printAst*(node: ref Ast, offset=""): string =
result = offset & "(" & $node.sym & " " & $node.start & " " & $node.stop result = offset & "(" & $node.sym & " " & $node.start & " " & $node.stop
if node.children.len() != 0: if node.children.len != 0:
result &= "\n" result &= "\n"
for child in node.children: for child in node.children:
result &= printAst(child, offset & " ") result &= printAst(child, offset & " ")

View file

@ -4,13 +4,15 @@ int test_call_int() {
return 5; return 5;
} }
struct STRUCT1 test_call_int_param(int param1) { #ifdef FORCE
struct STRUCT1 _test_call_int_param_(int param1) {
struct STRUCT1 s; struct STRUCT1 s;
s.field1 = param1; s.field1 = param1;
return s; return s;
} }
#endif
STRUCT2 test_call_int_param2(int param1, STRUCT2 param2) { STRUCT2 test_call_int_param2(int param1, STRUCT2 param2) {
STRUCT2 s; STRUCT2 s;

View file

@ -29,8 +29,15 @@ typedef enum {
enum6 enum6
} ENUM2; } ENUM2;
typedef void * VOIDPTR;
typedef int * INTPTR;
typedef struct {
int *field;
} STRUCT4;
int test_call_int(); int test_call_int();
struct STRUCT1 test_call_int_param(int param1); struct STRUCT1 _test_call_int_param_(int param1);
STRUCT2 test_call_int_param2(int param1, STRUCT2 param2); STRUCT2 test_call_int_param2(int param1, STRUCT2 param2);
STRUCT2 test_call_int_param3(int param1, struct STRUCT1 param2); STRUCT2 test_call_int_param3(int param1, struct STRUCT1 param2);
ENUM2 test_call_int_param4(enum ENUM param1); ENUM2 test_call_int_param4(enum ENUM param1);

View file

@ -2,6 +2,7 @@ import nimterop/cimport
cDebug() cDebug()
cDefine("FORCE")
cIncludeDir "include" cIncludeDir "include"
cAddSearchDir "include" cAddSearchDir "include"
cCompile cSearchPath("test.c") cCompile cSearchPath("test.c")
@ -18,10 +19,14 @@ var
s: STRUCT1 s: STRUCT1
s2: STRUCT2 s2: STRUCT2
s3: STRUCT3 s3: STRUCT3
s4: STRUCT4
e: ENUM e: ENUM
e2: ENUM2 = enum5 e2: ENUM2 = enum5
vptr: VOIDPTR
iptr: INTPTR
pt = 3 pt = 3
ct = 4 ct = 4
@ -37,3 +42,5 @@ doAssert test_call_int_param(5).field1 == 5
doAssert test_call_int_param2(5, s2).field1 == 11 doAssert test_call_int_param2(5, s2).field1 == 11
doAssert test_call_int_param3(5, s).field1 == 10 doAssert test_call_int_param3(5, s).field1 == 10
doAssert test_call_int_param4(e) == e2 doAssert test_call_int_param4(e) == e2
cAddStdDir()

View file

@ -6,12 +6,10 @@ import treesitter/[runtime, c, cpp]
const HELP = """ const HELP = """
> toast header.h > toast header.h
""" -m minimized output - non-pretty
-c C mode - CPP is default"""
var proc printLisp(root: TSNode, data: var string, pretty = true) =
gPretty = true
proc printLisp(root: TSNode, data: var string) =
var var
node = root node = root
nextnode: TSNode nextnode: TSNode
@ -19,17 +17,17 @@ proc printLisp(root: TSNode, data: var string) =
while true: while true:
if not node.tsNodeIsNull(): if not node.tsNodeIsNull():
if gPretty: if pretty:
stdout.write spaces(depth) stdout.write spaces(depth)
stdout.write "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte() stdout.write "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte()
if node.tsNodeNamedChildCount() != 0: if node.tsNodeNamedChildCount() != 0:
if gPretty: if pretty:
echo "" echo ""
nextnode = node.tsNodeNamedChild(0) nextnode = node.tsNodeNamedChild(0)
depth += 1 depth += 1
else: else:
if gPretty: if pretty:
echo ")" echo ")"
else: else:
stdout.write ")" stdout.write ")"
@ -39,7 +37,7 @@ proc printLisp(root: TSNode, data: var string) =
while true: while true:
node = node.tsNodeParent() node = node.tsNodeParent()
depth -= 1 depth -= 1
if gPretty: if pretty:
echo spaces(depth) & ")" echo spaces(depth) & ")"
else: else:
stdout.write ")" stdout.write ")"
@ -54,7 +52,7 @@ proc printLisp(root: TSNode, data: var string) =
if node == root: if node == root:
break break
proc process(path: string, mode="") = proc process(path: string, mode="cpp", pretty = true) =
if not existsFile(path): if not existsFile(path):
echo "Invalid path " & path echo "Invalid path " & path
return return
@ -68,7 +66,7 @@ proc process(path: string, mode="") =
defer: defer:
parser.tsParserDelete() parser.tsParserDelete()
if mode.len() != 0: if mode.len != 0:
pmode = mode pmode = mode
elif ext in [".h", ".c"]: elif ext in [".h", ".c"]:
pmode = "c" pmode = "c"
@ -91,23 +89,29 @@ proc process(path: string, mode="") =
quit() quit()
var var
tree = parser.tsParserParseString(nil, data.cstring, data.len().uint32) tree = parser.tsParserParseString(nil, data.cstring, data.len.uint32)
root = tree.tsTreeRootNode() root = tree.tsTreeRootNode()
defer: defer:
tree.tsTreeDelete() tree.tsTreeDelete()
printLisp(root, data) printLisp(root, data, pretty)
proc parseCli() = proc parseCli() =
let params = commandLineParams() var
mode = "cpp"
params = commandLineParams()
pretty = true
for param in params: for param in params:
if param in ["-h", "--help", "-?", "/?", "/h"]: if param in ["-h", "--help", "-?", "/?", "/h"]:
echo HELP echo HELP
quit() quit()
elif param == "-u": elif param == "-c":
gPretty = false mode = "c"
elif param == "-m":
pretty = false
else: else:
process(param) process(param, mode, pretty)
parseCli() parseCli()