Support for math expressions, nameless enums, uintptr, redundant typedef naming

This commit is contained in:
Ganesh Viswanathan 2018-12-26 13:25:45 -06:00
commit 34cb1715b8
5 changed files with 62 additions and 13 deletions

View file

@ -19,9 +19,9 @@ proc execCmd(cmd:string)=
task test, "Test": task test, "Test":
execCmd "nim c -r tests/tnimterop_c.nim" execCmd "nim c -r tests/tnimterop_c.nim"
execCmd "nim cpp -r tests/tnimterop_cpp.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim"
when defined(windows): # when defined(windows):
execCmd "nim c -r tests/tmath.nim" # execCmd "nim c -r tests/tmath.nim"
execCmd "nim cpp -r tests/tmath.nim" # execCmd "nim cpp -r tests/tmath.nim"
task installWithDeps, "install dependencies": task installWithDeps, "install dependencies":
for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter", for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter",

View file

@ -9,6 +9,7 @@ import "."/[getters, globals, grammar]
const gAtoms = @[ const gAtoms = @[
"field_identifier", "field_identifier",
"identifier", "identifier",
"math_expression",
"number_literal", "number_literal",
"preproc_arg", "preproc_arg",
"primitive_type", "primitive_type",
@ -25,7 +26,10 @@ proc saveNodeData(node: TSNode): bool =
if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier": if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier":
return true return true
if name in ["primitive_type", "sized_type_specifier"]: if name == "number_literal" and node.tsNodeParent.tsNodeType() == "math_expression":
return true
if name in ["math_expression", "primitive_type", "sized_type_specifier"]:
val = val.getType() val = val.getType()
let let
@ -39,7 +43,7 @@ proc saveNodeData(node: TSNode): bool =
not npparent.tsNodeIsNull() and npparent.tsNodeType() == "pointer_declarator"): not npparent.tsNodeIsNull() and npparent.tsNodeType() == "pointer_declarator"):
if gStateRT.data[^1].val != "object": if gStateRT.data[^1].val != "object":
gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier()
gStateRT.data.add((name, val)) gStateRT.data.add((name, val))

View file

@ -12,6 +12,16 @@ proc sanitizePath*(path: string): string =
proc getIdentifier*(str: string): string = proc getIdentifier*(str: string): string =
result = str.strip(chars={'_'}) result = str.strip(chars={'_'})
proc getUniqueIdentifier*(exists: seq[string]): string =
var
name = gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")])
count = 1
while (name & $count) in exists:
count += 1
return name & $count
proc getType*(str: string): string = proc getType*(str: string): string =
if str == "void": if str == "void":
return "object" return "object"
@ -22,7 +32,8 @@ proc getType*(str: string): string =
("double ", "cdouble"), ("double ", "cdouble"),
("long ", "clong"), ("long ", "clong"),
]). ]).
replace(re"([u]?int[\d]+)_t", "$1") replace(re"([u]?int[\d]+)_t", "$1").
replace(re"([u]?int)ptr_t", "ptr $1")
case result: case result:
of "long": of "long":

View file

@ -119,6 +119,7 @@ proc initGrammar() =
gStateRT.grammar.add((""" gStateRT.grammar.add(("""
(type_definition (type_definition
(struct_specifier|union_specifier (struct_specifier|union_specifier
(type_identifier?)
(field_declaration_list (field_declaration_list
(field_declaration+ (field_declaration+
(primitive_type|type_identifier?) (primitive_type|type_identifier?)
@ -139,12 +140,22 @@ proc initGrammar() =
) )
""", """,
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
pStructCommon(ast, node, gStateRT.data[^1].val, 0, 1) var
offset = 0
if gStateRT.data[0].name == "type_identifier":
offset = 1
pStructCommon(ast, node, gStateRT.data[^1].val, offset, 1)
)) ))
proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) =
let var
nname = name.getIdentifier() nname = name.getIdentifier()
if nname.len == 0:
nname = getUniqueIdentifier(gStateRT.types)
if nname notin gStateRT.types: if nname notin gStateRT.types:
gStateRT.types.add(nname) gStateRT.types.add(nname)
gStateRT.typeStr &= &" {nname}* = enum\n" gStateRT.typeStr &= &" {nname}* = enum\n"
@ -155,7 +166,7 @@ proc initGrammar() =
let let
fname = gStateRT.data[i].val.getIdentifier() fname = gStateRT.data[i].val.getIdentifier()
if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "number_literal": if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["math_expression", "number_literal"]:
gStateRT.typeStr &= &" {fname} = {gStateRT.data[i+1].val}\n" gStateRT.typeStr &= &" {fname} = {gStateRT.data[i+1].val}\n"
i += 2 i += 2
else: else:
@ -165,27 +176,42 @@ proc initGrammar() =
# enum X {} # enum X {}
gStateRT.grammar.add((""" gStateRT.grammar.add(("""
(enum_specifier (enum_specifier
(type_identifier) (type_identifier?)
(enumerator_list (enumerator_list
(enumerator+ (enumerator+
(identifier) (identifier)
(number_literal?) (number_literal?)
(math_expression?
(number_literal)
)
) )
) )
) )
""", """,
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
pEnumCommon(ast, node, gStateRT.data[0].val, 1, 0) var
name = ""
offset = 0
if gStateRT.data[0].name == "type_identifier":
name = gStateRT.data[0].val
offset = 1
pEnumCommon(ast, node, name, offset, 0)
)) ))
# typedef enum {} X # typedef enum {} X
gStateRT.grammar.add((""" gStateRT.grammar.add(("""
(type_definition (type_definition
(enum_specifier (enum_specifier
(type_identifier?)
(enumerator_list (enumerator_list
(enumerator+ (enumerator+
(identifier) (identifier)
(number_literal?) (number_literal?)
(math_expression?
(number_literal)
)
) )
) )
) )
@ -193,13 +219,19 @@ proc initGrammar() =
) )
""", """,
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
pEnumCommon(ast, node, gStateRT.data[^1].val, 0, 1) var
offset = 0
if gStateRT.data[0].name == "type_identifier":
offset = 1
pEnumCommon(ast, node, gStateRT.data[^1].val, offset, 1)
)) ))
# typ function(typ param1, ...) # typ function(typ param1, ...)
gStateRT.grammar.add((""" gStateRT.grammar.add(("""
(declaration (declaration
(type_qualifier?) (type_qualifier|storage_class_specifier?)
(primitive_type|type_identifier?) (primitive_type|type_identifier?)
(sized_type_specifier? (sized_type_specifier?
(primitive_type?) (primitive_type?)

View file

@ -4,6 +4,8 @@ import unittest
type type
locale_t = object locale_t = object
cDebug()
cAddStdDir() cAddStdDir()
cImport cSearchPath("math.h") cImport cSearchPath("math.h")