aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2018-11-21 17:24:13 -0600
committerGanesh Viswanathan <dev@genotrance.com>2018-11-21 17:24:13 -0600
commitc0481ac41c84bb34326058ad8db7cf74b35fcb82 (patch)
treead85a135738d18dc778e38a178e960a6126daf4a
parent01c295a41c6f80e8999db07f9b07d29943f98040 (diff)
downloadnimterop-c0481ac41c84bb34326058ad8db7cf74b35fcb82.tar.gz
nimterop-c0481ac41c84bb34326058ad8db7cf74b35fcb82.zip
Use enums for sym, fail if no toast
-rw-r--r--nimterop/ast.nim151
-rw-r--r--nimterop/getters.nim2
-rw-r--r--nimterop/globals.nim15
-rw-r--r--nimterop/lisp.nim17
4 files changed, 105 insertions, 80 deletions
diff --git a/nimterop/ast.nim b/nimterop/ast.nim
index 71ae9d1..b825efe 100644
--- a/nimterop/ast.nim
+++ b/nimterop/ast.nim
@@ -20,30 +20,30 @@ proc addHeader*(fullpath: string) =
# Preprocessor
#
-proc preprocDef(node: ref Ast) =
+proc pPreprocDef(node: ref Ast) =
if node.children.len() == 2:
let
- name = getNodeValIf(node.children[0], "identifier")
- val = getNodeValIf(node.children[1], "preproc_arg")
+ name = getNodeValIf(node.children[0], identifier)
+ val = getNodeValIf(node.children[1], preproc_arg)
if name.nBl and val.nBl and name notin gConsts:
gConsts.add(name)
if val.getLit().nBl:
# #define NAME VALUE
- gConstStr &= &" {name.getIdentifier()}* = {val} # preprocDef()\n"
+ gConstStr &= &" {name.getIdentifier()}* = {val} # pPreprocDef()\n"
#
# Types
#
-proc typeScan(node: ref Ast, sym, identifier, offset: string): string =
+proc typeScan(node: ref Ast, sym, id: Sym, offset: string): string =
if node.sym != sym or node.children.len() != 2:
return
let
- pname = getNodeValIf(node.children[1], identifier)
- ptyp = getNodeValIf(node.children[0], "primitive_type")
- ttyp = getNodeValIf(node.children[0], "type_identifier")
+ pname = getNodeValIf(node.children[1], id)
+ ptyp = getNodeValIf(node.children[0], primitive_type)
+ ttyp = getNodeValIf(node.children[0], type_identifier)
if pname.len() == 0:
return
@@ -51,48 +51,51 @@ proc typeScan(node: ref Ast, sym, identifier, offset: string): string =
result = &"{offset}{pname.getIdentifier()}: {ptyp.getType()}"
elif ttyp.nBl:
result = &"{offset}{pname.getIdentifier()}: {ttyp}"
- elif node.children[0].sym in ["struct_specifier", "enum_specifier"] and node.children[0].children.len() == 1:
- let styp = getNodeValIf(node.children[0].children[0], "type_identifier")
+ elif node.children[0].sym in [struct_specifier, enum_specifier] and node.children[0].children.len() == 1:
+ let styp = getNodeValIf(node.children[0].children[0], type_identifier)
if styp.nBl:
result = &"{offset}{pname.getIdentifier()}: {styp}"
else:
return
-proc structSpecifier(node: ref Ast, name = "") =
+proc pStructSpecifier(node: ref Ast, name = "") =
var stmt: string
if node.children.len() == 1 and name notin gTypes:
case node.children[0].sym:
- of "type_identifier":
- let typ = getNodeValIf(node.children[0], "type_identifier")
+ of type_identifier:
+ let typ = getNodeValIf(node.children[0], type_identifier)
if typ.nBl:
gTypes.add(name)
if name != typ:
# typedef struct X Y
- gTypeStr &= &" {name}* = {typ} #1 structSpecifier()\n"
+ gTypeStr &= &" {name}* = {typ} #1 pStructSpecifier()\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 pStructSpecifier()\n"
- of "field_declaration_list":
+ 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 pStructSpecifier()\n"
for field in node.children[0].children:
- let ts = typeScan(field, "field_declaration", "field_identifier", " ")
+ 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")
+ else:
+ discard
+
+ 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 pStructSpecifier()\n"
for field in node.children[1].children:
- let ts = typeScan(field, "field_declaration", "field_identifier", " ")
+ let ts = typeScan(field, field_declaration, field_identifier, " ")
if ts.len() == 0:
return
stmt &= ts & "\n"
@@ -100,33 +103,33 @@ proc structSpecifier(node: ref Ast, name = "") =
gTypes.add(name)
gTypeStr &= stmt
-proc enumSpecifier(node: ref Ast, name = "") =
+proc pEnumSpecifier(node: ref Ast, name = "") =
var
ename: string
elid: int
stmt: string
- if node.children.len() == 1 and node.children[0].sym == "enumerator_list":
+ 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"
- elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == "enumerator_list":
- ename = getNodeValIf(node.children[0], "type_identifier")
+ stmt = &" {name}* = enum #1 pEnumSpecifier()\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 pEnumSpecifier()\n"
else:
return
for field in node.children[elid].children:
- if field.sym == "enumerator":
- let fname = getNodeValIf(field.children[0], "identifier")
+ if field.sym == enumerator:
+ let fname = getNodeValIf(field.children[0], identifier)
if field.children.len() == 1:
stmt &= &" {fname}\n"
- elif field.children.len() == 2 and field.children[1].sym == "number_literal":
- let num = getNodeValIf(field.children[1], "number_literal")
+ elif field.children.len() == 2 and field.children[1].sym == number_literal:
+ let num = getNodeValIf(field.children[1], number_literal)
stmt &= &" {fname} = {num}\n"
else:
return
@@ -135,44 +138,46 @@ proc enumSpecifier(node: ref Ast, name = "") =
gTypes.add(name)
gTypeStr &= stmt
-proc typeDefinition(node: ref Ast) =
+proc pTypeDefinition(node: ref Ast) =
if node.children.len() == 2:
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")
+ 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.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 pTypeDefinition()\n"
elif ttyp.nBl:
# typedef X Y
gTypes.add(name)
- gTypeStr &= &" {name}* = {ttyp} #2 typeDefinition()\n"
+ gTypeStr &= &" {name}* = {ttyp} #2 pTypeDefinition()\n"
else:
case node.children[0].sym:
- of "struct_specifier":
- structSpecifier(node.children[0], name)
- of "enum_specifier":
- enumSpecifier(node.children[0], name)
+ of struct_specifier:
+ pStructSpecifier(node.children[0], name)
+ of enum_specifier:
+ pEnumSpecifier(node.children[0], name)
+ else:
+ discard
-proc functionDeclarator(node: ref Ast, typ: string) =
+proc pFunctionDeclarator(node: ref Ast, typ: string) =
if node.children.len() == 2:
let
- name = getNodeValIf(node.children[0], "identifier")
+ name = getNodeValIf(node.children[0], identifier)
- if name.nBl and name notin gProcs and node.children[1].sym == "parameter_list":
+ if name.nBl and name notin gProcs and node.children[1].sym == parameter_list:
# typ function(typ param1, ...)
- var stmt = &"# functionDeclarator()\nproc {name}*("
+ var stmt = &"# pFunctionDeclarator()\nproc {name}*("
for i in 0 .. node.children[1].children.len()-1:
- let ts = typeScan(node.children[1].children[i], "parameter_declaration", "identifier", "")
+ let ts = typeScan(node.children[1].children[i], parameter_declaration, identifier, "")
if ts.len() == 0:
return
stmt &= ts
@@ -189,38 +194,40 @@ proc functionDeclarator(node: ref Ast, typ: string) =
gProcs.add(name)
gProcStr &= stmt
-proc declaration*(node: ref Ast) =
- if node.children.len() == 2 and node.children[1].sym == "function_declarator":
+proc pDeclaration*(node: ref Ast) =
+ if node.children.len() == 2 and node.children[1].sym == function_declarator:
let
- ptyp = getNodeValIf(node.children[0], "primitive_type")
- ttyp = getNodeValIf(node.children[0], "type_identifier")
+ ptyp = getNodeValIf(node.children[0], primitive_type)
+ ttyp = getNodeValIf(node.children[0], type_identifier)
if ptyp.nBl:
- functionDeclarator(node.children[1], ptyp.getType())
+ pFunctionDeclarator(node.children[1], ptyp.getType())
elif ttyp.nBl:
- functionDeclarator(node.children[1], ttyp)
- elif node.children[0].sym == "struct_specifier" and node.children[0].children.len() == 1:
- let styp = getNodeValIf(node.children[0].children[0], "type_identifier")
+ pFunctionDeclarator(node.children[1], ttyp)
+ elif node.children[0].sym == struct_specifier and node.children[0].children.len() == 1:
+ let styp = getNodeValIf(node.children[0].children[0], type_identifier)
if styp.nBl:
- functionDeclarator(node.children[1], styp)
+ pFunctionDeclarator(node.children[1], styp)
proc genNimAst*(node: ref Ast) =
case node.sym:
- of "ERROR":
+ of ERROR:
let (line, col) = getLineCol(node)
echo &"Potentially invalid syntax at line {line} column {col}"
- of "preproc_def":
- preprocDef(node)
- of "type_definition":
- typeDefinition(node)
- of "declaration":
- declaration(node)
- of "struct_specifier":
- if node.parent.sym notin ["type_definition", "declaration"]:
- structSpecifier(node)
- of "enum_specifier":
- if node.parent.sym notin ["type_definition", "declaration"]:
- enumSpecifier(node)
+ of preproc_def:
+ pPreprocDef(node)
+ of type_definition:
+ pTypeDefinition(node)
+ of declaration:
+ pDeclaration(node)
+ of struct_specifier:
+ if node.parent.sym notin [type_definition, declaration]:
+ pStructSpecifier(node)
+ of enum_specifier:
+ if node.parent.sym notin [type_definition, declaration]:
+ pEnumSpecifier(node)
+ else:
+ discard
for child in node.children:
genNimAst(child)
diff --git a/nimterop/getters.nim b/nimterop/getters.nim
index 1ad4733..b4f9df6 100644
--- a/nimterop/getters.nim
+++ b/nimterop/getters.nim
@@ -16,7 +16,7 @@ proc getLit*(str: string): string =
str.contains(re"^0x[\d]+$"):
return str
-proc getNodeValIf*(node: ref Ast, esym: string): string =
+proc getNodeValIf*(node: ref Ast, esym: Sym): string =
if esym != node.sym:
return
diff --git a/nimterop/globals.nim b/nimterop/globals.nim
index 9802417..6ace9f5 100644
--- a/nimterop/globals.nim
+++ b/nimterop/globals.nim
@@ -1,9 +1,20 @@
import macros
type
+ Sym* = enum
+ ERROR, IGNORED,
+ enumerator, enumerator_list, enum_specifier,
+ declaration,
+ field_declaration, field_declaration_list, field_identifier, function_declarator,
+ identifier,
+ number_literal,
+ parameter_declaration, parameter_list, pointer_declarator, preproc_arg, preproc_def, primitive_type,
+ struct_specifier,
+ type_definition, type_identifier
+
Ast* = object
- sym*: string
- start*, stop*: int
+ sym*: Sym
+ start*, stop*: uint32
parent*: ref Ast
children*: seq[ref Ast]
diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim
index 6e49197..cf723b7 100644
--- a/nimterop/lisp.nim
+++ b/nimterop/lisp.nim
@@ -24,6 +24,10 @@ proc tokenize(fullpath: string) =
else:
collect &= $i
+ if gTokens.len() == 0:
+ echo "toast binary not installed - nimble install nimterop to force build"
+ quit(1)
+
proc readFromTokens(): ref Ast =
if idx == gTokens.len():
echo "Bad AST"
@@ -35,14 +39,17 @@ proc readFromTokens(): ref Ast =
quit(1)
if gTokens[idx+1] != "comment":
result = new(Ast)
- result.sym = gTokens[idx+1]
- result.start = gTokens[idx+2].parseInt()
- result.stop = gTokens[idx+3].parseInt()
+ try:
+ result.sym = parseEnum[Sym](gTokens[idx+1])
+ except:
+ result.sym = IGNORED
+ result.start = gTokens[idx+2].parseInt().uint32
+ result.stop = gTokens[idx+3].parseInt().uint32
result.children = @[]
idx += 4
while gTokens[idx] != ")":
var res = readFromTokens()
- if not res.isNil() and res.sym.nBl:
+ if not res.isNil():
res.parent = result
result.children.add(res)
elif gTokens[idx] == ")":
@@ -52,7 +59,7 @@ proc readFromTokens(): ref Ast =
idx += 1
proc printAst*(node: ref Ast, offset=""): string =
- result = offset & "(" & node.sym & " " & $node.start & " " & $node.stop
+ result = offset & "(" & $node.sym & " " & $node.start & " " & $node.stop
if node.children.len() != 0:
result &= "\n"
for child in node.children: