Use HashSet, fix #40, compare nimNames

This commit is contained in:
Ganesh Viswanathan 2019-01-17 22:19:26 -06:00
commit 287980c9ed
4 changed files with 27 additions and 22 deletions

View file

@ -1,4 +1,4 @@
import strformat, strutils, tables import sets, strformat, strutils, tables
import regex import regex
@ -14,7 +14,7 @@ const gAtoms = @[
"primitive_type", "primitive_type",
"sized_type_specifier", "sized_type_specifier",
"type_identifier" "type_identifier"
] ].toSet()
proc saveNodeData(node: TSNode): bool = proc saveNodeData(node: TSNode): bool =
let name = $node.tsNodeType() let name = $node.tsNodeType()

View file

@ -1,4 +1,4 @@
import macros, os, strformat, strutils, tables import macros, os, sets, strformat, strutils, tables
import regex import regex
@ -24,7 +24,7 @@ using
var var
when while when while
xor xor
yield""".split(Whitespace) yield""".split(Whitespace).toSet()
const gTypeMap = { const gTypeMap = {
# char # char
@ -92,21 +92,25 @@ proc getType*(str: string): string =
result = gTypeMap[result] result = gTypeMap[result]
proc getIdentifier*(str: string): string = proc getIdentifier*(str: string): string =
result = str.strip(chars={'_'}).replace(re"_+", "_").getType() result = str.strip(chars={'_'}).replace(re"_+", "_")
if result in gReserved: if result in gReserved:
result = &"`{result}`" result = &"`{result}`"
proc getUniqueIdentifier*(exists: seq[string], prefix = ""): string = proc getUniqueIdentifier*(existing: HashSet[string], prefix = ""): string =
var var
name = prefix & "_" & gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) name = prefix & "_" & gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")])
nimName = name.replace("_", "").toLowerAscii
count = 1 count = 1
while (name & $count) in exists: while (nimName & $count) in existing:
count += 1 count += 1
return name & $count return name & $count
proc addNewIdentifer*(existing: var HashSet[string], name: string): bool =
return not existing.containsOrIncl(name.replace("_", "").toLowerAscii)
proc getPtrType*(str: string): string = proc getPtrType*(str: string): string =
result = case str: result = case str:
of "ptr cchar": of "ptr cchar":

View file

@ -1,4 +1,4 @@
import tables import sets, tables
import regex import regex
@ -26,7 +26,7 @@ type
debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool
consts*, enums*, procs*, types*: seq[string] consts*, enums*, procs*, types*: HashSet[string]
code*, constStr*, currentHeader*, debugStr*, enumStr*, mode*, procStr*, typeStr*: string code*, constStr*, currentHeader*, debugStr*, enumStr*, mode*, procStr*, typeStr*: string
sourceFile*: string # eg, C or C++ source or header file sourceFile*: string # eg, C or C++ source or header file

View file

@ -1,4 +1,4 @@
import strformat, strutils, tables import sets, strformat, strutils, tables
import regex import regex
@ -17,8 +17,7 @@ proc initGrammar() =
name = gStateRT.data[0].val.getIdentifier() name = gStateRT.data[0].val.getIdentifier()
val = gStateRT.data[1].val.getLit() val = gStateRT.data[1].val.getLit()
if name notin gStateRT.consts and val.nBl: if val.nBl and gStateRT.consts.addNewIdentifer(name):
gStateRT.consts.add(name)
gStateRT.constStr &= &" {name}* = {val}\n" gStateRT.constStr &= &" {name}* = {val}\n"
)) ))
@ -82,7 +81,8 @@ proc initGrammar() =
pname = "a" & $count pname = "a" & $count
count += 1 count += 1
i += 1 i += 1
pout &= &"{pname}: {getPtrType(pptr&ptyp)}," if pptr == "ptr " or ptyp != "object":
pout &= &"{pname}: {getPtrType(pptr&ptyp)},"
# typedef int X # typedef int X
# typedef X Y # typedef X Y
@ -123,7 +123,7 @@ proc initGrammar() =
name = gStateRT.data[i].val.getIdentifier() name = gStateRT.data[i].val.getIdentifier()
i += 1 i += 1
if name notin gStateRT.types: if gStateRT.types.addNewIdentifer(name):
if i < gStateRT.data.len and gStateRT.data[^1].name == "function_declarator": if i < gStateRT.data.len and gStateRT.data[^1].name == "function_declarator":
var var
pout, pname, ptyp, pptr = "" pout, pname, ptyp, pptr = ""
@ -142,7 +142,6 @@ proc initGrammar() =
else: else:
gStateRT.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n" gStateRT.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n"
else: else:
gStateRT.types.add(name)
if i < gStateRT.data.len and gStateRT.data[i].name in ["identifier", "number_literal"]: if i < gStateRT.data.len and gStateRT.data[i].name in ["identifier", "number_literal"]:
let let
flen = gStateRT.data[i].val.getIdentifier() flen = gStateRT.data[i].val.getIdentifier()
@ -176,8 +175,7 @@ proc initGrammar() =
union = " {.union.}" union = " {.union.}"
break break
if nname notin gStateRT.types: if gStateRT.types.addNewIdentifer(nname):
gStateRT.types.add(nname)
gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object{union}\n" gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object{union}\n"
var var
@ -310,8 +308,7 @@ proc initGrammar() =
if nname.len == 0: if nname.len == 0:
nname = getUniqueIdentifier(gStateRT.enums, "Enum") nname = getUniqueIdentifier(gStateRT.enums, "Enum")
if nname notin gStateRT.enums: if gStateRT.enums.addNewIdentifer(nname):
gStateRT.enums.add(nname)
gStateRT.enumStr &= &"\ntype {nname}* = distinct int" gStateRT.enumStr &= &"\ntype {nname}* = distinct int"
gStateRT.enumStr &= &"\nconverter enumToInt(en: {nname}): int {{.used.}} = en.int\n" gStateRT.enumStr &= &"\nconverter enumToInt(en: {nname}): int {{.used.}} = en.int\n"
@ -326,7 +323,7 @@ proc initGrammar() =
i += 1 i += 1
continue continue
if fname notin gStateRT.consts: if gStateRT.consts.addNewIdentifer(fname):
if i+1 < gStateRT.data.len-fend and if i+1 < gStateRT.data.len-fend and
gStateRT.data[i+1].name in ["identifier", "shift_expression", "math_expression", "number_literal"]: gStateRT.data[i+1].name in ["identifier", "shift_expression", "math_expression", "number_literal"]:
if " " in gStateRT.data[i+1].val: if " " in gStateRT.data[i+1].val:
@ -432,8 +429,7 @@ proc initGrammar() =
if pout.len != 0 and pout[^1] == ',': if pout.len != 0 and pout[^1] == ',':
pout = pout[0 .. ^2] pout = pout[0 .. ^2]
if fnname notin gStateRT.procs: if gStateRT.procs.addNewIdentifer(fnname):
gStateRT.procs.add(fnname)
if ftyp != "object": if ftyp != "object":
gStateRT.procStr &= &"proc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" gStateRT.procStr &= &"proc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n"
else: else:
@ -456,6 +452,11 @@ proc initRegex(ast: ref Ast) =
raise newException(Exception, getCurrentExceptionMsg()) raise newException(Exception, getCurrentExceptionMsg())
proc parseGrammar*() = proc parseGrammar*() =
gStateRT.consts.init()
gStateRT.enums.init()
gStateRT.procs.init()
gStateRT.types.init()
initGrammar() initGrammar()
gStateRT.ast = initTable[string, seq[ref Ast]]() gStateRT.ast = initTable[string, seq[ref Ast]]()