diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2018-11-21 17:24:13 -0600 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2018-11-21 17:24:13 -0600 |
| commit | c0481ac41c84bb34326058ad8db7cf74b35fcb82 (patch) | |
| tree | ad85a135738d18dc778e38a178e960a6126daf4a | |
| parent | 01c295a41c6f80e8999db07f9b07d29943f98040 (diff) | |
| download | nimterop-c0481ac41c84bb34326058ad8db7cf74b35fcb82.tar.gz nimterop-c0481ac41c84bb34326058ad8db7cf74b35fcb82.zip | |
Use enums for sym, fail if no toast
| -rw-r--r-- | nimterop/ast.nim | 151 | ||||
| -rw-r--r-- | nimterop/getters.nim | 2 | ||||
| -rw-r--r-- | nimterop/globals.nim | 15 | ||||
| -rw-r--r-- | nimterop/lisp.nim | 17 |
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: |
