Support for unions
This commit is contained in:
parent
cb1c7f28cb
commit
dfe06fd9d4
7 changed files with 112 additions and 50 deletions
|
|
@ -84,7 +84,7 @@ proc searchAst(root: TSNode) =
|
|||
if name in gStateRT.ast:
|
||||
for ast in gStateRT.ast[name]:
|
||||
if searchAstForNode(ast, node):
|
||||
ast.tonim()
|
||||
ast.tonim(ast, node)
|
||||
break
|
||||
gStateRT.data = @[]
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import tables
|
|||
|
||||
import regex
|
||||
|
||||
import treesitter/runtime
|
||||
|
||||
type
|
||||
Kind* = enum
|
||||
exactlyOne
|
||||
|
|
@ -13,7 +15,7 @@ type
|
|||
name*: string
|
||||
kind*: Kind
|
||||
children*: seq[ref Ast]
|
||||
tonim*: proc () {.closure, locks: 0.}
|
||||
tonim*: proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.}
|
||||
regex*: Regex
|
||||
|
||||
State* = object
|
||||
|
|
@ -28,7 +30,7 @@ type
|
|||
|
||||
ast*: Table[string, seq[ref Ast]]
|
||||
data*: seq[tuple[name, val: string]]
|
||||
grammar*: seq[tuple[grammar: string, call: proc() {.locks: 0.}]]
|
||||
grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.locks: 0.}]]
|
||||
|
||||
var
|
||||
gStateCT* {.compiletime.}: State
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import strformat, tables
|
||||
import strformat, strutils, tables
|
||||
|
||||
import regex
|
||||
|
||||
import treesitter/runtime
|
||||
|
||||
import "."/[getters, globals, lisp]
|
||||
|
||||
proc initGrammar() =
|
||||
|
|
@ -12,7 +14,7 @@ proc initGrammar() =
|
|||
(preproc_arg)
|
||||
)
|
||||
""",
|
||||
proc () {.closure, locks: 0.} =
|
||||
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
|
||||
let
|
||||
name = gStateRT.data[0].val.getIdentifier()
|
||||
val = gStateRT.data[1].val.getLit()
|
||||
|
|
@ -41,7 +43,7 @@ proc initGrammar() =
|
|||
)
|
||||
)
|
||||
""",
|
||||
proc () {.closure, locks: 0.} =
|
||||
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
|
||||
var
|
||||
name = gStateRT.data[1].val.getIdentifier()
|
||||
typ = gStateRT.data[0].val.getIdentifier()
|
||||
|
|
@ -51,12 +53,31 @@ proc initGrammar() =
|
|||
gStateRT.typeStr &= &" {name}* = {typ}\n"
|
||||
))
|
||||
|
||||
proc pStructCommon(name: string, fstart, fend: int, prefix="") =
|
||||
let
|
||||
proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) =
|
||||
var
|
||||
nname = name.getIdentifier()
|
||||
prefix = ""
|
||||
union = ""
|
||||
|
||||
case $node.tsNodeType():
|
||||
of "struct_specifier":
|
||||
prefix = "struct "
|
||||
of "union_specifier":
|
||||
prefix = "union "
|
||||
union = " {.union.}"
|
||||
of "type_definition":
|
||||
if node.getTSNodeNamedChildCountSansComments() != 0:
|
||||
for i in 0 .. node.tsNodeNamedChildCount()-1:
|
||||
let
|
||||
nchild = $node.tsNodeNamedChild(i).tsNodeType()
|
||||
if nchild != "comment":
|
||||
if nchild == "union_specifier":
|
||||
union = " {.union.}"
|
||||
break
|
||||
|
||||
if nname notin gStateRT.types:
|
||||
gStateRT.types.add(nname)
|
||||
gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object\n"
|
||||
gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object{union}\n"
|
||||
|
||||
var
|
||||
i = fstart
|
||||
|
|
@ -69,13 +90,13 @@ proc initGrammar() =
|
|||
|
||||
# struct X {}
|
||||
gStateRT.grammar.add(("""
|
||||
(struct_specifier
|
||||
(struct_specifier|union_specifier
|
||||
(type_identifier)
|
||||
(field_declaration_list
|
||||
(field_declaration+
|
||||
(primitive_type|type_identifier?)
|
||||
(sized_type_specifier?
|
||||
(primitive_type)
|
||||
(primitive_type?)
|
||||
)
|
||||
(struct_specifier?
|
||||
(type_identifier)
|
||||
|
|
@ -88,14 +109,14 @@ proc initGrammar() =
|
|||
)
|
||||
)
|
||||
""",
|
||||
proc () {.closure, locks: 0.} =
|
||||
pStructCommon(gStateRT.data[0].val, 1, 0, "struct ")
|
||||
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
|
||||
pStructCommon(ast, node, gStateRT.data[0].val, 1, 1)
|
||||
))
|
||||
|
||||
# typedef struct X {}
|
||||
gStateRT.grammar.add(("""
|
||||
(type_definition
|
||||
(struct_specifier
|
||||
(struct_specifier|union_specifier
|
||||
(field_declaration_list
|
||||
(field_declaration+
|
||||
(primitive_type|type_identifier?)
|
||||
|
|
@ -115,11 +136,11 @@ proc initGrammar() =
|
|||
(type_identifier)
|
||||
)
|
||||
""",
|
||||
proc () {.closure, locks: 0.} =
|
||||
pStructCommon(gStateRT.data[^1].val, 0, 1)
|
||||
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
|
||||
pStructCommon(ast, node, gStateRT.data[^1].val, 0, 1)
|
||||
))
|
||||
|
||||
proc pEnumCommon(name: string, fstart, fend: int, prefix="") =
|
||||
proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) =
|
||||
let
|
||||
nname = name.getIdentifier()
|
||||
if nname notin gStateRT.types:
|
||||
|
|
@ -151,8 +172,8 @@ proc initGrammar() =
|
|||
)
|
||||
)
|
||||
""",
|
||||
proc () {.closure, locks: 0.} =
|
||||
pEnumCommon(gStateRT.data[0].val, 1, 0)
|
||||
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
|
||||
pEnumCommon(ast, node, gStateRT.data[0].val, 1, 0)
|
||||
))
|
||||
|
||||
# typedef enum {} X
|
||||
|
|
@ -169,8 +190,8 @@ proc initGrammar() =
|
|||
(type_identifier)
|
||||
)
|
||||
""",
|
||||
proc () {.closure, locks: 0.} =
|
||||
pEnumCommon(gStateRT.data[^1].val, 0, 1)
|
||||
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
|
||||
pEnumCommon(ast, node, gStateRT.data[^1].val, 0, 1)
|
||||
))
|
||||
|
||||
# typ function(typ param1, ...)
|
||||
|
|
@ -181,7 +202,7 @@ proc initGrammar() =
|
|||
(sized_type_specifier?
|
||||
(primitive_type?)
|
||||
)
|
||||
(struct_specifier?
|
||||
(struct_specifier|union_specifier?
|
||||
(type_identifier)
|
||||
)
|
||||
(function_declarator?
|
||||
|
|
@ -193,7 +214,7 @@ proc initGrammar() =
|
|||
(sized_type_specifier?
|
||||
(primitive_type?)
|
||||
)
|
||||
(struct_specifier?
|
||||
(struct_specifier|union_specifier?
|
||||
(type_identifier)
|
||||
)
|
||||
(enum_specifier?
|
||||
|
|
@ -216,7 +237,7 @@ proc initGrammar() =
|
|||
(sized_type_specifier?
|
||||
(primitive_type?)
|
||||
)
|
||||
(struct_specifier?
|
||||
(struct_specifier|union_specifier?
|
||||
(type_identifier)
|
||||
)
|
||||
(enum_specifier?
|
||||
|
|
@ -232,7 +253,7 @@ proc initGrammar() =
|
|||
)
|
||||
)
|
||||
""",
|
||||
proc () {.closure, locks: 0.} =
|
||||
proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} =
|
||||
let
|
||||
ftyp = gStateRT.data[0].val.getIdentifier()
|
||||
fname = gStateRT.data[1].val
|
||||
|
|
@ -277,10 +298,11 @@ proc parseGrammar*() =
|
|||
|
||||
ast.tonim = gStateRT.grammar[i].call
|
||||
ast.initRegex()
|
||||
if ast.name notin gStateRT.ast:
|
||||
gStateRT.ast[ast.name] = @[ast]
|
||||
else:
|
||||
gStateRT.ast[ast.name].add(ast)
|
||||
for n in ast.name.split("|"):
|
||||
if n notin gStateRT.ast:
|
||||
gStateRT.ast[n] = @[ast]
|
||||
else:
|
||||
gStateRT.ast[n].add(ast)
|
||||
|
||||
proc printGrammar*() =
|
||||
for name in gStateRT.ast.keys():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue