readme
Statically typed wrapper for nim ast at compile (NimNode
) and rutime
(PNode
). Another take on solving problem of node[0][0][1][0]
.
Mostly concerned with processing of types and procedure declarations.
Installation
Links
Description
Provides logical structure for objects/fields - you can set/get type,
check if field is a switch for case statement or not. Visit
eachField
in the object, map object to some code structure.
import hnimast, hnimast/obj_field_macros
import hpprint
let node = """
type Type = object
hello: float
""".parsePNodeStr()
var obj = parseObject(node, parsePPragma)
echo "# ~~~~ make object exported ~~~~ #"
obj.exported = true
echo obj.toNNode()
echo "# ~~~~ internal structure of object ~~~~ #"
pprint obj
# ~~~~ make object exported ~~~~ # Type* = object hello: float # ~~~~ internal structure of object ~~~~ # Object[ast.PNode, Pragma[ast.PNode]] exported: true annotation: Option[Pragma[ast.PNode]] val: Pragma[ast.PNode](kind: oakCaseOfBranch, elements: []) has: false name: NType[ast.PNode] kind: ntkIdent head: "Type" genParams: [] flds: - ObjectField[ast.PNode, Pragma[ast.PNode]] annotation: Option[Pragma[ast.PNode]] val: Pragma[ast.PNode] kind: oakCaseOfBranch elements: [] has: false value: Option[ast.PNode](val: <nil tree>) exported: false isTuple: false name: "hello" fldType: NType[ast.PNode] kind: ntkIdent head: "float" genParams: [] isKind: false
- working with enums
-
parseEnumImpl
- parse as enum implementation. Tested on alias, symbol, value, enum-as-generic-parameter,typedesc[Enum]
etc. -
getEnumPref
- for NEP-conforming enums (prefixEnumValueName
) getprefix
-
getEnumNames
- get list of all enum names -
enumNames
- macro. Generateseq[string]
of names for all enums.
-
- working with object declarations
-
ObjectBranch
,Object
andObjectField
types - wrappers on top of nim object declarations. Supports arbitrarily named case fields, annotations for objects etc. Currently does not cover all possible cases. -
eachField
- visit each field in object -
eachField
- recursively generatecase
expression for each possible and use insert result of callback for each field. For use case example see tests/tHnimAst.nim - can be conveted to and from
NimNode
-
eachCase
- generate case statement for object’s kind fields -
eachParallelCase
- generate case statement for two object’s kind fields. eachPath
-
- working with object values
-
ObjTree
- ‘stringly typed’ representation of object value. mainly used inhpprint
, but due to dependency reasons type definitions is still here.
-
Contribution & development
If you have any question about implementation, API etc. you can join my discord server and ask there.
Right now not all possible ast combinations are covered, more testing is necessary.
Ideas:
- [ ] Genereate wrappers for sourcetrail code indexer software library using libclang wrapper. Most groundwork has already been done - it should be relatively simple to assemble all pieces together.
- [ ] Generate graphviz graph of object dependencies using graphviz wrapper - basically the same as sourcetrail DB, just easier to implement as it does not require working with C++ bindings.
- [ ] Having more ‘typed’ representation of of object opens possibilities for things like refactoring, building graphs of object dependencies (which one uses another as field etc). Right now I don’t have any concrete ideas, but something like this might be easier to implement when we know logical structure of an object.