ast2 newTypeIdent cleanup, pragma tests, docs.nim docs

This commit is contained in:
Ganesh Viswanathan 2020-03-25 15:17:20 -05:00
commit 8b9c39f42e
6 changed files with 154 additions and 41 deletions

View file

@ -37,6 +37,7 @@ task test, "Test":
buildToastTask() buildToastTask()
execTest "tests/tast2.nim" execTest "tests/tast2.nim"
#execCmd "nim c -f -d:HEADER -r tests/tast2.nim"
execTest "tests/tnimterop_c.nim" execTest "tests/tnimterop_c.nim"
execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" execCmd "nim cpp -f -r tests/tnimterop_cpp.nim"

View file

@ -4,4 +4,4 @@ Module that should import everything so that `nim doc --project nimtero/all` run
# TODO: make sure it does import everything. # TODO: make sure it does import everything.
import "."/[cimport, build, types, plugin] import "."/[docs, cimport, build, types, plugin]

View file

@ -248,12 +248,13 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: seq[
result.add ident result.add ident
result.add nimState.newPragma(node, pragmas) result.add nimState.newPragma(node, pragmas)
proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", pragmas: seq[string] = @[]): PNode = proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pragmas: seq[string] = @[]): PNode =
# Create nkTypeDef PNode with first ident # Create nkTypeDef PNode with first ident if `nskType` else just create an nkPostfix node for `nskProc`
# #
# If `fname`, use it instead of node.getAtom() for name # If `fname`, use it instead of node.getAtom() for name
# If `pragmas`, add as nkPragmaExpr but only if `nskType` since procs add pragmas elsewhere
let let
(tname, origname, info) = nimState.getNameInfo(node.getAtom(), nskType) (tname, origname, info) = nimState.getNameInfo(node.getAtom(), kind)
name = name =
if fname.nBl: if fname.nBl:
@ -262,32 +263,49 @@ proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", pragmas: seq[str
tname tname
ident = nimState.getIdent(name, info) ident = nimState.getIdent(name, info)
prident =
if pragmas.nBl and not ident.isNil:
nimState.newPragmaExpr(node, ident, pragmas)
else:
ident
if name.Bl: if name.Bl:
# Name skipped or overridden since blank # Name skipped or overridden since blank
result = nimState.getOverrideOrSkip(node, origname, nskType) result = nimState.getOverrideOrSkip(node, origname, kind)
elif nimState.addNewIdentifer(name): elif nimState.addNewIdentifer(name):
# type name* = if kind == nskType:
# # type name* =
# nkTypeDef( #
# nkPostfix( # nkTypeDef(
# nkIdent("*"), # nkPostfix(
# nkIdent(name) # nkIdent("*"),
# ), # nkIdent(name)
# nkEmpty() # ),
# ) # nkEmpty()
result = newNode(nkTypeDef) # )
result.add prident let
result.add newNode(nkEmpty) pragmas =
if nimState.includeHeader and tname == origname:
# Need to add impShort
pragmas & nimState.impShort
else:
pragmas
prident =
if pragmas.nBl and not ident.isNil:
nimState.newPragmaExpr(node, ident, pragmas)
else:
ident
result = newNode(nkTypeDef)
result.add prident
result.add newNode(nkEmpty)
elif kind == nskProc:
# name*
#
# nkPostfix(
# nkIdent("*"),
# nkIdent(name)
# )
result = ident
nimState.identifierNodes[name] = result nimState.identifierNodes[name] = result
else: else:
necho &"# type '{origname}' is duplicate, skipped" necho &"# $1 '{origname}' is duplicate, skipped" % getKeyword(kind)
proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode =
# Create nkPtrTy tree depending on count # Create nkPtrTy tree depending on count
@ -520,9 +538,11 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname
else: else:
@["bycopy"] @["bycopy"]
typeDefExisting = not typeDef.isNil
typeDef = typeDef =
if typeDef.isNil: if typeDef.isNil:
nimState.newTypeIdent(node, fname, pragmas) nimState.newTypeIdent(node, fname = fname, pragmas = pragmas)
else: else:
typeDef typeDef
@ -558,10 +578,14 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname
typeDef.add obj typeDef.add obj
# If typeDef was passed in, need to add pragmas if any # If typeDef was passed in, need to add pragmas if any
if pragmas.nBl and typeDef[0].kind != nkPragmaExpr: if pragmas.nBl and typeDefExisting:
let if typeDef[0].kind != nkPragmaExpr:
npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas) # includeHeader already added impShort
typedef[0] = npexpr let
npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas)
typedef[0] = npexpr
else:
nimState.addPragma(node, typeDef[0][1], pragmas)
# nkTypeSection.add # nkTypeSection.add
nimState.typeSection.add typeDef nimState.typeSection.add typeDef
@ -1112,13 +1136,12 @@ proc addProc(nimState: NimState, node: TSNode) =
for i in start+1 ..< node.len: for i in start+1 ..< node.len:
let let
# node[i] = identifier = name # node[i] = identifier = name
tident = nimState.newTypeIdent(node[i]) ident = nimState.newTypeIdent(node[i], kind = nskProc)
if not tident.isNil: if not ident.isNil:
let let
# Only need the ident tree, not nkTypeDef parent # Only need the ident tree, not nkTypeDef parent
ident = tident[0] name = ident.getIdentName()
name = tident.getIdentName()
# node[i] could have nested pointers # node[i] could have nested pointers
tcount = node[i].getPtrCount() tcount = node[i].getPtrCount()
@ -1258,7 +1281,7 @@ proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) =
nimState.constSection.add nimState.newConstDef( nimState.constSection.add nimState.newConstDef(
root, fname = nimState.currentHeader, fval = '"' & fullpath & '"') root, fname = nimState.currentHeader, fval = '"' & fullpath & '"')
nimState.addPragma(root, impPragma, "header", newStrNode(nkStrLit, nimState.currentHeader)) nimState.addPragma(root, impPragma, "header", nimState.getIdent(nimState.currentHeader))
nimState.addPragma(root, impCPragma, "pragma", nimState.getIdent(nimState.impShort & "C")) nimState.addPragma(root, impCPragma, "pragma", nimState.getIdent(nimState.impShort & "C"))
nimState.addPragma(root, impCPragma, nimState.impShort) nimState.addPragma(root, impCPragma, nimState.impShort)
@ -1312,9 +1335,9 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) =
var var
tree = newNode(nkStmtList) tree = newNode(nkStmtList)
tree.add nimState.pragmaSection
tree.add nimState.enumSection tree.add nimState.enumSection
tree.add nimState.constSection tree.add nimState.constSection
tree.add nimState.pragmaSection
tree.add nimState.typeSection tree.add nimState.typeSection
tree.add nimState.procSection tree.add nimState.procSection

View file

@ -1,6 +1,10 @@
import macros, strformat import macros, strformat
from os import parentDir, getCurrentCompilerExe, DirSep from os import parentDir, getCurrentCompilerExe, DirSep
when defined(nimdoc):
from os import getCurrentDir, paramCount, paramStr
proc getNimRootDir(): string = proc getNimRootDir(): string =
#[ #[
hack, but works hack, but works

View file

@ -11,7 +11,7 @@ typedef struct A3 {};
typedef struct A4 A4, *A4p; typedef struct A4 A4, *A4p;
typedef const int A5; typedef const int A5;
typedef int *A6; typedef int *A6;
typedef A0 **A7; typedef struct A0 **A7;
typedef void *A8; typedef void *A8;
// Forward declaration // Forward declaration
@ -104,6 +104,8 @@ typedef enum VSPresetFormat {
// DUPLICATES // DUPLICATES
#ifndef HEADER
#define A 1 #define A 1
#define B 1.0 #define B 1.0
#define C 0x10 #define C 0x10
@ -117,7 +119,7 @@ typedef struct A3 {};
typedef struct A4 A4, *A4p; typedef struct A4 A4, *A4p;
typedef const int A5; typedef const int A5;
typedef int *A6; typedef int *A6;
typedef A0 **A7; typedef struct A0 **A7;
typedef void *A8; typedef void *A8;
// Forward declaration // Forward declaration
@ -131,7 +133,7 @@ typedef char *(*A11)[3];
typedef struct A1 *A111[12]; typedef struct A1 *A111[12];
typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int));
typedef int A13(int, int); typedef int A13(int, int, void (*func)(void));
struct A14 { volatile char a1; }; struct A14 { volatile char a1; };
struct A15 { char *a1; const int *a2[1]; }; struct A15 { char *a1; const int *a2[1]; };
@ -200,4 +202,6 @@ typedef enum VSPresetFormat {
// Anonymous // Anonymous
//typedef struct { char a1; }; //typedef struct { char a1; };
//struct A2 test_proc1(struct A0 a); //struct A2 test_proc1(struct A0 a);
#endif

View file

@ -1,4 +1,4 @@
import tables import macros, sets, tables
import nimterop/[cimport] import nimterop/[cimport]
@ -12,7 +12,36 @@ cOverride:
type type
A1* = A0 A1* = A0
cImport("include/tast2.h", flags="-d -f:ast2 -ENK_") when defined(HEADER):
cDefine("HEADER")
const
flags = " -H"
imp = @["importc", "header:headertast2"]
else:
const
flags = ""
imp = @[]
cImport("include/tast2.h", flags="-d -f:ast2 -ENK_" & flags)
proc getPragmas(n: NimNode): HashSet[string] =
for i in 0 ..< n.len:
if n[i].kind == nnkPragma:
for j in 0 ..< n[i].len:
if n[i][j].kind == nnkIdent:
result.incl $n[i][j]
elif n[i][j].kind == nnkExprColonExpr:
result.incl $n[i][j][0] & ":" & $n[i][j][1]
else:
result.incl n[i].getPragmas()
macro checkPragmas(t: typed, pragmas: static[seq[string]]): untyped =
let
ast = t.getImpl()
prag = ast.getPragmas()
exprag = pragmas.toHashSet()
doAssert symmetricDifference(prag, exprag).len == 0,
"\nWrong number of pragmas in " & $t & "\n" & $prag & " vs " & $exprag
proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) = proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) =
var var
@ -31,62 +60,114 @@ assert C == 0x10
assert D == "hello" assert D == "hello"
assert E == 'c' assert E == 'c'
const
pragmas = @["bycopy"] & imp
assert A0 is object assert A0 is object
testFields(A0, {"f1": "cint"}.toTable()) testFields(A0, {"f1": "cint"}.toTable())
checkPragmas(A0, pragmas)
assert A1 is A0 assert A1 is A0
testFields(A1, {"f1": "cint"}.toTable()) testFields(A1, {"f1": "cint"}.toTable())
assert A2 is object assert A2 is object
testFields(A2) testFields(A2)
checkPragmas(A2, pragmas)
assert A3 is object assert A3 is object
testFields(A3) testFields(A3)
checkPragmas(A3, pragmas)
assert A4 is object assert A4 is object
testFields(A4) testFields(A4)
checkPragmas(A4, pragmas)
assert A4p is ptr A4 assert A4p is ptr A4
checkPragmas(A4p, imp)
assert A5 is cint assert A5 is cint
checkPragmas(A5, imp)
assert A6 is ptr cint assert A6 is ptr cint
checkPragmas(A6, imp)
assert A7 is ptr ptr A0 assert A7 is ptr ptr A0
checkPragmas(A7, imp)
assert A8 is pointer assert A8 is pointer
checkPragmas(A8, imp)
assert A9p is array[3, cstring] assert A9p is array[3, cstring]
checkPragmas(A9p, imp)
#assert A9 is array[4, cchar] #assert A9 is array[4, cchar]
#checkPragmas(A9, imp)
assert A10 is array[3, array[6, cstring]] assert A10 is array[3, array[6, cstring]]
checkPragmas(A10, imp)
assert A11 is ptr array[3, cstring] assert A11 is ptr array[3, cstring]
checkPragmas(A11, imp)
assert A111 is array[12, ptr A1] assert A111 is array[12, ptr A1]
checkPragmas(A111, imp)
assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint
checkPragmas(A12, imp)
assert A13 is proc(a1: cint, a2: cint, `func`: proc()): cint assert A13 is proc(a1: cint, a2: cint, `func`: proc()): cint
checkPragmas(A13, imp)
assert A14 is object assert A14 is object
testFields(A14, {"a1": "cchar"}.toTable()) testFields(A14, {"a1": "cchar"}.toTable())
checkPragmas(A14, pragmas)
assert A15 is object assert A15 is object
testFields(A15, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) testFields(A15, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable())
checkPragmas(A15, pragmas)
assert A16 is object assert A16 is object
testFields(A16, {"f1": "cchar"}.toTable()) testFields(A16, {"f1": "cchar"}.toTable())
checkPragmas(A16, pragmas)
assert A17 is object assert A17 is object
testFields(A17, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) testFields(A17, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable())
checkPragmas(A17, pragmas)
assert A18 is A17 assert A18 is A17
checkPragmas(A18, imp)
assert A18p is ptr A17 assert A18p is ptr A17
checkPragmas(A18p, imp)
assert A19 is object assert A19 is object
testFields(A19, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) testFields(A19, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable())
checkPragmas(A19, pragmas)
assert A19p is ptr A19 assert A19p is ptr A19
checkPragmas(A19p, imp)
assert A20 is object assert A20 is object
testFields(A20, {"a1": "cchar"}.toTable()) testFields(A20, {"a1": "cchar"}.toTable())
checkPragmas(A20, pragmas)
assert A21 is A20 assert A21 is A20
checkPragmas(A21, imp)
assert A21p is ptr A20 assert A21p is ptr A20
checkPragmas(A21p, imp)
assert A22 is object assert A22 is object
testFields(A22, {"f1": "ptr ptr cint", "f2": "array[0..254, ptr cint]"}.toTable()) testFields(A22, {"f1": "ptr ptr cint", "f2": "array[0..254, ptr cint]"}.toTable())
checkPragmas(A22, pragmas)
assert U1 is object assert U1 is object
assert sizeof(U1) == sizeof(cfloat) assert sizeof(U1) == sizeof(cfloat)
checkPragmas(U1, pragmas & @["union"])
assert U2 is object assert U2 is object
assert sizeof(U2) == 256 * sizeof(cint) assert sizeof(U2) == 256 * sizeof(cint)
checkPragmas(U2, pragmas & @["union"])
assert PANEL_WINDOW == 1 assert PANEL_WINDOW == 1
assert PANEL_GROUP == 2 assert PANEL_GROUP == 2