Get rid of nimState

This commit is contained in:
Ganesh Viswanathan 2020-04-21 14:53:26 -05:00
commit 183eabff83
5 changed files with 595 additions and 611 deletions

View file

@ -4,27 +4,27 @@ import regex
import "."/[getters, globals, treesitter/api] import "."/[getters, globals, treesitter/api]
proc getHeaderPragma*(nimState: NimState): string = proc getHeaderPragma*(gState: State): string =
result = result =
if nimState.includeHeader(): if gState.isIncludeHeader():
&", header: {nimState.currentHeader}" &", header: {gState.currentHeader}"
else: else:
"" ""
proc getDynlib*(nimState: NimState): string = proc getDynlib*(gState: State): string =
result = result =
if nimState.gState.dynlib.nBl: if gState.dynlib.nBl:
&", dynlib: {nimState.gState.dynlib}" &", dynlib: {gState.dynlib}"
else: else:
"" ""
proc getImportC*(nimState: NimState, origName, nimName: string): string = proc getImportC*(gState: State, origName, nimName: string): string =
if nimName != origName: if nimName != origName:
result = &"importc: \"{origName}\"{nimState.getHeaderPragma()}" result = &"importc: \"{origName}\"{gState.getHeaderPragma()}"
else: else:
result = nimState.impShort result = gState.impShort
proc getPragma*(nimState: NimState, pragmas: varargs[string]): string = proc getPragma*(gState: State, pragmas: varargs[string]): string =
result = "" result = ""
for pragma in pragmas.items(): for pragma in pragmas.items():
if pragma.nBl: if pragma.nBl:
@ -32,15 +32,15 @@ proc getPragma*(nimState: NimState, pragmas: varargs[string]): string =
if result.nBl: if result.nBl:
result = " {." & result[0 .. ^3] & ".}" result = " {." & result[0 .. ^3] & ".}"
result = result.replace(nimState.impShort & ", cdecl", nimState.impShort & "C") result = result.replace(gState.impShort & ", cdecl", gState.impShort & "C")
let let
dy = nimState.getDynlib() dy = gState.getDynlib()
if ", cdecl" in result and dy.nBl: if ", cdecl" in result and dy.nBl:
result = result.replace(".}", dy & ".}") result = result.replace(".}", dy & ".}")
proc saveNodeData(node: TSNode, nimState: NimState): bool = proc saveNodeData(node: TSNode, gState: State): bool =
let name = $node.tsNodeType() let name = $node.tsNodeType()
# Atoms are nodes whose values are to be saved # Atoms are nodes whose values are to be saved
@ -52,7 +52,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool =
ppppname = node.getPxName(4) ppppname = node.getPxName(4)
var var
val = nimState.getNodeVal(node) val = gState.getNodeVal(node)
# Skip since value already obtained from parent atom # Skip since value already obtained from parent atom
if name == "primitive_type" and pname == "sized_type_specifier": if name == "primitive_type" and pname == "sized_type_specifier":
@ -64,7 +64,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool =
# Add reference point in saved data for bitfield_clause # Add reference point in saved data for bitfield_clause
if name in ["number_literal"] and pname == "bitfield_clause": if name in ["number_literal"] and pname == "bitfield_clause":
nimState.data.add(("bitfield_clause", val)) gState.data.add(("bitfield_clause", val))
return true return true
# Process value as a type # Process value as a type
@ -74,52 +74,52 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool =
if node.tsNodePrevNamedSibling().tsNodeIsNull(): if node.tsNodePrevNamedSibling().tsNodeIsNull():
if pname == "pointer_declarator": if pname == "pointer_declarator":
if ppname notin ["function_declarator", "array_declarator"]: if ppname notin ["function_declarator", "array_declarator"]:
nimState.data.add(("pointer_declarator", "")) gState.data.add(("pointer_declarator", ""))
elif ppname == "array_declarator": elif ppname == "array_declarator":
nimState.data.add(("array_pointer_declarator", "")) gState.data.add(("array_pointer_declarator", ""))
# Double pointer # Double pointer
if ppname == "pointer_declarator": if ppname == "pointer_declarator":
nimState.data.add(("pointer_declarator", "")) gState.data.add(("pointer_declarator", ""))
elif pname in ["function_declarator", "array_declarator"]: elif pname in ["function_declarator", "array_declarator"]:
if ppname == "pointer_declarator": if ppname == "pointer_declarator":
nimState.data.add(("pointer_declarator", "")) gState.data.add(("pointer_declarator", ""))
if pppname == "pointer_declarator": if pppname == "pointer_declarator":
nimState.data.add(("pointer_declarator", "")) gState.data.add(("pointer_declarator", ""))
nimState.data.add((name, val)) gState.data.add((name, val))
if pname == "pointer_declarator" and if pname == "pointer_declarator" and
ppname == "function_declarator": ppname == "function_declarator":
if name == "field_identifier": if name == "field_identifier":
if pppname == "pointer_declarator": if pppname == "pointer_declarator":
nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) gState.data.insert(("pointer_declarator", ""), gState.data.len-1)
if ppppname == "pointer_declarator": if ppppname == "pointer_declarator":
nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) gState.data.insert(("pointer_declarator", ""), gState.data.len-1)
nimState.data.add(("function_declarator", "")) gState.data.add(("function_declarator", ""))
elif name == "identifier": elif name == "identifier":
nimState.data.add(("pointer_declarator", "")) gState.data.add(("pointer_declarator", ""))
# Save node value for a top-level expression # Save node value for a top-level expression
elif name in gExpressions and name != "escape_sequence": elif name in gExpressions and name != "escape_sequence":
if $node.tsNodeParent.tsNodeType() notin gExpressions: if $node.tsNodeParent.tsNodeType() notin gExpressions:
nimState.data.add((name, nimState.getNodeVal(node))) gState.data.add((name, gState.getNodeVal(node)))
elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]:
nimState.data.add((name.replace("abstract_", ""), "")) gState.data.add((name.replace("abstract_", ""), ""))
return true return true
proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = proc searchAstForNode(ast: ref Ast, node: TSNode, gState: State): bool =
let let
childNames = node.getTSNodeNamedChildNames().join() childNames = node.getTSNodeNamedChildNames().join()
if ast.isNil: if ast.isNil:
return return
if nimState.gState.debug: if gState.debug:
nimState.nodeBranch.add $node.tsNodeType() gState.nodeBranch.add $node.tsNodeType()
necho "#" & spaces(nimState.nodeBranch.len * 2) & nimState.nodeBranch[^1] gecho "#" & spaces(gState.nodeBranch.len * 2) & gState.nodeBranch[^1]
if ast.children.nBl: if ast.children.nBl:
if childNames.contains(ast.regex) or if childNames.contains(ast.regex) or
@ -137,26 +137,26 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool =
else: else:
ast ast
if not searchAstForNode(astChild, nodeChild, nimState): if not searchAstForNode(astChild, nodeChild, gState):
flag = false flag = false
break break
if flag: if flag:
result = node.saveNodeData(nimState) result = node.saveNodeData(gState)
else: else:
result = node.saveNodeData(nimState) result = node.saveNodeData(gState)
else: else:
if nimState.gState.debug: if gState.debug:
necho "#" & spaces(nimState.nodeBranch.len * 2) & &" {ast.getRegexForAstChildren()} !=~ {childNames}" gecho "#" & spaces(gState.nodeBranch.len * 2) & &" {ast.getRegexForAstChildren()} !=~ {childNames}"
elif node.getTSNodeNamedChildCountSansComments() == 0: elif node.getTSNodeNamedChildCountSansComments() == 0:
result = node.saveNodeData(nimState) result = node.saveNodeData(gState)
if nimState.gState.debug: if gState.debug:
discard nimState.nodeBranch.pop() discard gState.nodeBranch.pop()
if nimstate.nodeBranch.Bl: if gState.nodeBranch.Bl:
necho "" gecho ""
proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = proc searchAst(root: TSNode, astTable: AstTable, gState: State) =
var var
node = root node = root
nextnode: TSNode nextnode: TSNode
@ -168,14 +168,14 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) =
name = $node.tsNodeType() name = $node.tsNodeType()
if name in astTable: if name in astTable:
for ast in astTable[name]: for ast in astTable[name]:
if nimState.gState.debug: if gState.debug:
necho "\n# " & nimState.getNodeVal(node).replace("\n", "\n# ") & "\n" gecho "\n# " & gState.getNodeVal(node).replace("\n", "\n# ") & "\n"
if searchAstForNode(ast, node, nimState): if searchAstForNode(ast, node, gState):
ast.tonim(ast, node, nimState) ast.tonim(ast, node, gState)
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# " & nimState.data.join("\n# ") & "\n" gState.debugStr &= "\n# " & gState.data.join("\n# ") & "\n"
break break
nimState.data = @[] gState.data = @[]
else: else:
break break
@ -204,48 +204,46 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) =
proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable) = proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable) =
var var
nimState = new(NimState)
fp = fullpath.replace("\\", "/") fp = fullpath.replace("\\", "/")
nimState.identifiers = newTable[string, string]() gState.identifiers = newTable[string, string]()
nimState.gState = gState gState.currentHeader = getCurrentHeader(fullpath)
nimState.currentHeader = getCurrentHeader(fullpath) gState.impShort = gState.currentHeader.replace("header", "imp")
nimState.impShort = nimState.currentHeader.replace("header", "imp") gState.sourceFile = fullpath
nimState.sourceFile = fullpath
if nimState.includeHeader(): if gState.isIncludeHeader():
nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" gState.constStr &= &"\n {gState.currentHeader} {{.used.}} = \"{fp}\""
root.searchAst(astTable, nimState) root.searchAst(astTable, gState)
if nimState.enumStr.nBl: if gState.enumStr.nBl:
necho &"{nimState.enumStr}\n" gecho &"{gState.enumStr}\n"
nimState.constStr = nimState.getOverrideFinal(nskConst) & nimState.constStr gState.constStr = gState.getOverrideFinal(nskConst) & gState.constStr
if nimState.constStr.nBl: if gState.constStr.nBl:
necho &"const{nimState.constStr}\n" gecho &"const{gState.constStr}\n"
necho &""" gecho &"""
{{.pragma: {nimState.impShort}, importc{nimState.getHeaderPragma()}.}} {{.pragma: {gState.impShort}, importc{gState.getHeaderPragma()}.}}
{{.pragma: {nimState.impShort}C, {nimState.impShort}, cdecl{nimState.getDynlib()}.}} {{.pragma: {gState.impShort}C, {gState.impShort}, cdecl{gState.getDynlib()}.}}
""" """
nimState.typeStr = nimState.getOverrideFinal(nskType) & nimState.typeStr gState.typeStr = gState.getOverrideFinal(nskType) & gState.typeStr
if nimState.typeStr.nBl: if gState.typeStr.nBl:
necho &"type{nimState.typeStr}\n" gecho &"type{gState.typeStr}\n"
nimState.procStr = nimState.getOverrideFinal(nskProc) & nimState.procStr gState.procStr = gState.getOverrideFinal(nskProc) & gState.procStr
if nimState.procStr.nBl: if gState.procStr.nBl:
necho &"{nimState.procStr}\n" gecho &"{gState.procStr}\n"
if nimState.gState.debug: if gState.debug:
if nimState.debugStr.nBl: if gState.debugStr.nBl:
necho nimState.debugStr gecho gState.debugStr
if nimState.skipStr.nBl: if gState.skipStr.nBl:
let let
hash = nimState.skipStr.hash().abs() hash = gState.skipStr.hash().abs()
sname = getTempDir() / &"nimterop_{$hash}.h" sname = getTempDir() / &"nimterop_{$hash}.h"
necho &"# Writing skipped definitions to {sname}\n" gecho &"# Writing skipped definitions to {sname}\n"
writeFile(sname, nimState.skipStr) writeFile(sname, gState.skipStr)

File diff suppressed because it is too large Load diff

View file

@ -113,32 +113,32 @@ proc checkIdentifier(name, kind, parent, origName: string) =
if parent.nBl: if parent.nBl:
doAssert name.nBl, &"Blank identifier, originally '{parentStr}{origName}' ({kind}), cannot be empty" doAssert name.nBl, &"Blank identifier, originally '{parentStr}{origName}' ({kind}), cannot be empty"
proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=""): string = proc getIdentifier*(gState: State, name: string, kind: NimSymKind, parent=""): string =
doAssert name.nBl, "Blank identifier error" doAssert name.nBl, "Blank identifier error"
if name notin nimState.gState.symOverride or parent.nBl: if name notin gState.symOverride or parent.nBl:
if nimState.gState.onSymbol != nil: if gState.onSymbol != nil:
# Use onSymbol from plugin provided by user # Use onSymbol from plugin provided by user
var var
sym = Symbol(name: name, parent: parent, kind: kind) sym = Symbol(name: name, parent: parent, kind: kind)
nimState.gState.onSymbol(sym) gState.onSymbol(sym)
result = sym.name result = sym.name
else: else:
result = name result = name
# Strip out --prefix from CLI if specified # Strip out --prefix from CLI if specified
for str in nimState.gState.prefix: for str in gState.prefix:
if result.startsWith(str): if result.startsWith(str):
result = result[str.len .. ^1] result = result[str.len .. ^1]
# Strip out --suffix from CLI if specified # Strip out --suffix from CLI if specified
for str in nimState.gState.suffix: for str in gState.suffix:
if result.endsWith(str): if result.endsWith(str):
result = result[0 .. ^(str.len+1)] result = result[0 .. ^(str.len+1)]
# --replace from CLI if specified # --replace from CLI if specified
for name, value in nimState.gState.replace.pairs: for name, value in gState.replace.pairs:
if name.len > 1 and name[0] == '@': if name.len > 1 and name[0] == '@':
result = result.replace(re(name[1 .. ^1]), value) result = result.replace(re(name[1 .. ^1]), value)
else: else:
@ -153,58 +153,58 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent="
# Skip identifier since in symOverride # Skip identifier since in symOverride
result = "" result = ""
proc getUniqueIdentifier*(nimState: NimState, prefix = ""): string = proc getUniqueIdentifier*(gState: State, prefix = ""): string =
var var
name = prefix & "_" & nimState.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) name = prefix & "_" & gState.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")])
nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii
count = 1 count = 1
while (nimName & $count) in nimState.identifiers: while (nimName & $count) in gState.identifiers:
count += 1 count += 1
return name & $count return name & $count
proc addNewIdentifer*(nimState: NimState, name: string, override = false): bool = proc addNewIdentifer*(gState: State, name: string, override = false): bool =
if override or name notin nimState.gState.symOverride: if override or name notin gState.symOverride:
let let
nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii
if nimState.identifiers.hasKey(nimName): if gState.identifiers.hasKey(nimName):
doAssert name == nimState.identifiers[nimName], doAssert name == gState.identifiers[nimName],
&"Identifier '{name}' is a stylistic duplicate of identifier " & &"Identifier '{name}' is a stylistic duplicate of identifier " &
&"'{nimState.identifiers[nimName]}', use 'cPlugin:onSymbol()' to rename" &"'{gState.identifiers[nimName]}', use 'cPlugin:onSymbol()' to rename"
result = false result = false
else: else:
nimState.identifiers[nimName] = name gState.identifiers[nimName] = name
result = true result = true
# Overrides related # Overrides related
proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = proc getOverride*(gState: State, name: string, kind: NimSymKind): string =
# Get cOverride for identifier `name` of `kind` if defined # Get cOverride for identifier `name` of `kind` if defined
doAssert name.nBl, "Blank identifier error" doAssert name.nBl, "Blank identifier error"
if nimState.gState.onSymbolOverride != nil: if gState.onSymbolOverride != nil:
var var
nname = nimState.getIdentifier(name, kind, "Override") nname = gState.getIdentifier(name, kind, "Override")
sym = Symbol(name: nname, kind: kind) sym = Symbol(name: nname, kind: kind)
if nname.nBl: if nname.nBl:
nimState.gState.onSymbolOverride(sym) gState.onSymbolOverride(sym)
if sym.override.nBl and nimState.addNewIdentifer(nname, override = true): if sym.override.nBl and gState.addNewIdentifer(nname, override = true):
result = sym.override result = sym.override
if kind != nskProc: if kind != nskProc:
result = result.replace(re"(?m)^(.*?)$", " $1") result = result.replace(re"(?m)^(.*?)$", " $1")
proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = proc getOverrideFinal*(gState: State, kind: NimSymKind): string =
# Get all unused cOverride symbols of `kind` # Get all unused cOverride symbols of `kind`
let let
typ = $kind typ = $kind
if nimState.gState.onSymbolOverrideFinal != nil: if gState.onSymbolOverrideFinal != nil:
for i in nimState.gState.onSymbolOverrideFinal(typ): for i in gState.onSymbolOverrideFinal(typ):
result &= "\n" & nimState.getOverride(i, kind) result &= "\n" & gState.getOverride(i, kind)
proc getKeyword*(kind: NimSymKind): string = proc getKeyword*(kind: NimSymKind): string =
# Convert `kind` into a Nim keyword # Convert `kind` into a Nim keyword
@ -232,9 +232,6 @@ proc getNodeVal*(gState: State, node: TSNode): string =
if not node.isNil: if not node.isNil:
return gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() return gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip()
proc getNodeVal*(nimState: NimState, node: TSNode): string =
nimState.gState.getNodeVal(node)
proc getAtom*(node: TSNode): TSNode = proc getAtom*(node: TSNode): TSNode =
if not node.isNil: if not node.isNil:
# Get child node which is topmost atom # Get child node which is topmost atom
@ -428,8 +425,8 @@ proc printLisp*(gState: State, root: TSNode): string =
proc getCommented*(str: string): string = proc getCommented*(str: string): string =
"\n# " & str.strip().replace("\n", "\n# ") "\n# " & str.strip().replace("\n", "\n# ")
proc printTree*(nimState: NimState, pnode: PNode, offset = ""): string = proc printTree*(gState: State, pnode: PNode, offset = ""): string =
if nimState.gState.debug and pnode.kind != nkNone: if gState.debug and pnode.kind != nkNone:
result &= "\n# " & offset & $pnode.kind & "(" result &= "\n# " & offset & $pnode.kind & "("
case pnode.kind case pnode.kind
of nkCharLit: of nkCharLit:
@ -447,7 +444,7 @@ proc printTree*(nimState: NimState, pnode: PNode, offset = ""): string =
else: else:
if pnode.sons.len != 0: if pnode.sons.len != 0:
for i in 0 ..< pnode.sons.len: for i in 0 ..< pnode.sons.len:
result &= nimState.printTree(pnode.sons[i], offset & " ") result &= gState.printTree(pnode.sons[i], offset & " ")
if i != pnode.sons.len - 1: if i != pnode.sons.len - 1:
result &= "," result &= ","
result &= "\n# " & offset & ")" result &= "\n# " & offset & ")"
@ -456,34 +453,34 @@ proc printTree*(nimState: NimState, pnode: PNode, offset = ""): string =
if offset.len == 0: if offset.len == 0:
result &= "\n" result &= "\n"
proc printDebug*(nimState: NimState, node: TSNode) = proc printDebug*(gState: State, node: TSNode) =
if nimState.gState.debug: if gState.debug:
necho ("Input => " & nimState.getNodeVal(node)).getCommented() & "\n" & gecho ("Input => " & gState.getNodeVal(node)).getCommented() & "\n" &
nimState.gState.printLisp(node).getCommented() gState.printLisp(node).getCommented()
proc printDebug*(nimState: NimState, pnode: PNode) = proc printDebug*(gState: State, pnode: PNode) =
if nimState.gState.debug: if gState.debug:
necho ("Output => " & $pnode).getCommented() & "\n" & gecho ("Output => " & $pnode).getCommented() & "\n" &
nimState.printTree(pnode) gState.printTree(pnode)
# Compiler shortcuts # Compiler shortcuts
proc getDefaultLineInfo*(nimState: NimState): TLineInfo = proc getDefaultLineInfo*(gState: State): TLineInfo =
result = newLineInfo(nimState.config, nimState.sourceFile.AbsoluteFile, 0, 0) result = newLineInfo(gState.config, gState.sourceFile.AbsoluteFile, 0, 0)
proc getLineInfo*(nimState: NimState, node: TSNode): TLineInfo = proc getLineInfo*(gState: State, node: TSNode): TLineInfo =
# Get Nim equivalent line:col info from node # Get Nim equivalent line:col info from node
let let
(line, col) = nimState.gState.getLineCol(node) (line, col) = gState.getLineCol(node)
result = newLineInfo(nimState.config, nimState.sourceFile.AbsoluteFile, line, col) result = newLineInfo(gState.config, gState.sourceFile.AbsoluteFile, line, col)
proc getIdent*(nimState: NimState, name: string, info: TLineInfo, exported = true): PNode = proc getIdent*(gState: State, name: string, info: TLineInfo, exported = true): PNode =
if name.nBl: if name.nBl:
# Get ident PNode for name + info # Get ident PNode for name + info
let let
exp = getIdent(nimState.identCache, "*") exp = getIdent(gState.identCache, "*")
ident = getIdent(nimState.identCache, name) ident = getIdent(gState.identCache, name)
if exported: if exported:
result = newNode(nkPostfix) result = newNode(nkPostfix)
@ -492,8 +489,8 @@ proc getIdent*(nimState: NimState, name: string, info: TLineInfo, exported = tru
else: else:
result = newIdentNode(ident, info) result = newIdentNode(ident, info)
proc getIdent*(nimState: NimState, name: string): PNode = proc getIdent*(gState: State, name: string): PNode =
nimState.getIdent(name, nimState.getDefaultLineInfo(), exported = false) gState.getIdent(name, gState.getDefaultLineInfo(), exported = false)
proc getIdentName*(node: PNode): string = proc getIdentName*(node: PNode): string =
if not node.isNil: if not node.isNil:
@ -503,15 +500,15 @@ proc getIdentName*(node: PNode): string =
if result.Bl and node.len > 0: if result.Bl and node.len > 0:
result = node[0].getIdentName() result = node[0].getIdentName()
proc getNameInfo*(nimState: NimState, node: TSNode, kind: NimSymKind, parent = ""): proc getNameInfo*(gState: State, node: TSNode, kind: NimSymKind, parent = ""):
tuple[name, origname: string, info: TLineInfo] = tuple[name, origname: string, info: TLineInfo] =
# Shortcut to get identifier name and info (node value and line:col) # Shortcut to get identifier name and info (node value and line:col)
result.origname = nimState.getNodeVal(node) result.origname = gState.getNodeVal(node)
result.name = nimState.getIdentifier(result.origname, kind, parent) result.name = gState.getIdentifier(result.origname, kind, parent)
if result.name.nBl: if result.name.nBl:
if kind == nskType: if kind == nskType:
result.name = result.name.getType() result.name = result.name.getType()
result.info = nimState.getLineInfo(node) result.info = gState.getLineInfo(node)
proc getCurrentHeader*(fullpath: string): string = proc getCurrentHeader*(fullpath: string): string =
("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")])) ("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")]))
@ -644,7 +641,7 @@ proc getAstChildByName*(ast: ref Ast, name: string): ref Ast =
if ast.children.len == 1 and ast.children[0].name == ".": if ast.children.len == 1 and ast.children[0].name == ".":
return ast.children[0] return ast.children[0]
proc getNimExpression*(nimState: NimState, expr: string, name = ""): string = proc getNimExpression*(gState: State, expr: string, name = ""): string =
# Convert C/C++ expression into Nim - cast identifiers to `name` if specified # Convert C/C++ expression into Nim - cast identifiers to `name` if specified
var var
clean = expr.multiReplace([("\n", " "), ("\r", "")]) clean = expr.multiReplace([("\n", " "), ("\r", "")])
@ -691,8 +688,8 @@ proc getNimExpression*(nimState: NimState, expr: string, name = ""): string =
if ident.nBl: if ident.nBl:
# Issue #178 # Issue #178
if ident != "_": if ident != "_":
ident = nimState.getIdentifier(ident, nskConst, name) ident = gState.getIdentifier(ident, nskConst, name)
if name.nBl and ident in nimState.constIdentifiers: if name.nBl and ident in gState.constIdentifiers:
ident = ident & "." & name ident = ident & "." & name
result &= ident result &= ident
ident = "" ident = ""
@ -708,15 +705,15 @@ proc getSplitComma*(joined: seq[string]): seq[string] =
for i in joined: for i in joined:
result = result.concat(i.split(",")) result = result.concat(i.split(","))
template includeHeader*(nimState: NimState): bool = template isIncludeHeader*(gState: State): bool =
nimState.gState.dynlib.Bl and nimState.gState.includeHeader gState.dynlib.Bl and gState.includeHeader
proc getComments*(nimState: NimState, strip = false): string = proc getComments*(gState: State, strip = false): string =
if not nimState.gState.nocomments and nimState.commentStr.nBl: if not gState.nocomments and gState.commentStr.nBl:
result = "\n" & nimState.commentStr result = "\n" & gState.commentStr
if strip: if strip:
result = result.replace("\n ", "\n") result = result.replace("\n ", "\n")
nimState.commentStr = "" gState.commentStr = ""
proc dll*(path: string): string = proc dll*(path: string): string =
let let

View file

@ -49,7 +49,7 @@ type
recursive*: bool recursive*: bool
children*: seq[ref Ast] children*: seq[ref Ast]
when not declared(CIMPORT): when not declared(CIMPORT):
tonim*: proc (ast: ref Ast, node: TSNode, nimState: NimState) tonim*: proc (ast: ref Ast, node: TSNode, gState: State)
regex*: Regex regex*: Regex
AstTable {.used.} = TableRef[string, seq[ref Ast]] AstTable {.used.} = TableRef[string, seq[ref Ast]]
@ -70,7 +70,6 @@ type
outputHandle*: File outputHandle*: File
NimState {.used.} = ref object
# All symbols that have been declared so far indexed by nimName # All symbols that have been declared so far indexed by nimName
identifiers*: TableRef[string, string] identifiers*: TableRef[string, string]
@ -92,8 +91,6 @@ type
# Craeted symbols to generated AST - forward declaration tracking # Craeted symbols to generated AST - forward declaration tracking
identifierNodes*: TableRef[string, PNode] identifierNodes*: TableRef[string, PNode]
gState*: State
currentHeader*, impShort*, sourceFile*: string currentHeader*, impShort*, sourceFile*: string
data*: seq[tuple[name, val: string]] data*: seq[tuple[name, val: string]]
@ -113,8 +110,7 @@ template Bl(s: typed): untyped {.used.} =
(s.len == 0) (s.len == 0)
when not declared(CIMPORT): when not declared(CIMPORT):
export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, nBl, Bl
nBl, Bl
# Redirect output to file when required # Redirect output to file when required
template gecho*(args: string) {.dirty.} = template gecho*(args: string) {.dirty.} =
@ -123,11 +119,6 @@ when not declared(CIMPORT):
else: else:
gState.outputHandle.writeLine(args) gState.outputHandle.writeLine(args)
template necho*(args: string) {.dirty.} =
when not declared(gState):
let gState = nimState.gState
gecho args
template decho*(str: untyped): untyped = template decho*(str: untyped): untyped =
if nimState.gState.debug: if gState.debug:
necho str.getCommented() gecho str.getCommented()

View file

@ -5,7 +5,7 @@ import regex
import "."/[ast, getters, globals, lisp, treesitter/api] import "."/[ast, getters, globals, lisp, treesitter/api]
type type
Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, nimState: NimState) {.nimcall.}]] Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, gState: State) {.nimcall.}]]
proc getPtrType(str: string): string = proc getPtrType(str: string): string =
result = case str: result = case str:
@ -39,26 +39,26 @@ proc initGrammar(): Grammar =
(preproc_arg) (preproc_arg)
) )
""", """,
proc (ast: ref Ast, node: TSNode, nimState: NimState) = proc (ast: ref Ast, node: TSNode, gState: State) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# define X Y" gState.debugStr &= "\n# define X Y"
let let
name = nimState.data[0].val name = gState.data[0].val
nname = nimState.getIdentifier(name, nskConst) nname = gState.getIdentifier(name, nskConst)
val = nimState.data[1].val.getLit() val = gState.data[1].val.getLit()
if not nname.nBl: if not nname.nBl:
let let
override = nimState.getOverride(name, nskConst) override = gState.getOverride(name, nskConst)
if override.nBl: if override.nBl:
nimState.constStr &= &"{nimState.getComments()}\n{override}" gState.constStr &= &"{gState.getComments()}\n{override}"
else: else:
nimState.constStr &= &"{nimState.getComments()}\n # Const '{name}' skipped" gState.constStr &= &"{gState.getComments()}\n # Const '{name}' skipped"
if nimState.gState.debug: if gState.debug:
nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" gState.skipStr &= &"\n{gState.getNodeVal(node)}"
elif val.nBl and nimState.addNewIdentifer(nname): elif val.nBl and gState.addNewIdentifer(nname):
nimState.constStr &= &"{nimState.getComments()}\n {nname}* = {val}" gState.constStr &= &"{gState.getComments()}\n {nname}* = {val}"
)) ))
let let
@ -125,25 +125,25 @@ proc initGrammar(): Grammar =
""" """
template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen: untyped): untyped = template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen: untyped): untyped =
ptyp = nimState.getIdentifier(nimState.data[i].val, nskType, fname).getType() ptyp = gState.getIdentifier(gState.data[i].val, nskType, fname).getType()
pptr = "" pptr = ""
while i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": while i+1 < gState.data.len and gState.data[i+1].name == "pointer_declarator":
pptr &= "ptr " pptr &= "ptr "
i += 1 i += 1
if i+1 < nimState.data.len and nimState.data[i+1].name == "identifier": if i+1 < gState.data.len and gState.data[i+1].name == "identifier":
pname = nimState.getIdentifier(nimState.data[i+1].val, nskParam, fname) pname = gState.getIdentifier(gState.data[i+1].val, nskParam, fname)
i += 2 i += 2
else: else:
pname = "a" & $count pname = "a" & $count
count += 1 count += 1
i += 1 i += 1
if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: if i < gState.data.len and gState.data[i].name in ["identifier", "number_literal"]:
flen = nimState.data[i].val flen = gState.data[i].val
if nimState.data[i].name == "identifier": if gState.data[i].name == "identifier":
flen = nimState.getIdentifier(flen, nskConst, fname) flen = gState.getIdentifier(flen, nskConst, fname)
pout &= &"{pname}: array[{flen}, {getPtrType(pptr&ptyp)}], " pout &= &"{pname}: array[{flen}, {getPtrType(pptr&ptyp)}], "
i += 1 i += 1
@ -172,13 +172,13 @@ proc initGrammar(): Grammar =
{funcGrammar} {funcGrammar}
) )
""", """,
proc (ast: ref Ast, node: TSNode, nimState: NimState) = proc (ast: ref Ast, node: TSNode, gState: State) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# typedef X Y" gState.debugStr &= "\n# typedef X Y"
var var
i = 0 i = 0
typ = nimState.getIdentifier(nimState.data[i].val, nskType, "Parent").getType() typ = gState.getIdentifier(gState.data[i].val, nskType, "Parent").getType()
name = "" name = ""
nname = "" nname = ""
tptr = "" tptr = ""
@ -186,8 +186,8 @@ proc initGrammar(): Grammar =
pragmas: seq[string] = @[] pragmas: seq[string] = @[]
i += 1 i += 1
while i < nimState.data.len and "pointer" in nimState.data[i].name: while i < gState.data.len and "pointer" in gState.data[i].name:
case nimState.data[i].name: case gState.data[i].name:
of "pointer_declarator": of "pointer_declarator":
tptr &= "ptr " tptr &= "ptr "
i += 1 i += 1
@ -195,32 +195,32 @@ proc initGrammar(): Grammar =
aptr &= "ptr " aptr &= "ptr "
i += 1 i += 1
if i < nimState.data.len: if i < gState.data.len:
name = nimState.data[i].val name = gState.data[i].val
nname = nimState.getIdentifier(name, nskType) nname = gState.getIdentifier(name, nskType)
i += 1 i += 1
if nimState.includeHeader(): if gState.isIncludeHeader():
pragmas.add nimState.getImportC(name, nname) pragmas.add gState.getImportC(name, nname)
let let
pragma = nimState.getPragma(pragmas) pragma = gState.getPragma(pragmas)
if not nname.nBl: if not nname.nBl:
let let
override = nimState.getOverride(name, nskType) override = gState.getOverride(name, nskType)
if override.nBl: if override.nBl:
nimState.typeStr &= &"{nimState.getComments()}\n{override}" gState.typeStr &= &"{gState.getComments()}\n{override}"
elif nname notin gTypeMap and typ.nBl and nimState.addNewIdentifer(nname): elif nname notin gTypeMap and typ.nBl and gState.addNewIdentifer(nname):
if i < nimState.data.len and nimState.data[^1].name == "function_declarator": if i < gState.data.len and gState.data[^1].name == "function_declarator":
var var
fname = nname fname = nname
pout, pname, ptyp, pptr = "" pout, pname, ptyp, pptr = ""
count = 1 count = 1
flen = "" flen = ""
while i < nimState.data.len: while i < gState.data.len:
if nimState.data[i].name == "function_declarator": if gState.data[i].name == "function_declarator":
break break
funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen)
@ -229,34 +229,34 @@ proc initGrammar(): Grammar =
pout = pout[0 .. ^3] pout = pout[0 .. ^3]
if tptr.nBl or typ != "object": if tptr.nBl or typ != "object":
nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}" gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}"
else: else:
nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}" gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}"
else: else:
if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: if i < gState.data.len and gState.data[i].name in ["identifier", "number_literal"]:
var var
flen = nimState.data[i].val flen = gState.data[i].val
if nimState.data[i].name == "identifier": if gState.data[i].name == "identifier":
flen = nimState.getIdentifier(flen, nskConst, nname) flen = gState.getIdentifier(flen, nskConst, nname)
nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]"
else: else:
if nname == typ: if nname == typ:
pragmas.add "incompleteStruct" pragmas.add "incompleteStruct"
let let
pragma = nimState.getPragma(pragmas) pragma = gState.getPragma(pragmas)
nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object" gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = object"
else: else:
nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = {getPtrType(tptr&typ)}" gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = {getPtrType(tptr&typ)}"
)) ))
proc pDupTypeCommon(nname: string, fend: int, nimState: NimState, isEnum=false) = proc pDupTypeCommon(nname: string, fend: int, gState: State, isEnum=false) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# pDupTypeCommon()" gState.debugStr &= "\n# pDupTypeCommon()"
var var
dname = nimState.data[^1].val dname = gState.data[^1].val
ndname = nimState.getIdentifier(dname, nskType) ndname = gState.getIdentifier(dname, nskType)
dptr = dptr =
if fend == 2: if fend == 2:
"ptr " "ptr "
@ -265,21 +265,21 @@ proc initGrammar(): Grammar =
if ndname.nBl and ndname != nname: if ndname.nBl and ndname != nname:
if isEnum: if isEnum:
if nimState.addNewIdentifer(ndname): if gState.addNewIdentifer(ndname):
nimState.enumStr &= &"{nimState.getComments(true)}\ntype {ndname}* = {dptr}{nname}" gState.enumStr &= &"{gState.getComments(true)}\ntype {ndname}* = {dptr}{nname}"
else: else:
if nimState.addNewIdentifer(ndname): if gState.addNewIdentifer(ndname):
let let
pragma = nimState.getPragma(nimState.getImportc(dname, ndname), "bycopy") pragma = gState.getPragma(gState.getImportc(dname, ndname), "bycopy")
nimState.typeStr &= gState.typeStr &=
&"{nimState.getComments()}\n {ndname}*{pragma} = {dptr}{nname}" &"{gState.getComments()}\n {ndname}*{pragma} = {dptr}{nname}"
proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, gState: State) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# pStructCommon" gState.debugStr &= "\n# pStructCommon"
var var
nname = nimState.getIdentifier(name, nskType) nname = gState.getIdentifier(name, nskType)
prefix = "" prefix = ""
union = "" union = ""
@ -307,25 +307,25 @@ proc initGrammar(): Grammar =
if not nname.nBl: if not nname.nBl:
let let
override = nimState.getOverride(name, nskType) override = gState.getOverride(name, nskType)
if override.nBl: if override.nBl:
nimState.typeStr &= &"{nimState.getComments()}\n{override}" gState.typeStr &= &"{gState.getComments()}\n{override}"
elif nimState.addNewIdentifer(nname): elif gState.addNewIdentifer(nname):
if nimState.data.len == 1: if gState.data.len == 1:
nimState.typeStr &= &"{nimState.getComments()}\n {nname}* {{.bycopy{union}.}} = object" gState.typeStr &= &"{gState.getComments()}\n {nname}* {{.bycopy{union}.}} = object"
else: else:
var var
pragmas: seq[string] = @[] pragmas: seq[string] = @[]
if nimState.includeHeader(): if gState.isIncludeHeader():
pragmas.add nimState.getImportC(prefix & name, nname) pragmas.add gState.getImportC(prefix & name, nname)
pragmas.add "bycopy" pragmas.add "bycopy"
if union.nBl: if union.nBl:
pragmas.add "union" pragmas.add "union"
let let
pragma = nimState.getPragma(pragmas) pragma = gState.getPragma(pragmas)
nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object" gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = object"
var var
i = fstart i = fstart
@ -333,19 +333,19 @@ proc initGrammar(): Grammar =
fptr = "" fptr = ""
aptr = "" aptr = ""
flen = "" flen = ""
while i < nimState.data.len-fend: while i < gState.data.len-fend:
fptr = "" fptr = ""
aptr = "" aptr = ""
if nimState.data[i].name == "field_declaration": if gState.data[i].name == "field_declaration":
i += 1 i += 1
continue continue
if nimState.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]: if gState.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]:
ftyp = nimState.getIdentifier(nimState.data[i].val, nskType, nname).getType() ftyp = gState.getIdentifier(gState.data[i].val, nskType, nname).getType()
i += 1 i += 1
while i < nimState.data.len-fend and "pointer" in nimState.data[i].name: while i < gState.data.len-fend and "pointer" in gState.data[i].name:
case nimState.data[i].name: case gState.data[i].name:
of "pointer_declarator": of "pointer_declarator":
fptr &= "ptr " fptr &= "ptr "
i += 1 i += 1
@ -353,33 +353,33 @@ proc initGrammar(): Grammar =
aptr &= "ptr " aptr &= "ptr "
i += 1 i += 1
fname = nimState.getIdentifier(nimState.data[i].val, nskField, nname) fname = gState.getIdentifier(gState.data[i].val, nskField, nname)
if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: if i+1 < gState.data.len-fend and gState.data[i+1].name in gEnumVals:
# Struct field is an array where size is an expression # Struct field is an array where size is an expression
var var
flen = nimState.getNimExpression(nimState.data[i+1].val) flen = gState.getNimExpression(gState.data[i+1].val)
if "/" in flen: if "/" in flen:
flen = &"({flen}).int" flen = &"({flen}).int"
nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" gState.typeStr &= &"{gState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]"
i += 2 i += 2
elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "bitfield_clause": elif i+1 < gState.data.len-fend and gState.data[i+1].name == "bitfield_clause":
let let
size = nimState.data[i+1].val size = gState.data[i+1].val
nimState.typeStr &= &"{nimState.getComments()}\n {fname}* {{.bitsize: {size}.}} : {getPtrType(fptr&ftyp)} " gState.typeStr &= &"{gState.getComments()}\n {fname}* {{.bitsize: {size}.}} : {getPtrType(fptr&ftyp)} "
i += 2 i += 2
elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "function_declarator": elif i+1 < gState.data.len-fend and gState.data[i+1].name == "function_declarator":
var var
pout, pname, ptyp, pptr = "" pout, pname, ptyp, pptr = ""
count = 1 count = 1
i += 2 i += 2
while i < nimState.data.len-fend: while i < gState.data.len-fend:
if nimState.data[i].name == "function_declarator": if gState.data[i].name == "function_declarator":
i += 1 i += 1
continue continue
if nimState.data[i].name == "field_declaration": if gState.data[i].name == "field_declaration":
break break
funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen)
@ -387,20 +387,20 @@ proc initGrammar(): Grammar =
if pout.nBl and pout[^2 .. ^1] == ", ": if pout.nBl and pout[^2 .. ^1] == ", ":
pout = pout[0 .. ^3] pout = pout[0 .. ^3]
if fptr.nBl or ftyp != "object": if fptr.nBl or ftyp != "object":
nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}" gState.typeStr &= &"{gState.getComments()}\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}"
else: else:
nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}) {{.cdecl.}}" gState.typeStr &= &"{gState.getComments()}\n {fname}*: proc({pout}) {{.cdecl.}}"
i += 1 i += 1
else: else:
if ftyp == "object": if ftyp == "object":
nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: pointer" gState.typeStr &= &"{gState.getComments()}\n {fname}*: pointer"
else: else:
nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: {getPtrType(fptr&ftyp)}" gState.typeStr &= &"{gState.getComments()}\n {fname}*: {getPtrType(fptr&ftyp)}"
i += 1 i += 1
if node.tsNodeType() == "type_definition" and if node.tsNodeType() == "type_definition" and
nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.nBl: gState.data[^1].name == "type_identifier" and gState.data[^1].val.nBl:
pDupTypeCommon(nname, fend, nimState, false) pDupTypeCommon(nname, fend, gState, false)
let let
fieldGrammar = &""" fieldGrammar = &"""
@ -451,11 +451,11 @@ proc initGrammar(): Grammar =
{fieldListGrammar} {fieldListGrammar}
) )
""", """,
proc (ast: ref Ast, node: TSNode, nimState: NimState) = proc (ast: ref Ast, node: TSNode, gState: State) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# struct X {}" gState.debugStr &= "\n# struct X {}"
pStructCommon(ast, node, nimState.data[0].val, 1, 1, nimState) pStructCommon(ast, node, gState.data[0].val, 1, 1, gState)
)) ))
# typedef struct X {} # typedef struct X {}
@ -474,69 +474,69 @@ proc initGrammar(): Grammar =
) )
) )
""", """,
proc (ast: ref Ast, node: TSNode, nimState: NimState) = proc (ast: ref Ast, node: TSNode, gState: State) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# typedef struct X {}" gState.debugStr &= "\n# typedef struct X {}"
var var
fstart = 0 fstart = 0
fend = 1 fend = 1
if nimState.data[^2].name == "pointer_declarator": if gState.data[^2].name == "pointer_declarator":
fend = 2 fend = 2
if nimState.data.len > 1 and if gState.data.len > 1 and
nimState.data[0].name == "type_identifier" and gState.data[0].name == "type_identifier" and
nimState.data[1].name notin ["field_identifier", "pointer_declarator"]: gState.data[1].name notin ["field_identifier", "pointer_declarator"]:
fstart = 1 fstart = 1
pStructCommon(ast, node, nimState.data[0].val, fstart, fend, nimState) pStructCommon(ast, node, gState.data[0].val, fstart, fend, gState)
else: else:
pStructCommon(ast, node, nimState.data[^1].val, fstart, fend, nimState) pStructCommon(ast, node, gState.data[^1].val, fstart, fend, gState)
)) ))
proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, gState: State) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# pEnumCommon()" gState.debugStr &= "\n# pEnumCommon()"
let nname = let nname =
if name.Bl: if name.Bl:
getUniqueIdentifier(nimState, "Enum") getUniqueIdentifier(gState, "Enum")
else: else:
nimState.getIdentifier(name, nskType) gState.getIdentifier(name, nskType)
if nname.nBl and nimState.addNewIdentifer(nname): if nname.nBl and gState.addNewIdentifer(nname):
nimState.enumStr &= &"{nimState.getComments(true)}\ndefineEnum({nname})" gState.enumStr &= &"{gState.getComments(true)}\ndefineEnum({nname})"
var var
i = fstart i = fstart
count = 0 count = 0
while i < nimState.data.len-fend: while i < gState.data.len-fend:
if nimState.data[i].name == "enumerator": if gState.data[i].name == "enumerator":
i += 1 i += 1
continue continue
let let
fname = nimState.getIdentifier(nimState.data[i].val, nskEnumField) fname = gState.getIdentifier(gState.data[i].val, nskEnumField)
if i+1 < nimState.data.len-fend and if i+1 < gState.data.len-fend and
nimState.data[i+1].name in gEnumVals: gState.data[i+1].name in gEnumVals:
if fname.nBl and nimState.addNewIdentifer(fname): if fname.nBl and gState.addNewIdentifer(fname):
nimState.constStr &= &"{nimState.getComments()}\n {fname}* = ({nimState.getNimExpression(nimState.data[i+1].val)}).{nname}" gState.constStr &= &"{gState.getComments()}\n {fname}* = ({gState.getNimExpression(gState.data[i+1].val)}).{nname}"
try: try:
count = nimState.data[i+1].val.parseInt() + 1 count = gState.data[i+1].val.parseInt() + 1
except: except:
count += 1 count += 1
i += 2 i += 2
else: else:
if fname.nBl and nimState.addNewIdentifer(fname): if fname.nBl and gState.addNewIdentifer(fname):
nimState.constStr &= &"{nimState.getComments()}\n {fname}* = {count}.{nname}" gState.constStr &= &"{gState.getComments()}\n {fname}* = {count}.{nname}"
i += 1 i += 1
count += 1 count += 1
if node.tsNodeType() == "type_definition" and if node.tsNodeType() == "type_definition" and
nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.nBl: gState.data[^1].name == "type_identifier" and gState.data[^1].val.nBl:
pDupTypeCommon(nname, fend, nimState, true) pDupTypeCommon(nname, fend, gState, true)
# enum X {} # enum X {}
result.add((""" result.add(("""
@ -550,19 +550,19 @@ proc initGrammar(): Grammar =
) )
) )
""" % gEnumVals.join("|"), """ % gEnumVals.join("|"),
proc (ast: ref Ast, node: TSNode, nimState: NimState) = proc (ast: ref Ast, node: TSNode, gState: State) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# enum X {}" gState.debugStr &= "\n# enum X {}"
var var
name = "" name = ""
offset = 0 offset = 0
if nimState.data[0].name == "type_identifier": if gState.data[0].name == "type_identifier":
name = nimState.data[0].val name = gState.data[0].val
offset = 1 offset = 1
pEnumCommon(ast, node, name, offset, 0, nimState) pEnumCommon(ast, node, name, offset, 0, gState)
)) ))
# typedef enum {} X # typedef enum {} X
@ -578,23 +578,23 @@ proc initGrammar(): Grammar =
) )
) )
""", """,
proc (ast: ref Ast, node: TSNode, nimState: NimState) = proc (ast: ref Ast, node: TSNode, gState: State) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# typedef enum {}" gState.debugStr &= "\n# typedef enum {}"
var var
fstart = 0 fstart = 0
fend = 1 fend = 1
if nimState.data[^2].name == "pointer_declarator": if gState.data[^2].name == "pointer_declarator":
fend = 2 fend = 2
if nimState.data[0].name == "type_identifier": if gState.data[0].name == "type_identifier":
fstart = 1 fstart = 1
pEnumCommon(ast, node, nimState.data[0].val, fstart, fend, nimState) pEnumCommon(ast, node, gState.data[0].val, fstart, fend, gState)
else: else:
pEnumCommon(ast, node, nimState.data[^1].val, fstart, fend, nimState) pEnumCommon(ast, node, gState.data[^1].val, fstart, fend, gState)
)) ))
# typ function(typ param1, ...) # typ function(typ param1, ...)
@ -611,39 +611,39 @@ proc initGrammar(): Grammar =
{funcGrammar} {funcGrammar}
) )
""", """,
proc (ast: ref Ast, node: TSNode, nimState: NimState) = proc (ast: ref Ast, node: TSNode, gState: State) =
if nimState.gState.debug: if gState.debug:
nimState.debugStr &= "\n# typ function" gState.debugStr &= "\n# typ function"
var var
fptr = "" fptr = ""
i = 1 i = 1
while i < nimState.data.len: while i < gState.data.len:
if nimState.data[i].name == "function_declarator": if gState.data[i].name == "function_declarator":
i += 1 i += 1
continue continue
fptr = "" fptr = ""
while i < nimState.data.len and nimState.data[i].name == "pointer_declarator": while i < gState.data.len and gState.data[i].name == "pointer_declarator":
fptr &= "ptr " fptr &= "ptr "
i += 1 i += 1
var var
fname = nimState.data[i].val fname = gState.data[i].val
fnname = nimState.getIdentifier(fname, nskProc) fnname = gState.getIdentifier(fname, nskProc)
pout, pname, ptyp, pptr = "" pout, pname, ptyp, pptr = ""
count = 1 count = 1
flen = "" flen = ""
fVar = false fVar = false
i += 1 i += 1
if i < nimState.data.len and nimState.data[i].name == "pointer_declarator": if i < gState.data.len and gState.data[i].name == "pointer_declarator":
fVar = true fVar = true
i += 1 i += 1
while i < nimState.data.len: while i < gState.data.len:
if nimState.data[i].name == "function_declarator": if gState.data[i].name == "function_declarator":
break break
funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i, flen) funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i, flen)
@ -653,24 +653,24 @@ proc initGrammar(): Grammar =
if not fnname.nBl: if not fnname.nBl:
let let
override = nimState.getOverride(fname, nskProc) override = gState.getOverride(fname, nskProc)
if override.nBl: if override.nBl:
nimState.typeStr &= &"{nimState.getComments()}\n{override}" gState.typeStr &= &"{gState.getComments()}\n{override}"
elif nimState.addNewIdentifer(fnname): elif gState.addNewIdentifer(fnname):
let let
ftyp = nimState.getIdentifier(nimState.data[0].val, nskType, fnname).getType() ftyp = gState.getIdentifier(gState.data[0].val, nskType, fnname).getType()
pragma = nimState.getPragma(nimState.getImportC(fname, fnname), "cdecl") pragma = gState.getPragma(gState.getImportC(fname, fnname), "cdecl")
if fptr.nBl or ftyp != "object": if fptr.nBl or ftyp != "object":
if fVar: if fVar:
nimState.procStr &= &"{nimState.getComments(true)}\nvar {fnname}*: proc ({pout}): {getPtrType(fptr&ftyp)}{{.cdecl.}}" gState.procStr &= &"{gState.getComments(true)}\nvar {fnname}*: proc ({pout}): {getPtrType(fptr&ftyp)}{{.cdecl.}}"
else: else:
nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" gState.procStr &= &"{gState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}"
else: else:
if fVar: if fVar:
nimState.procStr &= &"{nimState.getComments(true)}\nvar {fnname}*: proc ({pout}){{.cdecl.}}" gState.procStr &= &"{gState.getComments(true)}\nvar {fnname}*: proc ({pout}){{.cdecl.}}"
else: else:
nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}){pragma}" gState.procStr &= &"{gState.getComments(true)}\nproc {fnname}*({pout}){pragma}"
)) ))
# // comment # // comment
@ -678,15 +678,15 @@ proc initGrammar(): Grammar =
(comment (comment
) )
""", """,
proc (ast: ref Ast, node: TSNode, nimState: NimState) = proc (ast: ref Ast, node: TSNode, gState: State) =
let let
cmt = $nimState.getNodeVal(node) cmt = $gState.getNodeVal(node)
for line in cmt.splitLines(): for line in cmt.splitLines():
let let
line = line.multiReplace([("//", ""), ("/*", ""), ("*/", "")]) line = line.multiReplace([("//", ""), ("/*", ""), ("*/", "")])
nimState.commentStr &= &"\n # {line.strip(leading=false)}" gState.commentStr &= &"\n # {line.strip(leading=false)}"
)) ))
# // unknown # // unknown
@ -695,37 +695,37 @@ proc initGrammar(): Grammar =
(^.*) (^.*)
) )
""", """,
proc (ast: ref Ast, node: TSNode, nimState: NimState) = proc (ast: ref Ast, node: TSNode, gState: State) =
var var
done = false done = false
for i in nimState.data: for i in gState.data:
case $node.tsNodeType() case $node.tsNodeType()
of "declaration": of "declaration":
if i.name == "identifier": if i.name == "identifier":
let let
override = nimState.getOverride(i.val, nskProc) override = gState.getOverride(i.val, nskProc)
if override.nBl: if override.nBl:
nimState.procStr &= &"{nimState.getComments(true)}\n{override}" gState.procStr &= &"{gState.getComments(true)}\n{override}"
done = true done = true
break break
else: else:
nimState.procStr &= &"{nimState.getComments(true)}\n# Declaration '{i.val}' skipped" gState.procStr &= &"{gState.getComments(true)}\n# Declaration '{i.val}' skipped"
else: else:
if i.name == "type_identifier": if i.name == "type_identifier":
let let
override = nimState.getOverride(i.val, nskType) override = gState.getOverride(i.val, nskType)
if override.nBl: if override.nBl:
nimState.typeStr &= &"{nimState.getComments()}\n{override}" gState.typeStr &= &"{gState.getComments()}\n{override}"
done = true done = true
break break
else: else:
nimState.typeStr &= &"{nimState.getComments()}\n # Type '{i.val}' skipped" gState.typeStr &= &"{gState.getComments()}\n # Type '{i.val}' skipped"
if nimState.gState.debug and not done: if gState.debug and not done:
nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" gState.skipStr &= &"\n{gState.getNodeVal(node)}"
)) ))
proc initRegex(ast: ref Ast) = proc initRegex(ast: ref Ast) =