aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2018-11-21 14:14:18 -0600
committerGanesh Viswanathan <dev@genotrance.com>2018-11-21 14:14:18 -0600
commit01c295a41c6f80e8999db07f9b07d29943f98040 (patch)
treec839ed333d0f25fdb3866db896a86ea9363262a9
parent047e33868f4523516b4b88742d29905dbe702e45 (diff)
downloadnimterop-01c295a41c6f80e8999db07f9b07d29943f98040.tar.gz
nimterop-01c295a41c6f80e8999db07f9b07d29943f98040.zip
Initial pointer support, ugly toast
-rw-r--r--nimterop/ast.nim54
-rw-r--r--nimterop/getters.nim2
-rw-r--r--nimterop/lisp.nim10
-rw-r--r--toast.nim22
4 files changed, 51 insertions, 37 deletions
diff --git a/nimterop/ast.nim b/nimterop/ast.nim
index 474c918..71ae9d1 100644
--- a/nimterop/ast.nim
+++ b/nimterop/ast.nim
@@ -14,12 +14,12 @@ proc addReorder*(): NimNode =
proc addHeader*(fullpath: string) =
gCurrentHeader = ("header" & fullpath.splitFile().name.replace(re"[-.]+", ""))
- gConstStr &= &" {gCurrentHeader} = \"{fullpath}\" # addHeader()\n"
+ gConstStr &= &" {gCurrentHeader} = \"{fullpath}\" # addHeader()\n"
#
# Preprocessor
#
-
+
proc preprocDef(node: ref Ast) =
if node.children.len() == 2:
let
@@ -30,7 +30,7 @@ proc preprocDef(node: ref Ast) =
gConsts.add(name)
if val.getLit().nBl:
# #define NAME VALUE
- gConstStr &= &" {name.getIdentifier()}* = {val} # preprocDef()\n"
+ gConstStr &= &" {name.getIdentifier()}* = {val} # preprocDef()\n"
#
# Types
@@ -44,7 +44,7 @@ proc typeScan(node: ref Ast, sym, identifier, offset: string): string =
pname = getNodeValIf(node.children[1], identifier)
ptyp = getNodeValIf(node.children[0], "primitive_type")
ttyp = getNodeValIf(node.children[0], "type_identifier")
-
+
if pname.len() == 0:
return
elif ptyp.nBl:
@@ -68,28 +68,28 @@ proc structSpecifier(node: ref Ast, name = "") =
gTypes.add(name)
if name != typ:
# typedef struct X Y
- gTypeStr &= &" {name}* = {typ} #1 structSpecifier()\n"
+ gTypeStr &= &" {name}* = {typ} #1 structSpecifier()\n"
else:
# typedef struct X X
- gTypeStr &= &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 structSpecifier()\n"
+ gTypeStr &= &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 structSpecifier()\n"
of "field_declaration_list":
# typedef struct { fields } X
- stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 structSpecifier()\n"
-
+ stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 structSpecifier()\n"
+
for field in node.children[0].children:
let ts = typeScan(field, "field_declaration", "field_identifier", " ")
if ts.len() == 0:
return
stmt &= ts & "\n"
-
+
gTypes.add(name)
gTypeStr &= stmt
elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == "field_declaration_list":
let ename = getNodeValIf(node.children[0], "type_identifier")
if ename.nBl and ename notin gTypes:
# struct X { fields }
- stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #4 structSpecifier()\n"
+ stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #4 structSpecifier()\n"
for field in node.children[1].children:
let ts = typeScan(field, "field_declaration", "field_identifier", " ")
@@ -105,18 +105,18 @@ proc enumSpecifier(node: ref Ast, name = "") =
ename: string
elid: int
stmt: string
-
+
if node.children.len() == 1 and node.children[0].sym == "enumerator_list":
# typedef enum { fields } X
ename = name
elid = 0
- stmt = &" {name}* = enum #1 enumSpecifier()\n"
+ stmt = &" {name}* = enum #1 enumSpecifier()\n"
elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == "enumerator_list":
ename = getNodeValIf(node.children[0], "type_identifier")
elid = 1
if ename.nBl:
# enum X { fields }
- stmt = &" {ename}* = enum #2 enumSpecifier()\n"
+ stmt = &" {ename}* = enum #2 enumSpecifier()\n"
else:
return
@@ -130,27 +130,31 @@ proc enumSpecifier(node: ref Ast, name = "") =
stmt &= &" {fname} = {num}\n"
else:
return
-
+
if ename notin gTypes:
gTypes.add(name)
gTypeStr &= stmt
proc typeDefinition(node: ref Ast) =
if node.children.len() == 2:
- let
+ var
name = getNodeValIf(node.children[1], "type_identifier")
+ pname = getNodeValIf(node.children[1], "pointer_declarator")
ptyp = getNodeValIf(node.children[0], "primitive_type")
ttyp = getNodeValIf(node.children[0], "type_identifier")
-
+
+ if name.len() == 0 and node.children[1].sym == "pointer_declarator" and node.children[1].children.len() == 1:
+ name = getNodeValIf(node.children[1].children[0], "type_identifier")
+
if name.nBl and name notin gTypes:
if ptyp.nBl:
# typedef int X
gTypes.add(name)
- gTypeStr &= &" {name}* = {ptyp.getType()} #1 typeDefinition()\n"
+ gTypeStr &= &" {name}* = {ptyp.getType()} #1 typeDefinition()\n"
elif ttyp.nBl:
# typedef X Y
gTypes.add(name)
- gTypeStr &= &" {name}* = {ttyp} #2 typeDefinition()\n"
+ gTypeStr &= &" {name}* = {ttyp} #2 typeDefinition()\n"
else:
case node.children[0].sym:
of "struct_specifier":
@@ -162,11 +166,11 @@ proc functionDeclarator(node: ref Ast, typ: string) =
if node.children.len() == 2:
let
name = getNodeValIf(node.children[0], "identifier")
-
+
if name.nBl and name notin gProcs and node.children[1].sym == "parameter_list":
# typ function(typ param1, ...)
var stmt = &"# functionDeclarator()\nproc {name}*("
-
+
for i in 0 .. node.children[1].children.len()-1:
let ts = typeScan(node.children[1].children[i], "parameter_declaration", "identifier", "")
if ts.len() == 0:
@@ -174,17 +178,17 @@ proc functionDeclarator(node: ref Ast, typ: string) =
stmt &= ts
if i != node.children[1].children.len()-1:
stmt &= ", "
-
+
if typ != "void":
stmt &= &"): {typ.getType()} "
else:
stmt &= ") "
-
+
stmt &= &"{{.importc: \"{name}\", header: {gCurrentHeader}.}}\n"
gProcs.add(name)
gProcStr &= stmt
-
+
proc declaration*(node: ref Ast) =
if node.children.len() == 2 and node.children[1].sym == "function_declarator":
let
@@ -199,7 +203,7 @@ proc declaration*(node: ref Ast) =
let styp = getNodeValIf(node.children[0].children[0], "type_identifier")
if styp.nBl:
functionDeclarator(node.children[1], styp)
-
+
proc genNimAst*(node: ref Ast) =
case node.sym:
of "ERROR":
@@ -217,8 +221,6 @@ proc genNimAst*(node: ref Ast) =
of "enum_specifier":
if node.parent.sym notin ["type_definition", "declaration"]:
enumSpecifier(node)
- of "":
- return
for child in node.children:
genNimAst(child)
diff --git a/nimterop/getters.nim b/nimterop/getters.nim
index d31034a..1ad4733 100644
--- a/nimterop/getters.nim
+++ b/nimterop/getters.nim
@@ -8,7 +8,7 @@ proc getIdentifier*(str: string): string =
result = str.strip(chars={'_'})
proc getType*(str: string): string =
- result = str.strip(chars={'_'}).replace(re"([u]?int[\d]+)_t", "$1")
+ result = str.strip(chars={'_'}).replace(re"([u]?int[\d]+)_t", "$1").replace(re"^void$", "object")
proc getLit*(str: string): string =
if str.contains(re"^[\-]?[\d]+$") or
diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim
index 4a0b71d..6e49197 100644
--- a/nimterop/lisp.nim
+++ b/nimterop/lisp.nim
@@ -13,16 +13,14 @@ proc tokenize(fullpath: string) =
gTokens = @[]
idx = 0
- for i in staticExec("toast " & fullpath):
+ for i in staticExec("toast -u " & fullpath):
case i:
- of ' ', '\n', '\r', ')':
+ of ' ', '\n', '\r', '(', ')':
if collect.nBl:
gTokens.add(collect)
collect = ""
- if i == ')':
- gTokens.add(")")
- of '(':
- gTokens.add("(")
+ if i in ['(', ')']:
+ gTokens.add($i)
else:
collect &= $i
diff --git a/toast.nim b/toast.nim
index c2f2a3b..60f92d8 100644
--- a/toast.nim
+++ b/toast.nim
@@ -8,6 +8,9 @@ const HELP = """
> toast header.h
"""
+var
+ gPretty = true
+
proc printLisp(root: TSNode, data: var string) =
var
node = root
@@ -16,21 +19,30 @@ proc printLisp(root: TSNode, data: var string) =
while true:
if not node.tsNodeIsNull():
- stdout.write spaces(depth) & "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte()
+ if gPretty:
+ stdout.write spaces(depth)
+ stdout.write "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte()
if node.tsNodeNamedChildCount() != 0:
- echo ""
+ if gPretty:
+ echo ""
nextnode = node.tsNodeNamedChild(0)
depth += 1
else:
- echo ")"
+ if gPretty:
+ echo ")"
+ else:
+ stdout.write ")"
nextnode = node.tsNodeNextNamedSibling()
if nextnode.tsNodeIsNull():
while true:
node = node.tsNodeParent()
depth -= 1
- echo spaces(depth) & ")"
+ if gPretty:
+ echo spaces(depth) & ")"
+ else:
+ stdout.write ")"
if node == root:
break
if not node.tsNodeNextNamedSibling().tsNodeIsNull():
@@ -93,6 +105,8 @@ proc parseCli() =
if param in ["-h", "--help", "-?", "/?", "/h"]:
echo HELP
quit()
+ elif param == "-u":
+ gPretty = false
else:
process(param)