diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2019-01-28 00:30:59 -0600 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2019-01-28 00:30:59 -0600 |
| commit | 70aa3e2b5e47102a7e9bdbb76320d8c6ccad57b9 (patch) | |
| tree | f84681e64fc6a70050be32a8a1e1497fe7c3a2b4 | |
| parent | ef0a250066a336ef0bd372ed3045c8170a00dd35 (diff) | |
| download | nimterop-70aa3e2b5e47102a7e9bdbb76320d8c6ccad57b9.tar.gz nimterop-70aa3e2b5e47102a7e9bdbb76320d8c6ccad57b9.zip | |
Fix #42 - duplicate stylistic identifiers
| -rw-r--r-- | nimterop/ast.nim | 80 | ||||
| -rw-r--r-- | nimterop/getters.nim | 21 | ||||
| -rw-r--r-- | nimterop/globals.nim | 22 | ||||
| -rw-r--r-- | nimterop/grammar.nim | 268 | ||||
| -rw-r--r-- | toast.nim | 11 |
5 files changed, 204 insertions, 198 deletions
diff --git a/nimterop/ast.nim b/nimterop/ast.nim index c5810b3..b719d5f 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -4,7 +4,7 @@ import regex import "."/[getters, globals, grammar, treesitter/runtime] -proc saveNodeData(node: TSNode): bool = +proc saveNodeData(node: TSNode, nimState: NimState): bool = let name = $node.tsNodeType() if name in gAtoms: var @@ -27,32 +27,32 @@ proc saveNodeData(node: TSNode): bool = if node.tsNodePrevNamedSibling().tsNodeIsNull(): if pname == "pointer_declarator": if ppname notin ["function_declarator", "array_declarator"]: - gStateRT.data.add(("pointer_declarator", "")) + nimState.data.add(("pointer_declarator", "")) elif ppname == "array_declarator": - gStateRT.data.add(("array_pointer_declarator", "")) + nimState.data.add(("array_pointer_declarator", "")) elif pname in ["function_declarator", "array_declarator"]: if ppname == "pointer_declarator": - gStateRT.data.add(("pointer_declarator", "")) + nimState.data.add(("pointer_declarator", "")) - gStateRT.data.add((name, val)) + nimState.data.add((name, val)) if node.tsNodeType() == "field_identifier" and pname == "pointer_declarator" and ppname == "function_declarator": if pppname == "pointer_declarator": - gStateRT.data.insert(("pointer_declarator", ""), gStateRT.data.len-1) - gStateRT.data.add(("function_declarator", "")) + nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) + nimState.data.add(("function_declarator", "")) elif name in gExpressions: if $node.tsNodeParent.tsNodeType() notin gExpressions: - gStateRT.data.add((name, node.getNodeVal())) + nimState.data.add((name, node.getNodeVal())) elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: - gStateRT.data.add((name.replace("abstract_", ""), "")) + nimState.data.add((name.replace("abstract_", ""), "")) return true -proc searchAstForNode(ast: ref Ast, node: TSNode): bool = +proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = let childNames = node.getTSNodeNamedChildNames().join() @@ -73,18 +73,18 @@ proc searchAstForNode(ast: ref Ast, node: TSNode): bool = ast.getAstChildByName($nodeChild.tsNodeType()) else: ast - if not searchAstForNode(astChild, nodeChild): + if not searchAstForNode(astChild, nodeChild, nimState): flag = false break if flag: - return node.saveNodeData() + return node.saveNodeData(nimState) else: - return node.saveNodeData() + return node.saveNodeData(nimState) elif node.getTSNodeNamedChildCountSansComments() == 0: - return node.saveNodeData() + return node.saveNodeData(nimState) -proc searchAst(root: TSNode) = +proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = var node = root nextnode: TSNode @@ -94,18 +94,18 @@ proc searchAst(root: TSNode) = if not node.tsNodeIsNull() and depth > -1: let name = $node.tsNodeType() - if name in gStateRT.ast: - for ast in gStateRT.ast[name]: - if searchAstForNode(ast, node): - ast.tonim(ast, node) + if name in astTable: + for ast in astTable[name]: + if searchAstForNode(ast, node, nimState): + ast.tonim(ast, node, nimState) if gStateRT.debug: - gStateRT.debugStr &= "\n\n# " & gStateRT.data.join("\n# ") + nimState.debugStr &= "\n\n# " & nimState.data.join("\n# ") break - gStateRT.data = @[] + nimState.data = @[] else: break - if $node.tsNodeType() notin gStateRT.ast and node.tsNodeNamedChildCount() != 0: + if $node.tsNodeType() notin astTable and node.tsNodeNamedChildCount() != 0: nextnode = node.tsNodeNamedChild(0) depth += 1 else: @@ -128,28 +128,30 @@ proc searchAst(root: TSNode) = if node == root: break -proc printNim*(fullpath: string, root: TSNode) = - parseGrammar() - +proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = echo "{.experimental: \"codeReordering\".}" - var fp = fullpath.replace("\\", "/") - gStateRT.currentHeader = getCurrentHeader(fullpath) - gStateRT.constStr &= &" {gStateRT.currentHeader} = \"{fp}\"\n" + var + nimState = new(NimState) + fp = fullpath.replace("\\", "/") + nimState.identifiers = newTable[string, string]() + + nimState.currentHeader = getCurrentHeader(fullpath) + nimState.constStr &= &" {nimState.currentHeader} = \"{fp}\"\n" - root.searchAst() + root.searchAst(astTable, nimState) - if gStateRT.enumStr.nBl: - echo gStateRT.enumStr + if nimState.enumStr.nBl: + echo nimState.enumStr - if gStateRT.constStr.nBl: - echo "const\n" & gStateRT.constStr + if nimState.constStr.nBl: + echo "const\n" & nimState.constStr - if gStateRT.typeStr.nBl: - echo "type\n" & gStateRT.typeStr + if nimState.typeStr.nBl: + echo "type\n" & nimState.typeStr - if gStateRT.procStr.nBl: - echo gStateRT.procStr + if nimState.procStr.nBl: + echo nimState.procStr - if gStateRT.debug and gStateRT.debugStr.nBl: - echo gStateRT.debugStr
\ No newline at end of file + if gStateRT.debug and nimState.debugStr.nBl: + echo nimState.debugStr
\ No newline at end of file diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 6e3b31a..f430ae1 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -103,15 +103,15 @@ proc getIdentifier*(str: string, kind: NimSymKind): string = checkUnderscores(result, &"Identifier '{str}' still contains leading/trailing underscores '_' after 'cPlugin:onSymbol()': result '{result}'") else: result = str - checkUnderscores(result, &"Identifier '{result}' contains unsupported leading/trailing underscores '_': use 'cPlugin:onSymbol()' to handle") + checkUnderscores(result, &"Identifier '{result}' contains unsupported leading/trailing underscores '_': use 'cPlugin:onSymbol()' to remove") if result in gReserved: result = &"`{result}`" -proc getUniqueIdentifier*(existing: HashSet[string], prefix = ""): string = +proc getUniqueIdentifier*(existing: TableRef[string, string], prefix = ""): string = var name = prefix & "_" & gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) - nimName = name.replace("_", "").toLowerAscii + nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii count = 1 while (nimName & $count) in existing: @@ -119,16 +119,17 @@ proc getUniqueIdentifier*(existing: HashSet[string], prefix = ""): string = return name & $count -proc addNewIdentifer*(existing: var HashSet[string], name: string): bool = +proc addNewIdentifer*(existing: var TableRef[string, string], name: string): bool = if name notin gStateRT.symOverride: let - nimName = - if existing == gStateRT.types: - name[0] & name[1 .. ^1].replace("_", "").toLowerAscii - else: - name.replace("_", "").toLowerAscii + nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii - return not existing.containsOrIncl(nimName) + if existing.hasKey(nimName): + doAssert name == existing[nimName], &"Identifier '{name}' is a stylistic duplicate of identifier '{existing[nimName]}', use 'cPlugin:onSymbol()' to rename" + result = false + else: + existing[nimName] = name + result = true proc getPtrType*(str: string): string = result = case str: diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 86dc819..cfbefdb 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -44,24 +44,28 @@ type recursive*: bool children*: seq[ref Ast] when not declared(CIMPORT): - tonim*: proc (ast: ref Ast, node: TSNode) + tonim*: proc (ast: ref Ast, node: TSNode, nimState: NimState) regex*: Regex + AstTable = TableRef[string, seq[ref Ast]] + State = object compile*, defines*, headers*, includeDirs*, searchDirs*, symOverride*: seq[string] nocache*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool - consts*, enums*, procs*, types*: HashSet[string] + code*, mode*, pluginSourcePath*, sourceFile*: string + + onSymbol*: OnSymbol + + NimState = ref object + identifiers*: TableRef[string, string] + constStr*, debugStr*, enumStr*, procStr*, typeStr*: string - code*, currentHeader*, mode*, pluginSourcePath*, sourceFile*: string - ast*: Table[string, seq[ref Ast]] - data*: seq[tuple[name, val: string]] - when not declared(CIMPORT): - grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.nimcall.}]] + currentHeader*: string - onSymbol*: OnSymbol + data*: seq[tuple[name, val: string]] var gStateCT {.compiletime, used.}: State @@ -78,4 +82,4 @@ type CompileMode = enum const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant when not declared(CIMPORT): - export gAtoms, gExpressions, gEnumVals, Kind, Ast, State, gStateRT, nBl, CompileMode, modeDefault
\ No newline at end of file + export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, gStateRT, nBl, CompileMode, modeDefault
\ No newline at end of file diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 3859c4e..bfc9998 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -4,21 +4,24 @@ import regex import "."/[getters, globals, lisp, treesitter/runtime] -proc initGrammar() = +type + Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, nimState: NimState) {.nimcall.}]] + +proc initGrammar(): Grammar = # #define X Y - gStateRT.grammar.add((""" + result.add((""" (preproc_def (identifier) (preproc_arg) ) """, - proc (ast: ref Ast, node: TSNode) = + proc (ast: ref Ast, node: TSNode, nimState: NimState) = let - name = gStateRT.data[0].val.getIdentifier(nskConst) - val = gStateRT.data[1].val.getLit() + name = nimState.data[0].val.getIdentifier(nskConst) + val = nimState.data[1].val.getLit() - if name.nBl and val.nBl and gStateRT.consts.addNewIdentifer(name): - gStateRT.constStr &= &" {name}* = {val}\n" + if name.nBl and val.nBl and nimState.identifiers.addNewIdentifer(name): + nimState.constStr &= &" {name}* = {val}\n" )) let @@ -67,18 +70,18 @@ proc initGrammar() = """ template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i: untyped): untyped = - ptyp = gStateRT.data[i].val.getIdentifier(nskType) - doAssert ptyp.nBl, &"Blank param type for '{fname}', originally '{gStateRT.data[i].val}'" + ptyp = nimState.data[i].val.getIdentifier(nskType) + doAssert ptyp.nBl, &"Blank param type for '{fname}', originally '{nimState.data[i].val}'" - if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "pointer_declarator": + if i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": pptr = "ptr " i += 1 else: pptr = "" - if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "identifier": - pname = gStateRT.data[i+1].val.getIdentifier(nskParam) - doAssert pname.nBl, &"Blank param name for '{fname}', originally '{gStateRT.data[i+1].val}'" + if i+1 < nimState.data.len and nimState.data[i+1].name == "identifier": + pname = nimState.data[i+1].val.getIdentifier(nskParam) + doAssert pname.nBl, &"Blank param name for '{fname}', originally '{nimState.data[i+1].val}'" i += 2 else: pname = "a" & $count @@ -92,7 +95,7 @@ proc initGrammar() = # typedef X Y # typedef struct X Y # typedef ?* Y - gStateRT.grammar.add((&""" + result.add((&""" (type_definition {typeGrammar} (type_identifier!) @@ -105,17 +108,17 @@ proc initGrammar() = {funcGrammar} ) """, - proc (ast: ref Ast, node: TSNode) = + proc (ast: ref Ast, node: TSNode, nimState: NimState) = var i = 0 - typ = gStateRT.data[i].val.getIdentifier(nskType) + typ = nimState.data[i].val.getIdentifier(nskType) name = "" tptr = "" aptr = "" i += 1 - if i < gStateRT.data.len: - case gStateRT.data[i].name: + if i < nimState.data.len: + case nimState.data[i].name: of "pointer_declarator": tptr = "ptr " i += 1 @@ -123,19 +126,19 @@ proc initGrammar() = aptr = "ptr " i += 1 - if i < gStateRT.data.len: - name = gStateRT.data[i].val.getIdentifier(nskType) + if i < nimState.data.len: + name = nimState.data[i].val.getIdentifier(nskType) i += 1 - if typ.nBl and name.nBl and gStateRT.types.addNewIdentifer(name): - if i < gStateRT.data.len and gStateRT.data[^1].name == "function_declarator": + if typ.nBl and name.nBl and nimState.identifiers.addNewIdentifer(name): + if i < nimState.data.len and nimState.data[^1].name == "function_declarator": var fname = name pout, pname, ptyp, pptr = "" count = 1 - while i < gStateRT.data.len: - if gStateRT.data[i].name == "function_declarator": + while i < nimState.data.len: + if nimState.data[i].name == "function_declarator": break funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) @@ -144,29 +147,29 @@ proc initGrammar() = pout = pout[0 .. ^2] if tptr == "ptr " or typ != "object": - gStateRT.typeStr &= &" {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}\n" + nimState.typeStr &= &" {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}\n" else: - gStateRT.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n" + nimState.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n" else: - if i < gStateRT.data.len and gStateRT.data[i].name in ["identifier", "number_literal"]: + if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: var - flen = gStateRT.data[i].val - if gStateRT.data[i].name == "identifier": + flen = nimState.data[i].val + if nimState.data[i].name == "identifier": flen = flen.getIdentifier(nskConst) - doAssert flen.len != 0, &"Blank array length for '{name}', originally '{gStateRT.data[i].val}'" + doAssert flen.len != 0, &"Blank array length for '{name}', originally '{nimState.data[i].val}'" - gStateRT.typeStr &= &" {name}* = {aptr}array[{flen}, {getPtrType(tptr&typ)}]\n" + nimState.typeStr &= &" {name}* = {aptr}array[{flen}, {getPtrType(tptr&typ)}]\n" else: if name == typ: - gStateRT.typeStr &= &" {name}* = object\n" + nimState.typeStr &= &" {name}* = object\n" else: - gStateRT.typeStr &= &" {name}* = {getPtrType(tptr&typ)}\n" + nimState.typeStr &= &" {name}* = {getPtrType(tptr&typ)}\n" )) - proc pDupTypeCommon(nname: string, fend: int, isEnum=false) = + proc pDupTypeCommon(nname: string, fend: int, nimState: NimState, isEnum=false) = var - dname = gStateRT.data[^1].val - ndname = gStateRT.data[^1].val.getIdentifier(nskType) + dname = nimState.data[^1].val + ndname = nimState.data[^1].val.getIdentifier(nskType) dptr = if fend == 2: "ptr " @@ -175,14 +178,14 @@ proc initGrammar() = if ndname.nBl and ndname != nname: if isEnum: - if gStateRT.enums.addNewIdentifer(ndname): - gStateRT.enumStr &= &"type {ndname}* = {dptr}{nname}\n" + if nimState.identifiers.addNewIdentifer(ndname): + nimState.enumStr &= &"type {ndname}* = {dptr}{nname}\n" else: - if gStateRT.types.addNewIdentifer(ndname): - gStateRT.typeStr &= - &" {ndname}* {{.importc: \"{dname}\", header: {gStateRT.currentHeader}, bycopy.}} = {dptr}{nname}\n" + if nimState.identifiers.addNewIdentifer(ndname): + nimState.typeStr &= + &" {ndname}* {{.importc: \"{dname}\", header: {nimState.currentHeader}, bycopy.}} = {dptr}{nname}\n" - proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = + proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = var nname = name.getIdentifier(nskType) prefix = "" @@ -210,29 +213,29 @@ proc initGrammar() = union = " {.union.}" break - if nname.nBl and gStateRT.types.addNewIdentifer(nname): - if gStateRT.data.len == 1: - gStateRT.typeStr &= &" {nname}* {{.bycopy.}} = object{union}\n" + if nname.nBl and nimState.identifiers.addNewIdentifer(nname): + if nimState.data.len == 1: + nimState.typeStr &= &" {nname}* {{.bycopy.}} = object{union}\n" else: - gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object{union}\n" + nimState.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {nimState.currentHeader}, bycopy.}} = object{union}\n" var i = fstart ftyp, fname: string fptr = "" aptr = "" - while i < gStateRT.data.len-fend: + while i < nimState.data.len-fend: fptr = "" aptr = "" - if gStateRT.data[i].name == "field_declaration": + if nimState.data[i].name == "field_declaration": i += 1 continue - if gStateRT.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]: - ftyp = gStateRT.data[i].val.getType() + if nimState.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]: + ftyp = nimState.data[i].val.getType() i += 1 - case gStateRT.data[i].name: + case nimState.data[i].name: of "pointer_declarator": fptr = "ptr " i += 1 @@ -240,26 +243,26 @@ proc initGrammar() = aptr = "ptr " i += 1 - fname = gStateRT.data[i].val.getIdentifier(nskField) - doAssert fname.len != 0, &"Blank field name for '{nname}', originally '{gStateRT.data[i].val}'" + fname = nimState.data[i].val.getIdentifier(nskField) + doAssert fname.len != 0, &"Blank field name for '{nname}', originally '{nimState.data[i].val}'" - if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in gEnumVals: + if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: let - flen = gStateRT.data[i+1].val.getNimExpression() - gStateRT.typeStr &= &" {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]\n" + flen = nimState.data[i+1].val.getNimExpression() + nimState.typeStr &= &" {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]\n" i += 2 - elif i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "function_declarator": + elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "function_declarator": var pout, pname, ptyp, pptr = "" count = 1 i += 2 - while i < gStateRT.data.len-fend: - if gStateRT.data[i].name == "function_declarator": + while i < nimState.data.len-fend: + if nimState.data[i].name == "function_declarator": i += 1 continue - if gStateRT.data[i].name == "field_declaration": + if nimState.data[i].name == "field_declaration": break funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) @@ -267,20 +270,20 @@ proc initGrammar() = if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] if fptr == "ptr " or ftyp != "object": - gStateRT.typeStr &= &" {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}\n" + nimState.typeStr &= &" {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}\n" else: - gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n" + nimState.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n" i += 1 else: if ftyp == "object": - gStateRT.typeStr &= &" {fname}*: pointer\n" + nimState.typeStr &= &" {fname}*: pointer\n" else: - gStateRT.typeStr &= &" {fname}*: {getPtrType(fptr&ftyp)}\n" + nimState.typeStr &= &" {fname}*: {getPtrType(fptr&ftyp)}\n" i += 1 if node.tsNodeType() == "type_definition" and - gStateRT.data[^1].name == "type_identifier" and gStateRT.data[^1].val.len != 0: - pDupTypeCommon(nname, fend, false) + nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.len != 0: + pDupTypeCommon(nname, fend, nimState, false) let fieldGrammar = &""" @@ -313,18 +316,18 @@ proc initGrammar() = """ # struct X {} - gStateRT.grammar.add((&""" + result.add((&""" (struct_specifier|union_specifier (type_identifier) {fieldListGrammar} ) """, - proc (ast: ref Ast, node: TSNode) = - pStructCommon(ast, node, gStateRT.data[0].val, 1, 1) + proc (ast: ref Ast, node: TSNode, nimState: NimState) = + pStructCommon(ast, node, nimState.data[0].val, 1, 1, nimState) )) # typedef struct X {} - gStateRT.grammar.add((&""" + result.add((&""" (type_definition (struct_specifier|union_specifier (type_identifier?) @@ -336,67 +339,67 @@ proc initGrammar() = ) ) """, - proc (ast: ref Ast, node: TSNode) = + proc (ast: ref Ast, node: TSNode, nimState: NimState) = var fstart = 0 fend = 1 - if gStateRT.data[^2].name == "pointer_declarator": + if nimState.data[^2].name == "pointer_declarator": fend = 2 - if gStateRT.data.len > 1 and - gStateRT.data[0].name == "type_identifier" and - gStateRT.data[1].name != "field_identifier": + if nimState.data.len > 1 and + nimState.data[0].name == "type_identifier" and + nimState.data[1].name != "field_identifier": fstart = 1 - pStructCommon(ast, node, gStateRT.data[0].val, fstart, fend) + pStructCommon(ast, node, nimState.data[0].val, fstart, fend, nimState) else: - pStructCommon(ast, node, gStateRT.data[^1].val, fstart, fend) + pStructCommon(ast, node, nimState.data[^1].val, fstart, fend, nimState) )) - proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = + proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = let nname = if name.len == 0: - getUniqueIdentifier(gStateRT.enums, "Enum") + getUniqueIdentifier(nimState.identifiers, "Enum") else: name.getIdentifier(nskType) - if nname.nBl and gStateRT.enums.addNewIdentifer(nname): - gStateRT.enumStr &= &"\ntype {nname}* = distinct int" - gStateRT.enumStr &= &"\nconverter enumToInt(en: {nname}): int {{.used.}} = en.int\n" + if nname.nBl and nimState.identifiers.addNewIdentifer(nname): + nimState.enumStr &= &"\ntype {nname}* = distinct int" + nimState.enumStr &= &"\nconverter enumToInt(en: {nname}): int {{.used.}} = en.int\n" var i = fstart count = 0 - while i < gStateRT.data.len-fend: - if gStateRT.data[i].name == "enumerator": + while i < nimState.data.len-fend: + if nimState.data[i].name == "enumerator": i += 1 continue let - fname = gStateRT.data[i].val.getIdentifier(nskEnumField) + fname = nimState.data[i].val.getIdentifier(nskEnumField) - if i+1 < gStateRT.data.len-fend and - gStateRT.data[i+1].name in gEnumVals: - if fname.nBl and gStateRT.consts.addNewIdentifer(fname): - gStateRT.constStr &= &" {fname}* = ({gStateRT.data[i+1].val.getNimExpression()}).{nname}\n" + if i+1 < nimState.data.len-fend and + nimState.data[i+1].name in gEnumVals: + if fname.nBl and nimState.identifiers.addNewIdentifer(fname): + nimState.constStr &= &" {fname}* = ({nimState.data[i+1].val.getNimExpression()}).{nname}\n" try: - count = gStateRT.data[i+1].val.parseInt() + 1 + count = nimState.data[i+1].val.parseInt() + 1 except: count += 1 i += 2 else: - if fname.nBl and gStateRT.consts.addNewIdentifer(fname): - gStateRT.constStr &= &" {fname}* = {count}.{nname}\n" + if fname.nBl and nimState.identifiers.addNewIdentifer(fname): + nimState.constStr &= &" {fname}* = {count}.{nname}\n" i += 1 count += 1 if node.tsNodeType() == "type_definition" and - gStateRT.data[^1].name == "type_identifier" and gStateRT.data[^1].val.len != 0: - pDupTypeCommon(nname, fend, true) + nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.len != 0: + pDupTypeCommon(nname, fend, nimState, true) # enum X {} - gStateRT.grammar.add((""" + result.add((""" (enum_specifier (type_identifier?) (enumerator_list @@ -407,46 +410,46 @@ proc initGrammar() = ) ) """ % gEnumVals.join("|"), - proc (ast: ref Ast, node: TSNode) = + proc (ast: ref Ast, node: TSNode, nimState: NimState) = var name = "" offset = 0 - if gStateRT.data[0].name == "type_identifier": - name = gStateRT.data[0].val + if nimState.data[0].name == "type_identifier": + name = nimState.data[0].val offset = 1 - pEnumCommon(ast, node, name, offset, 0) + pEnumCommon(ast, node, name, offset, 0, nimState) )) # typedef enum {} X - gStateRT.grammar.add((&""" + result.add((&""" (type_definition - {gStateRT.grammar[^1].grammar} + {result[^1].grammar} (type_identifier!) (pointer_declarator (type_identifier) ) ) """, - proc (ast: ref Ast, node: TSNode) = + proc (ast: ref Ast, node: TSNode, nimState: NimState) = var fstart = 0 fend = 1 - if gStateRT.data[^2].name == "pointer_declarator": + if nimState.data[^2].name == "pointer_declarator": fend = 2 - if gStateRT.data[0].name == "type_identifier": + if nimState.data[0].name == "type_identifier": fstart = 1 - pEnumCommon(ast, node, gStateRT.data[0].val, fstart, fend) + pEnumCommon(ast, node, nimState.data[0].val, fstart, fend, nimState) else: - pEnumCommon(ast, node, gStateRT.data[^1].val, fstart, fend) + pEnumCommon(ast, node, nimState.data[^1].val, fstart, fend, nimState) )) # typ function(typ param1, ...) - gStateRT.grammar.add((&""" + result.add((&""" (declaration (storage_class_specifier?) {typeGrammar} @@ -456,32 +459,32 @@ proc initGrammar() = {funcGrammar} ) """, - proc (ast: ref Ast, node: TSNode) = + proc (ast: ref Ast, node: TSNode, nimState: NimState) = var - ftyp = gStateRT.data[0].val.getIdentifier(nskType) + ftyp = nimState.data[0].val.getIdentifier(nskType) fptr = "" i = 1 - while i < gStateRT.data.len: - if gStateRT.data[i].name == "function_declarator": + while i < nimState.data.len: + if nimState.data[i].name == "function_declarator": i += 1 continue - if gStateRT.data[i].name == "pointer_declarator": + if nimState.data[i].name == "pointer_declarator": fptr = "ptr " i += 1 else: fptr = "" var - fname = gStateRT.data[i].val + fname = nimState.data[i].val fnname = fname.getIdentifier(nskProc) pout, pname, ptyp, pptr = "" count = 1 i += 1 - while i < gStateRT.data.len: - if gStateRT.data[i].name == "function_declarator": + while i < nimState.data.len: + if nimState.data[i].name == "function_declarator": break funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i) @@ -489,11 +492,11 @@ proc initGrammar() = if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] - if ftyp.nBl and fnname.nBl and gStateRT.procs.addNewIdentifer(fnname): + if ftyp.nBl and fnname.nBl and nimState.identifiers.addNewIdentifer(fnname): if fptr == "ptr " or ftyp != "object": - gStateRT.procStr &= &"proc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + nimState.procStr &= &"proc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {nimState.currentHeader}.}}\n" else: - gStateRT.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + nimState.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {nimState.currentHeader}.}}\n" )) @@ -512,28 +515,23 @@ proc initRegex(ast: ref Ast) = echo reg raise newException(Exception, getCurrentExceptionMsg()) -proc parseGrammar*() = - gStateRT.consts.init() - gStateRT.enums.init() - gStateRT.procs.init() - gStateRT.types.init() - - initGrammar() +proc parseGrammar*(): AstTable = + let grammars = initGrammar() - gStateRT.ast = initTable[string, seq[ref Ast]]() - for i in 0 .. gStateRT.grammar.len-1: + result = newTable[string, seq[ref Ast]]() + for i in 0 .. grammars.len-1: var - ast = gStateRT.grammar[i].grammar.parseLisp() + ast = grammars[i].grammar.parseLisp() - ast.tonim = gStateRT.grammar[i].call + ast.tonim = grammars[i].call ast.initRegex() for n in ast.name.split("|"): - if n notin gStateRT.ast: - gStateRT.ast[n] = @[ast] + if n notin result: + result[n] = @[ast] else: - gStateRT.ast[n].add(ast) + result[n].add(ast) -proc printGrammar*() = - for name in gStateRT.ast.keys(): - for ast in gStateRT.ast[name]: +proc printGrammar*(astTable: AstTable) = + for name in astTable.keys(): + for ast in astTable[name]: echo ast.printAst() @@ -53,7 +53,7 @@ proc printLisp(root: TSNode) = if node == root: break -proc process(path: string) = +proc process(path: string, astTable: AstTable) = if not existsFile(path): echo "Invalid path " & path return @@ -97,7 +97,7 @@ proc process(path: string) = if gStateRT.past: printLisp(root) elif gStateRT.pnim: - printNim(path, root) + printNim(path, root, astTable) elif gStateRT.preprocess: echo gStateRT.code @@ -136,11 +136,12 @@ proc main( if pluginSourcePath.nBl: loadPlugin(pluginSourcePath) + let + astTable = parseGrammar() if pgrammar: - parseGrammar() - printGrammar() + astTable.printGrammar() elif source.len != 0: - process(source[0]) + process(source[0], astTable) when isMainModule: import cligen |
