aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2019-01-11 19:36:38 -0600
committerGanesh Viswanathan <dev@genotrance.com>2019-01-11 19:36:38 -0600
commita1d920bc6ab1b9b398dac9b8cf3b02c226cb2512 (patch)
treec7e77db7d4586f35978c046e9cc2088a1c943bda
parentbc282938125fbb60ce04338d9d276cca18dd2aaa (diff)
downloadnimterop-a1d920bc6ab1b9b398dac9b8cf3b02c226cb2512.tar.gz
nimterop-a1d920bc6ab1b9b398dac9b8cf3b02c226cb2512.zip
orWithNext, pointer cleanup
-rw-r--r--nimterop/ast.nim7
-rw-r--r--nimterop/getters.nim11
-rw-r--r--nimterop/globals.nim1
-rw-r--r--nimterop/grammar.nim111
4 files changed, 84 insertions, 46 deletions
diff --git a/nimterop/ast.nim b/nimterop/ast.nim
index df3f626..35817a2 100644
--- a/nimterop/ast.nim
+++ b/nimterop/ast.nim
@@ -36,12 +36,7 @@ proc saveNodeData(node: TSNode): bool =
if node.tsNodePrevNamedSibling().tsNodeIsNull() and
((node.isPName("pointer_declarator") and not node.isPPName("function_declarator")) or
(node.getPName() in ["function_declarator", "array_declarator"] and node.isPPName("pointer_declarator"))):
- if gStateRT.data[^1].val != "object":
- gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier()
- if gStateRT.data[^1].val == "ptr char":
- gStateRT.data[^1].val = "cstring"
- else:
- gStateRT.data[^1].val = "pointer"
+ gStateRT.data.add(("pointer_declarator", ""))
gStateRT.data.add((name, val))
diff --git a/nimterop/getters.nim b/nimterop/getters.nim
index 77243f6..19d32ea 100644
--- a/nimterop/getters.nim
+++ b/nimterop/getters.nim
@@ -185,6 +185,8 @@ converter toString*(kind: Kind): string =
"*"
of zeroOrOne:
"?"
+ of orWithNext:
+ "!"
converter toKind*(kind: string): Kind =
return case kind:
@@ -194,6 +196,8 @@ converter toKind*(kind: string): Kind =
zeroOrMore
of "?":
zeroOrOne
+ of "!":
+ orWithNext
else:
exactlyOne
@@ -223,7 +227,12 @@ proc getRegexForAstChildren*(ast: ref Ast): string =
result = "^"
for i in 0 .. ast.children.len-1:
let kind: string = ast.children[i].kind
- result &= &"(?:{ast.children[i].name}){kind}"
+ let begin = if result[^1] == '|': "" else: "(?:"
+ case kind:
+ of "!":
+ result &= &"{begin}{ast.children[i].name}|"
+ else:
+ result &= &"{begin}{ast.children[i].name}){kind}"
result &= "$"
proc getAstChildByName*(ast: ref Ast, name: string): ref Ast =
diff --git a/nimterop/globals.nim b/nimterop/globals.nim
index 7b2375c..e5bb6ac 100644
--- a/nimterop/globals.nim
+++ b/nimterop/globals.nim
@@ -10,6 +10,7 @@ type
oneOrMore # +
zeroOrMore # *
zeroOrOne # ?
+ orWithNext # !
Ast* = object
name*: string
diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim
index 13fab13..8210cd3 100644
--- a/nimterop/grammar.nim
+++ b/nimterop/grammar.nim
@@ -50,18 +50,35 @@ proc initGrammar() =
""",
proc (ast: ref Ast, node: TSNode) =
var
- name = gStateRT.data[1].val.getIdentifier()
- typ = gStateRT.data[0].val.getIdentifier()
+ i = 0
+ typ = gStateRT.data[i].val.getIdentifier()
+ name = ""
+ tptr = ""
+
+ i += 1
+ if i < gStateRT.data.len:
+ if gStateRT.data[i].name == "pointer_declarator":
+ tptr = "ptr "
+ i += 1
+
+ name = gStateRT.data[i].val.getIdentifier()
if name notin gStateRT.types:
gStateRT.types.add(name)
- if name == typ:
- typ = "object"
- gStateRT.typeStr &= &" {name}* = {typ}\n"
+ if name == typ or typ == "object":
+ gStateRT.typeStr &= &" {name}* = object\n"
+ else:
+ gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n"
))
- template funcParamCommon(pname, ptyp, pout, count, i: untyped): untyped =
+ template funcParamCommon(pname, ptyp, pptr, pout, count, i: untyped): untyped =
ptyp = gStateRT.data[i].val.getIdentifier()
+ if i+1 < gStateRT.data.len and gStateRT.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()
i += 2
@@ -70,7 +87,7 @@ proc initGrammar() =
count += 1
i += 1
if ptyp != "object":
- pout &= &"{pname}: {ptyp},"
+ pout &= &"{pname}: {pptr}{ptyp},"
proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) =
var
@@ -100,25 +117,34 @@ proc initGrammar() =
var
i = fstart
+ ftyp, fname: string
+ fptr = ""
while i < gStateRT.data.len-fend:
+ fptr = ""
if gStateRT.data[i].name == "field_declaration":
i += 1
continue
- let
+ if gStateRT.data[i].name notin ["field_identifier", "pointer_declarator"]:
ftyp = gStateRT.data[i].val.getIdentifier()
- fname = gStateRT.data[i+1].val.getIdentifier()
- if i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name in ["identifier", "number_literal"]:
+ i += 1
+
+ if gStateRT.data[i].name == "pointer_declarator":
+ fptr = "ptr "
+ i += 1
+
+ fname = gStateRT.data[i].val.getIdentifier()
+ if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["identifier", "number_literal"]:
let
- flen = gStateRT.data[i+2].val.getIdentifier()
- gStateRT.typeStr &= &" {fname}*: array[{flen}, {ftyp}]\n"
- i += 3
- elif i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name == "function_declarator":
+ flen = gStateRT.data[i+1].val.getIdentifier()
+ gStateRT.typeStr &= &" {fname}*: array[{flen}, {fptr}{ftyp}]\n"
+ i += 2
+ elif i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "function_declarator":
var
- pout, pname, ptyp = ""
+ pout, pname, ptyp, pptr = ""
count = 1
- i += 3
+ i += 2
while i < gStateRT.data.len-fend:
if gStateRT.data[i].name == "function_declarator":
i += 1
@@ -127,18 +153,18 @@ proc initGrammar() =
if gStateRT.data[i].name == "field_declaration":
break
- funcParamCommon(pname, ptyp, pout, count, i)
+ funcParamCommon(pname, ptyp, pptr, pout, count, i)
if pout.len != 0 and pout[^1] == ',':
pout = pout[0 .. ^2]
if ftyp != "object":
- gStateRT.typeStr &= &" {fname}*: proc({pout}): {ftyp} {{.nimcall.}}\n"
+ gStateRT.typeStr &= &" {fname}*: proc({pout}): {fptr}{ftyp} {{.nimcall.}}\n"
else:
gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n"
- i += 1
+ i += 1
else:
- gStateRT.typeStr &= &" {fname}*: {ftyp}\n"
- i += 2
+ gStateRT.typeStr &= &" {fname}*: {fptr}{ftyp}\n"
+ i += 1
let
paramListGrammar = &"""
@@ -155,12 +181,12 @@ proc initGrammar() =
"""
fieldGrammar = &"""
- (field_identifier?)
- (array_declarator?
+ (field_identifier!)
+ (array_declarator!
(field_identifier)
(identifier|number_literal)
)
- (function_declarator?
+ (function_declarator+
(pointer_declarator
(field_identifier)
)
@@ -172,10 +198,10 @@ proc initGrammar() =
(field_declaration_list
(field_declaration+
{typeGrammar}
- {fieldGrammar}
- (pointer_declarator?
+ (pointer_declarator!
{fieldGrammar}
)
+ {fieldGrammar}
)
)
"""
@@ -295,7 +321,7 @@ proc initGrammar() =
))
let funcGrammar = &"""
- (function_declarator*
+ (function_declarator+
(identifier)
{paramListGrammar}
)
@@ -306,31 +332,31 @@ proc initGrammar() =
(declaration
(storage_class_specifier?)
{typeGrammar}
- {funcGrammar}
- (pointer_declarator*
+ (pointer_declarator!
{funcGrammar}
)
{funcGrammar}
- (pointer_declarator*
- {funcGrammar}
- )
)
""",
proc (ast: ref Ast, node: TSNode) =
- let
- ftyp = gStateRT.data[0].val.getIdentifier()
-
var
+ ftyp = gStateRT.data[0].val.getIdentifier()
+ fptr = ""
i = 1
+
while i < gStateRT.data.len:
if gStateRT.data[i].name == "function_declarator":
i += 1
continue
+ if gStateRT.data[i].name == "pointer_declarator":
+ fptr = "ptr "
+ i += 1
+
var
fname = gStateRT.data[i].val
fnname = fname.getIdentifier()
- pout, pname, ptyp = ""
+ pout, pname, ptyp, pptr = ""
count = 1
i += 1
@@ -338,7 +364,7 @@ proc initGrammar() =
if gStateRT.data[i].name == "function_declarator":
break
- funcParamCommon(pname, ptyp, pout, count, i)
+ funcParamCommon(pname, ptyp, pptr, pout, count, i)
if pout.len != 0 and pout[^1] == ',':
pout = pout[0 .. ^2]
@@ -346,7 +372,7 @@ proc initGrammar() =
if fnname notin gStateRT.procs:
gStateRT.procs.add(fnname)
if ftyp != "object":
- gStateRT.procStr &= &"proc {fnname}*({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n"
+ gStateRT.procStr &= &"proc {fnname}*({pout}): {fptr}{ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n"
else:
gStateRT.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n"
@@ -357,7 +383,14 @@ proc initRegex(ast: ref Ast) =
for child in ast.children:
child.initRegex()
- ast.regex = ast.getRegexForAstChildren().re()
+ var
+ reg: string
+ try:
+ reg = ast.getRegexForAstChildren()
+ ast.regex = reg.re()
+ except:
+ echo reg
+ raise newException(Exception, getCurrentExceptionMsg())
proc parseGrammar*() =
initGrammar()