aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2019-01-28 00:30:59 -0600
committerGanesh Viswanathan <dev@genotrance.com>2019-01-28 00:30:59 -0600
commit70aa3e2b5e47102a7e9bdbb76320d8c6ccad57b9 (patch)
treef84681e64fc6a70050be32a8a1e1497fe7c3a2b4
parentef0a250066a336ef0bd372ed3045c8170a00dd35 (diff)
downloadnimterop-70aa3e2b5e47102a7e9bdbb76320d8c6ccad57b9.tar.gz
nimterop-70aa3e2b5e47102a7e9bdbb76320d8c6ccad57b9.zip
Fix #42 - duplicate stylistic identifiers
-rw-r--r--nimterop/ast.nim80
-rw-r--r--nimterop/getters.nim21
-rw-r--r--nimterop/globals.nim22
-rw-r--r--nimterop/grammar.nim268
-rw-r--r--toast.nim11
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()
diff --git a/toast.nim b/toast.nim
index a045d63..4b2de74 100644
--- a/toast.nim
+++ b/toast.nim
@@ -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