diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2019-01-18 21:52:29 -0600 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2019-01-18 21:52:29 -0600 |
| commit | cd8a263f85a4ade35ec59bbe8360ece880f681ce (patch) | |
| tree | d72f103b0edae320c7782d0491078339771abee2 | |
| parent | 287980c9edbb1f037b1827b62ca8cc3453b2203a (diff) | |
| download | nimterop-recurexpr.tar.gz nimterop-recurexpr.zip | |
Recursive node support, enum expressions, or/and/notrecurexpr
| -rw-r--r-- | nimterop/ast.nim | 29 | ||||
| -rw-r--r-- | nimterop/getters.nim | 15 | ||||
| -rw-r--r-- | nimterop/globals.nim | 26 | ||||
| -rw-r--r-- | nimterop/grammar.nim | 25 | ||||
| -rw-r--r-- | nimterop/lisp.nim | 8 | ||||
| -rw-r--r-- | tests/include/test.h | 6 | ||||
| -rw-r--r-- | tests/tnimterop_c.nim | 4 |
7 files changed, 75 insertions, 38 deletions
diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 6981deb..6498c93 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -4,18 +4,6 @@ import regex import "."/[getters, globals, grammar, treesitter/runtime] -const gAtoms = @[ - "field_identifier", - "identifier", - "shift_expression", - "math_expression", - "number_literal", - "preproc_arg", - "primitive_type", - "sized_type_specifier", - "type_identifier" -].toSet() - proc saveNodeData(node: TSNode): bool = let name = $node.tsNodeType() if name in gAtoms: @@ -25,10 +13,10 @@ proc saveNodeData(node: TSNode): bool = if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier": return true - if name == "number_literal" and $node.tsNodeParent.tsNodeType() in ["shift_expression", "math_expression"]: + if name == "number_literal" and $node.tsNodeParent.tsNodeType() in gExpressions: return true - if name in ["math_expression", "primitive_type", "sized_type_specifier"]: + if name in ["primitive_type", "sized_type_specifier"]: val = val.getType() let @@ -52,6 +40,10 @@ proc saveNodeData(node: TSNode): bool = ppname == "function_declarator": gStateRT.data.add(("function_declarator", "")) + elif name in gExpressions: + if $node.tsNodeParent.tsNodeType() notin gExpressions: + gStateRT.data.add((name, node.getNodeVal())) + elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: gStateRT.data.add((name.replace("abstract_", ""), "")) @@ -65,14 +57,19 @@ proc searchAstForNode(ast: ref Ast, node: TSNode): bool = return if ast.children.len != 0: - if childNames.contains(ast.regex): + if childNames.contains(ast.regex) or + (childNames.len == 0 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 = ast.getAstChildByName($nodeChild.tsNodeType()) + astChild = + if not ast.recursive: + ast.getAstChildByName($nodeChild.tsNodeType()) + else: + ast if not searchAstForNode(astChild, nodeChild): flag = false break diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 59dbb15..1b39247 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -236,12 +236,16 @@ converter toKind*(kind: string): Kind = else: exactlyOne -proc getNameKind*(name: string): tuple[name: string, kind: Kind] = - result.name = name +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 = name[0 .. ^2] + result.name = result.name[0 .. ^2] proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = if node.tsNodeNamedChildCount() != 0: @@ -261,8 +265,9 @@ proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = proc getRegexForAstChildren*(ast: ref Ast): string = result = "^" for i in 0 .. ast.children.len-1: - let kind: string = ast.children[i].kind - let begin = if result[^1] == '|': "" else: "(?:" + let + kind: string = ast.children[i].kind + begin = if result[^1] == '|': "" else: "(?:" case kind: of "!": result &= &"{begin}{ast.children[i].name}|" diff --git a/nimterop/globals.nim b/nimterop/globals.nim index ed69ff5..0c81e27 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,10 +1,33 @@ -import sets, tables +import sequtils, sets, tables import regex when not declared(CIMPORT): import "."/treesitter/runtime +const + gAtoms* = @[ + "field_identifier", + "identifier", + "number_literal", + "preproc_arg", + "primitive_type", + "sized_type_specifier", + "type_identifier" + ].toSet() + + gExpressions* = @[ + "parenthesized_expression", + "bitwise_expression", + "shift_expression", + "math_expression" + ].toSet() + + gEnumVals* = @[ + "identifier", + "number_literal" + ].concat(toSeq(gExpressions.items)) + type Kind* = enum exactlyOne @@ -16,6 +39,7 @@ type Ast* = object name*: string kind*: Kind + recursive*: bool children*: seq[ref Ast] when not declared(CIMPORT): tonim*: proc (ast: ref Ast, node: TSNode) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index ae46404..ee42825 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -325,14 +325,15 @@ proc initGrammar() = if gStateRT.consts.addNewIdentifer(fname): if i+1 < gStateRT.data.len-fend and - gStateRT.data[i+1].name in ["identifier", "shift_expression", "math_expression", "number_literal"]: - if " " in gStateRT.data[i+1].val: - gStateRT.data[i+1].val = "(" & gStateRT.data[i+1].val.replace(" ", "") & ")" + gStateRT.data[i+1].name in gEnumVals: gStateRT.data[i+1].val = gStateRT.data[i+1].val.multiReplace([ - ("<<", " shl "), (">>", " shr ") + (" ", ""), + ("<<", " shl "), (">>", " shr "), + ("^", " xor "), ("&", " and "), ("|", " or "), + ("~", " not ") ]) - gStateRT.constStr &= &" {fname}* = {gStateRT.data[i+1].val}.{nname}\n" + gStateRT.constStr &= &" {fname}* = ({gStateRT.data[i+1].val}).{nname}\n" try: count = gStateRT.data[i+1].val.parseInt() + 1 except: @@ -349,15 +350,12 @@ proc initGrammar() = (type_identifier?) (enumerator_list (enumerator+ - (identifier+) - (number_literal?) - (shift_expression|math_expression? - (number_literal+) - ) + (identifier?) + (^$1+) ) ) ) - """, + """ % gEnumVals.join("|"), proc (ast: ref Ast, node: TSNode) = var name = "" @@ -439,8 +437,9 @@ proc initGrammar() = proc initRegex(ast: ref Ast) = if ast.children.len != 0: - for child in ast.children: - child.initRegex() + if not ast.recursive: + for child in ast.children: + child.initRegex() var reg: string diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 3d3c34e..c21c3be 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -34,8 +34,10 @@ proc readFromTokens(): ref Ast = quit(1) if gTokens[idx+1] != "comment": result = new(Ast) - (result.name, result.kind) = gTokens[idx+1].getNameKind() + (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() @@ -48,9 +50,9 @@ proc readFromTokens(): ref Ast = idx += 1 proc printAst*(node: ref Ast, offset=""): string = - result = offset & "(" & node.name & node.kind.toString() + result = offset & "(" & (if node.recursive: "^" else: "") & node.name & node.kind.toString() - if node.children.len != 0: + if node.children.len != 0 and not node.recursive: result &= "\n" for child in node.children: result &= printAst(child, offset & " ") diff --git a/tests/include/test.h b/tests/include/test.h index 8a8c579..64bdbb2 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -60,6 +60,12 @@ typedef enum ENUM4 { enum12 } ENUM4; +enum ENUM5 { + enum13 = (1 << 2), + enum14 = ((1 << 3) | 1), + enum15 = (1 << (1 & 1)) +}; + typedef void * VOIDPTR; typedef int * INTPTR; diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 0f53556..86526c1 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -97,6 +97,10 @@ else: check e3 == enum7 check e4 == enum11 +check enum13 == 4 +check enum14 == 9 +check enum15 == 2 + cAddStdDir() ## failing tests |
