aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2019-01-11 22:14:05 -0600
committerGanesh Viswanathan <dev@genotrance.com>2019-01-11 22:14:05 -0600
commit8c644e814ca676ce2e126bc85497eba7877cc94f (patch)
tree3276671e441fb2179ea003ff489ca08c59c889f9
parenta1d920bc6ab1b9b398dac9b8cf3b02c226cb2512 (diff)
downloadnimterop-8c644e814ca676ce2e126bc85497eba7877cc94f.tar.gz
nimterop-8c644e814ca676ce2e126bc85497eba7877cc94f.zip
Cleanup abstract pointers, typedef function support
-rw-r--r--nimterop/ast.nim4
-rw-r--r--nimterop/grammar.nim134
2 files changed, 81 insertions, 57 deletions
diff --git a/nimterop/ast.nim b/nimterop/ast.nim
index 35817a2..73c602c 100644
--- a/nimterop/ast.nim
+++ b/nimterop/ast.nim
@@ -44,9 +44,7 @@ proc saveNodeData(node: TSNode): bool =
gStateRT.data.add(("function_declarator", ""))
elif name in ["abstract_pointer_declarator"]:
- gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier()
- if gStateRT.data[^1].val == "ptr char":
- gStateRT.data[^1].val = "cstring"
+ gStateRT.data.add(("pointer_declarator", ""))
elif name in ["field_declaration", "function_declarator"]:
gStateRT.data.add((name, ""))
diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim
index 8210cd3..7b12477 100644
--- a/nimterop/grammar.nim
+++ b/nimterop/grammar.nim
@@ -24,16 +24,55 @@ proc initGrammar() =
gStateRT.constStr &= &" {name}* = {val}\n"
))
- let typeGrammar = """
- (type_qualifier?)
- (primitive_type|type_identifier?)
- (sized_type_specifier?
- (primitive_type?)
- )
- (struct_specifier|union_specifier|enum_specifier?
- (type_identifier)
- )
- """
+ let
+ typeGrammar = """
+ (type_qualifier?)
+ (primitive_type|type_identifier?)
+ (sized_type_specifier?
+ (primitive_type?)
+ )
+ (struct_specifier|union_specifier|enum_specifier?
+ (type_identifier)
+ )
+ """
+
+ paramListGrammar = &"""
+ (parameter_list
+ (parameter_declaration*
+ {typeGrammar}
+ (identifier|type_identifier?)
+ (pointer_declarator?
+ (identifier|type_identifier)
+ )
+ (abstract_pointer_declarator?)
+ )
+ )
+ """
+
+ funcGrammar = &"""
+ (function_declarator*
+ (identifier|type_identifier)
+ {paramListGrammar}
+ )
+ """
+
+ 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
+ else:
+ pname = "a" & $count
+ count += 1
+ i += 1
+ if ptyp != "object":
+ pout &= &"{pname}: {pptr}{ptyp},"
# typedef int X
# typedef X Y
@@ -44,8 +83,10 @@ proc initGrammar() =
{typeGrammar}
(type_identifier?)
(pointer_declarator?
- (type_identifier)
+ (type_identifier!)
+ {funcGrammar}
)
+ {funcGrammar}
)
""",
proc (ast: ref Ast, node: TSNode) =
@@ -61,33 +102,35 @@ proc initGrammar() =
tptr = "ptr "
i += 1
+ if i < gStateRT.data.len:
name = gStateRT.data[i].val.getIdentifier()
+ i += 1
if name notin gStateRT.types:
- gStateRT.types.add(name)
- if name == typ or typ == "object":
- gStateRT.typeStr &= &" {name}* = object\n"
- else:
- gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n"
- ))
+ if i < gStateRT.data.len and gStateRT.data[^1].name == "function_declarator":
+ var
+ pout, pname, ptyp, pptr = ""
+ count = 1
- 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 = ""
+ while i < gStateRT.data.len:
+ if gStateRT.data[i].name == "function_declarator":
+ break
- if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "identifier":
- pname = gStateRT.data[i+1].val.getIdentifier()
- i += 2
- else:
- pname = "a" & $count
- count += 1
- i += 1
- if ptyp != "object":
- pout &= &"{pname}: {pptr}{ptyp},"
+ funcParamCommon(pname, ptyp, pptr, pout, count, i)
+
+ if pout.len != 0 and pout[^1] == ',':
+ pout = pout[0 .. ^2]
+ if typ != "object":
+ gStateRT.typeStr &= &" {name}* = proc({pout}): {tptr}{typ} {{.nimcall.}}\n"
+ else:
+ gStateRT.typeStr &= &" {name}*: proc({pout}) {{.nimcall.}}\n"
+ else:
+ gStateRT.types.add(name)
+ if name == typ or typ == "object":
+ gStateRT.typeStr &= &" {name}* = object\n"
+ else:
+ gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n"
+ ))
proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) =
var
@@ -163,23 +206,13 @@ proc initGrammar() =
gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n"
i += 1
else:
- gStateRT.typeStr &= &" {fname}*: {fptr}{ftyp}\n"
+ if ftyp == "object":
+ gStateRT.typeStr &= &" {fname}*: pointer\n"
+ else:
+ gStateRT.typeStr &= &" {fname}*: {fptr}{ftyp}\n"
i += 1
let
- paramListGrammar = &"""
- (parameter_list
- (parameter_declaration*
- {typeGrammar}
- (identifier?)
- (pointer_declarator?
- (identifier)
- )
- (abstract_pointer_declarator?)
- )
- )
- """
-
fieldGrammar = &"""
(field_identifier!)
(array_declarator!
@@ -320,13 +353,6 @@ proc initGrammar() =
pEnumCommon(ast, node, gStateRT.data[^1].val, offset, 1)
))
- let funcGrammar = &"""
- (function_declarator+
- (identifier)
- {paramListGrammar}
- )
- """
-
# typ function(typ param1, ...)
gStateRT.grammar.add((&"""
(declaration