diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 4a9b048..dff355e 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -951,10 +951,10 @@ proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNo # type name[X] => array[X, type] let # Size of array could be a Nim expression - size = gState.parseCExpression(gState.getNodeVal(cnode[1])) - if size.kind != nkNone: - result = gState.newArrayTree(cnode, result, size) - cnode = cnode[0] + size = gState.parseCExpression(gState.getNodeVal(cnode[1]), skipIdentValidation = true) + + result = gState.newArrayTree(cnode, result, size) + cnode = cnode[0] elif cnode.len == 1: # type name[] = UncheckedArray[type] result = gState.newArrayTree(cnode, result) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index b0c34c1..b089fd2 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -45,14 +45,14 @@ proc getExprIdent*(gState: State, identName: string, kind = nskConst, parent = " ## ## Returns PNode(nkNone) if the identifier is blank result = newNode(nkNone) - if identName notin gState.skippedSyms: + if gState.skipIdentValidation or identName notin gState.skippedSyms: var ident = identName if ident != "_": # Process the identifier through cPlugin ident = gState.getIdentifier(ident, kind, parent) if kind == nskType: result = gState.getIdent(ident) - elif ident.nBl and ident in gState.constIdentifiers: + elif gState.skipIdentValidation or ident.nBl and ident in gState.constIdentifiers: if gState.currentTyCastName.nBl: ident = ident & "." & gState.currentTyCastName result = gState.getIdent(ident) @@ -591,7 +591,7 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = decho "NODE RESULT: ", result -proc parseCExpression*(gState: State, codeRoot: TSNode, name = ""): PNode = +proc parseCExpression*(gState: State, codeRoot: TSNode): PNode = ## Parse a c expression from a root ts node # This var is used for keeping track of the type of the first @@ -607,14 +607,16 @@ proc parseCExpression*(gState: State, codeRoot: TSNode, name = ""): PNode = decho "UNEXPECTED EXCEPTION: ", e.msg result = newNode(nkNone) -proc parseCExpression*(gState: State, code: string, name = ""): PNode = +proc parseCExpression*(gState: State, code: string, name = "", skipIdentValidation = false): PNode = ## Convert the C string to a nim PNode tree gState.currentExpr = code gState.currentTyCastName = name + gState.skipIdentValidation = skipIdentValidation withCodeAst(gState.currentExpr, gState.mode): - result = gState.parseCExpression(root, name) + result = gState.parseCExpression(root) # Clear the state gState.currentExpr = "" - gState.currentTyCastName = "" \ No newline at end of file + gState.currentTyCastName = "" + gState.skipIdentValidation = false \ No newline at end of file diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 46203ea..05284a9 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -114,6 +114,9 @@ type # 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 diff --git a/nimterop/toast.nim b/nimterop/toast.nim index b1f910c..f54aa67 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -4,6 +4,8 @@ import "."/treesitter/[api, c, cpp] import "."/[ast, ast2, build, globals, getters, grammar, tshelp] +{.passC: "-DNIMTEROP".} + proc process(gState: State, path: string, astTable: AstTable) = doAssert existsFile(path), &"Invalid path {path}" diff --git a/tests/include/tast2.h b/tests/include/tast2.h index bbb3315..b8433f9 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -42,13 +42,29 @@ extern "C" { #define REG_STR "regular string" #define NOTSUPPORTEDSTR "not a " REG_STR -#define NULLCHAR '\0'/* comments should not break things*/ -#define OCTCHAR '\012' // nor should this comment +#define NULLCHAR '\0' +#define OCTCHAR '\012' #define HEXCHAR '\xFE' #define TRICKYSTR "\x4E\034\nfoo\0\'\"\r\v\a\b\e\f\t\\\?bar" #define ALLSHL (SHL1 | SHL2 | SHL3) +#ifdef NIMTEROP +#define SOME_CONST 8 +#endif + +struct some_struct_s +{ + int x; +}; + +struct parent_struct_s +{ + struct some_struct_s s[SOME_CONST]; +}; + +typedef struct some_struct_s SOME_ARRAY[SOME_CONST]; + struct A0; struct A1 {}; typedef struct A2; diff --git a/tests/tast2.nim b/tests/tast2.nim index 4fd16cc..8deb99e 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -35,6 +35,7 @@ cOverride: type A1* = A0 +cDefine("SOME_CONST=100") cImport(path, flags="-f:ast2 -ENK_,SDL_ -GVICE=SLICE -TMyInt=cint" & flags) proc getPragmas(n: NimNode): HashSet[string] = @@ -155,6 +156,9 @@ assert typeof(POINTERPOINTERPOINTEREXPR) is (ptr ptr ptr cint) assert ALLSHL == (SHL1 or SHL2 or SHL3) +assert typeof(parent_struct_s().s) is array[100, some_struct_s] +assert typeof(SOME_ARRAY) is array[100, some_struct_s] + assert A0 is object testFields(A0, "f1!cint") checkPragmas(A0, pHeaderBy, istype = false)