orWithNext, pointer cleanup
This commit is contained in:
parent
bc28293812
commit
a1d920bc6a
4 changed files with 84 additions and 46 deletions
|
|
@ -36,12 +36,7 @@ proc saveNodeData(node: TSNode): bool =
|
||||||
if node.tsNodePrevNamedSibling().tsNodeIsNull() and
|
if node.tsNodePrevNamedSibling().tsNodeIsNull() and
|
||||||
((node.isPName("pointer_declarator") and not node.isPPName("function_declarator")) or
|
((node.isPName("pointer_declarator") and not node.isPPName("function_declarator")) or
|
||||||
(node.getPName() in ["function_declarator", "array_declarator"] and node.isPPName("pointer_declarator"))):
|
(node.getPName() in ["function_declarator", "array_declarator"] and node.isPPName("pointer_declarator"))):
|
||||||
if gStateRT.data[^1].val != "object":
|
gStateRT.data.add(("pointer_declarator", ""))
|
||||||
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((name, val))
|
gStateRT.data.add((name, val))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,8 @@ converter toString*(kind: Kind): string =
|
||||||
"*"
|
"*"
|
||||||
of zeroOrOne:
|
of zeroOrOne:
|
||||||
"?"
|
"?"
|
||||||
|
of orWithNext:
|
||||||
|
"!"
|
||||||
|
|
||||||
converter toKind*(kind: string): Kind =
|
converter toKind*(kind: string): Kind =
|
||||||
return case kind:
|
return case kind:
|
||||||
|
|
@ -194,6 +196,8 @@ converter toKind*(kind: string): Kind =
|
||||||
zeroOrMore
|
zeroOrMore
|
||||||
of "?":
|
of "?":
|
||||||
zeroOrOne
|
zeroOrOne
|
||||||
|
of "!":
|
||||||
|
orWithNext
|
||||||
else:
|
else:
|
||||||
exactlyOne
|
exactlyOne
|
||||||
|
|
||||||
|
|
@ -223,7 +227,12 @@ proc getRegexForAstChildren*(ast: ref Ast): string =
|
||||||
result = "^"
|
result = "^"
|
||||||
for i in 0 .. ast.children.len-1:
|
for i in 0 .. ast.children.len-1:
|
||||||
let kind: string = ast.children[i].kind
|
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 &= "$"
|
result &= "$"
|
||||||
|
|
||||||
proc getAstChildByName*(ast: ref Ast, name: string): ref Ast =
|
proc getAstChildByName*(ast: ref Ast, name: string): ref Ast =
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ type
|
||||||
oneOrMore # +
|
oneOrMore # +
|
||||||
zeroOrMore # *
|
zeroOrMore # *
|
||||||
zeroOrOne # ?
|
zeroOrOne # ?
|
||||||
|
orWithNext # !
|
||||||
|
|
||||||
Ast* = object
|
Ast* = object
|
||||||
name*: string
|
name*: string
|
||||||
|
|
|
||||||
|
|
@ -50,18 +50,35 @@ proc initGrammar() =
|
||||||
""",
|
""",
|
||||||
proc (ast: ref Ast, node: TSNode) =
|
proc (ast: ref Ast, node: TSNode) =
|
||||||
var
|
var
|
||||||
name = gStateRT.data[1].val.getIdentifier()
|
i = 0
|
||||||
typ = gStateRT.data[0].val.getIdentifier()
|
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:
|
if name notin gStateRT.types:
|
||||||
gStateRT.types.add(name)
|
gStateRT.types.add(name)
|
||||||
if name == typ:
|
if name == typ or typ == "object":
|
||||||
typ = "object"
|
gStateRT.typeStr &= &" {name}* = object\n"
|
||||||
gStateRT.typeStr &= &" {name}* = {typ}\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()
|
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":
|
if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "identifier":
|
||||||
pname = gStateRT.data[i+1].val.getIdentifier()
|
pname = gStateRT.data[i+1].val.getIdentifier()
|
||||||
i += 2
|
i += 2
|
||||||
|
|
@ -70,7 +87,7 @@ proc initGrammar() =
|
||||||
count += 1
|
count += 1
|
||||||
i += 1
|
i += 1
|
||||||
if ptyp != "object":
|
if ptyp != "object":
|
||||||
pout &= &"{pname}: {ptyp},"
|
pout &= &"{pname}: {pptr}{ptyp},"
|
||||||
|
|
||||||
proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) =
|
proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) =
|
||||||
var
|
var
|
||||||
|
|
@ -100,25 +117,34 @@ proc initGrammar() =
|
||||||
|
|
||||||
var
|
var
|
||||||
i = fstart
|
i = fstart
|
||||||
|
ftyp, fname: string
|
||||||
|
fptr = ""
|
||||||
while i < gStateRT.data.len-fend:
|
while i < gStateRT.data.len-fend:
|
||||||
|
fptr = ""
|
||||||
if gStateRT.data[i].name == "field_declaration":
|
if gStateRT.data[i].name == "field_declaration":
|
||||||
i += 1
|
i += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
let
|
if gStateRT.data[i].name notin ["field_identifier", "pointer_declarator"]:
|
||||||
ftyp = gStateRT.data[i].val.getIdentifier()
|
ftyp = gStateRT.data[i].val.getIdentifier()
|
||||||
fname = gStateRT.data[i+1].val.getIdentifier()
|
i += 1
|
||||||
if i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name in ["identifier", "number_literal"]:
|
|
||||||
|
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
|
let
|
||||||
flen = gStateRT.data[i+2].val.getIdentifier()
|
flen = gStateRT.data[i+1].val.getIdentifier()
|
||||||
gStateRT.typeStr &= &" {fname}*: array[{flen}, {ftyp}]\n"
|
gStateRT.typeStr &= &" {fname}*: array[{flen}, {fptr}{ftyp}]\n"
|
||||||
i += 3
|
i += 2
|
||||||
elif i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name == "function_declarator":
|
elif i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "function_declarator":
|
||||||
var
|
var
|
||||||
pout, pname, ptyp = ""
|
pout, pname, ptyp, pptr = ""
|
||||||
count = 1
|
count = 1
|
||||||
|
|
||||||
i += 3
|
i += 2
|
||||||
while i < gStateRT.data.len-fend:
|
while i < gStateRT.data.len-fend:
|
||||||
if gStateRT.data[i].name == "function_declarator":
|
if gStateRT.data[i].name == "function_declarator":
|
||||||
i += 1
|
i += 1
|
||||||
|
|
@ -127,18 +153,18 @@ proc initGrammar() =
|
||||||
if gStateRT.data[i].name == "field_declaration":
|
if gStateRT.data[i].name == "field_declaration":
|
||||||
break
|
break
|
||||||
|
|
||||||
funcParamCommon(pname, ptyp, pout, count, i)
|
funcParamCommon(pname, ptyp, pptr, pout, count, i)
|
||||||
|
|
||||||
if pout.len != 0 and pout[^1] == ',':
|
if pout.len != 0 and pout[^1] == ',':
|
||||||
pout = pout[0 .. ^2]
|
pout = pout[0 .. ^2]
|
||||||
if ftyp != "object":
|
if ftyp != "object":
|
||||||
gStateRT.typeStr &= &" {fname}*: proc({pout}): {ftyp} {{.nimcall.}}\n"
|
gStateRT.typeStr &= &" {fname}*: proc({pout}): {fptr}{ftyp} {{.nimcall.}}\n"
|
||||||
else:
|
else:
|
||||||
gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n"
|
gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n"
|
||||||
i += 1
|
i += 1
|
||||||
else:
|
else:
|
||||||
gStateRT.typeStr &= &" {fname}*: {ftyp}\n"
|
gStateRT.typeStr &= &" {fname}*: {fptr}{ftyp}\n"
|
||||||
i += 2
|
i += 1
|
||||||
|
|
||||||
let
|
let
|
||||||
paramListGrammar = &"""
|
paramListGrammar = &"""
|
||||||
|
|
@ -155,12 +181,12 @@ proc initGrammar() =
|
||||||
"""
|
"""
|
||||||
|
|
||||||
fieldGrammar = &"""
|
fieldGrammar = &"""
|
||||||
(field_identifier?)
|
(field_identifier!)
|
||||||
(array_declarator?
|
(array_declarator!
|
||||||
(field_identifier)
|
(field_identifier)
|
||||||
(identifier|number_literal)
|
(identifier|number_literal)
|
||||||
)
|
)
|
||||||
(function_declarator?
|
(function_declarator+
|
||||||
(pointer_declarator
|
(pointer_declarator
|
||||||
(field_identifier)
|
(field_identifier)
|
||||||
)
|
)
|
||||||
|
|
@ -172,10 +198,10 @@ proc initGrammar() =
|
||||||
(field_declaration_list
|
(field_declaration_list
|
||||||
(field_declaration+
|
(field_declaration+
|
||||||
{typeGrammar}
|
{typeGrammar}
|
||||||
{fieldGrammar}
|
(pointer_declarator!
|
||||||
(pointer_declarator?
|
|
||||||
{fieldGrammar}
|
{fieldGrammar}
|
||||||
)
|
)
|
||||||
|
{fieldGrammar}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
|
|
@ -295,7 +321,7 @@ proc initGrammar() =
|
||||||
))
|
))
|
||||||
|
|
||||||
let funcGrammar = &"""
|
let funcGrammar = &"""
|
||||||
(function_declarator*
|
(function_declarator+
|
||||||
(identifier)
|
(identifier)
|
||||||
{paramListGrammar}
|
{paramListGrammar}
|
||||||
)
|
)
|
||||||
|
|
@ -306,31 +332,31 @@ proc initGrammar() =
|
||||||
(declaration
|
(declaration
|
||||||
(storage_class_specifier?)
|
(storage_class_specifier?)
|
||||||
{typeGrammar}
|
{typeGrammar}
|
||||||
{funcGrammar}
|
(pointer_declarator!
|
||||||
(pointer_declarator*
|
|
||||||
{funcGrammar}
|
{funcGrammar}
|
||||||
)
|
)
|
||||||
{funcGrammar}
|
{funcGrammar}
|
||||||
(pointer_declarator*
|
|
||||||
{funcGrammar}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
proc (ast: ref Ast, node: TSNode) =
|
proc (ast: ref Ast, node: TSNode) =
|
||||||
let
|
|
||||||
ftyp = gStateRT.data[0].val.getIdentifier()
|
|
||||||
|
|
||||||
var
|
var
|
||||||
|
ftyp = gStateRT.data[0].val.getIdentifier()
|
||||||
|
fptr = ""
|
||||||
i = 1
|
i = 1
|
||||||
|
|
||||||
while i < gStateRT.data.len:
|
while i < gStateRT.data.len:
|
||||||
if gStateRT.data[i].name == "function_declarator":
|
if gStateRT.data[i].name == "function_declarator":
|
||||||
i += 1
|
i += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if gStateRT.data[i].name == "pointer_declarator":
|
||||||
|
fptr = "ptr "
|
||||||
|
i += 1
|
||||||
|
|
||||||
var
|
var
|
||||||
fname = gStateRT.data[i].val
|
fname = gStateRT.data[i].val
|
||||||
fnname = fname.getIdentifier()
|
fnname = fname.getIdentifier()
|
||||||
pout, pname, ptyp = ""
|
pout, pname, ptyp, pptr = ""
|
||||||
count = 1
|
count = 1
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
@ -338,7 +364,7 @@ proc initGrammar() =
|
||||||
if gStateRT.data[i].name == "function_declarator":
|
if gStateRT.data[i].name == "function_declarator":
|
||||||
break
|
break
|
||||||
|
|
||||||
funcParamCommon(pname, ptyp, pout, count, i)
|
funcParamCommon(pname, ptyp, pptr, pout, count, i)
|
||||||
|
|
||||||
if pout.len != 0 and pout[^1] == ',':
|
if pout.len != 0 and pout[^1] == ',':
|
||||||
pout = pout[0 .. ^2]
|
pout = pout[0 .. ^2]
|
||||||
|
|
@ -346,7 +372,7 @@ proc initGrammar() =
|
||||||
if fnname notin gStateRT.procs:
|
if fnname notin gStateRT.procs:
|
||||||
gStateRT.procs.add(fnname)
|
gStateRT.procs.add(fnname)
|
||||||
if ftyp != "object":
|
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:
|
else:
|
||||||
gStateRT.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n"
|
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:
|
for child in ast.children:
|
||||||
child.initRegex()
|
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*() =
|
proc parseGrammar*() =
|
||||||
initGrammar()
|
initGrammar()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue