-
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
366 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#pragma once | ||
|
||
#include <nix/nixexpr.hh> | ||
|
||
namespace nixt { | ||
|
||
nix::PosIdx displOf(const nix::Expr *E, nix::Displacement Displ); | ||
|
||
nix::PosIdx displOf(const nix::ExprAttrs *E, nix::Displacement Displ); | ||
|
||
nix::PosIdx displOf(const nix::ExprLet *E, nix::Displacement Displ); | ||
|
||
nix::PosIdx displOf(const nix::ExprLambda *E, nix::Displacement Displ); | ||
|
||
} // namespace nixt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#pragma once | ||
|
||
#include <nix/nixexpr.hh> | ||
|
||
namespace nixt { | ||
|
||
// Get printable name of some expression | ||
const char *nameOf(const nix::Expr *E); | ||
|
||
} // namespace nixt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/// Nodes.inc, nix expressions declaration. | ||
/// \file | ||
/// This record file provides NIX_EXPR macro that contains all names of | ||
/// nix::Expr | ||
|
||
#ifdef NIX_EXPR | ||
|
||
NIX_EXPR(ExprAssert) | ||
NIX_EXPR(ExprAttrs) | ||
NIX_EXPR(ExprCall) | ||
NIX_EXPR(ExprConcatStrings) | ||
NIX_EXPR(ExprFloat) | ||
NIX_EXPR(ExprIf) | ||
NIX_EXPR(ExprInt) | ||
NIX_EXPR(ExprLambda) | ||
NIX_EXPR(ExprLet) | ||
NIX_EXPR(ExprList) | ||
NIX_EXPR(ExprOpAnd) | ||
NIX_EXPR(ExprOpConcatLists) | ||
NIX_EXPR(ExprOpEq) | ||
NIX_EXPR(ExprOpHasAttr) | ||
NIX_EXPR(ExprOpImpl) | ||
NIX_EXPR(ExprOpNEq) | ||
NIX_EXPR(ExprOpNot) | ||
NIX_EXPR(ExprOpOr) | ||
NIX_EXPR(ExprOpUpdate) | ||
NIX_EXPR(ExprPath) | ||
NIX_EXPR(ExprPos) | ||
NIX_EXPR(ExprSelect) | ||
NIX_EXPR(ExprString) | ||
NIX_EXPR(ExprVar) | ||
NIX_EXPR(ExprWith) | ||
|
||
#endif // NIX_EXPR |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#pragma once | ||
|
||
#include "Visitor.h" | ||
|
||
namespace nixt { | ||
|
||
using ParentMap = std::map<const nix::Expr *, const nix::Expr *>; | ||
|
||
ParentMap parentMap(const nix::Expr *Root); | ||
|
||
} // namespace nixt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/// Traverse.inc, the file declares how to traverse nix::Expr | ||
/// | ||
/// The file provides: DEF_TRAVERSE_TYPE(Name, Stmt) | ||
/// Stmt defines how to traverse AST nodes (i.e. visit it's subnodes) | ||
/// The subnodes is wrapped around with macro TRY_TO_TRAVERSE. | ||
|
||
#ifdef DEF_TRAVERSE_TYPE | ||
|
||
DEF_TRAVERSE_TYPE(ExprAssert, { | ||
TRY_TO_TRAVERSE(T->cond); | ||
TRY_TO_TRAVERSE(T->body); | ||
}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprAttrs, { | ||
for (auto &[_, Elem] : T->attrs) | ||
TRY_TO_TRAVERSE(Elem.e); | ||
for (auto &DAD : T->dynamicAttrs) { | ||
TRY_TO_TRAVERSE(DAD.nameExpr); | ||
TRY_TO_TRAVERSE(DAD.valueExpr); | ||
} | ||
}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprCall, { | ||
for (auto &Arg : T->args) | ||
TRY_TO_TRAVERSE(Arg); | ||
TRY_TO_TRAVERSE(T->fun); | ||
}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprConcatStrings, { | ||
for (auto &[_, E] : *T->es) | ||
TRY_TO_TRAVERSE(E); | ||
}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprFloat, {}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprIf, { | ||
TRY_TO_TRAVERSE(T->cond); | ||
TRY_TO_TRAVERSE(T->then); | ||
TRY_TO_TRAVERSE(T->else_); | ||
}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprInt, {}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprLambda, { | ||
if (T->hasFormals()) | ||
for (auto &F : T->formals->formals) | ||
TRY_TO_TRAVERSE(F.def); | ||
TRY_TO_TRAVERSE(T->body); | ||
}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprLet, { | ||
TRY_TO_TRAVERSE(T->attrs); | ||
TRY_TO_TRAVERSE(T->body); | ||
}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprList, { | ||
for (auto &E : T->elems) | ||
TRY_TO_TRAVERSE(E); | ||
}) | ||
|
||
#define DEF_TRAVERSE_BINARY_EXPR(BIN_OP) \ | ||
DEF_TRAVERSE_TYPE(BIN_OP, { \ | ||
TRY_TO_TRAVERSE(T->e1); \ | ||
TRY_TO_TRAVERSE(T->e2); \ | ||
}) | ||
|
||
DEF_TRAVERSE_BINARY_EXPR(ExprOpAnd) | ||
DEF_TRAVERSE_BINARY_EXPR(ExprOpConcatLists) | ||
DEF_TRAVERSE_BINARY_EXPR(ExprOpEq) | ||
DEF_TRAVERSE_BINARY_EXPR(ExprOpImpl) | ||
DEF_TRAVERSE_BINARY_EXPR(ExprOpNEq) | ||
DEF_TRAVERSE_BINARY_EXPR(ExprOpOr) | ||
DEF_TRAVERSE_BINARY_EXPR(ExprOpUpdate) | ||
|
||
#undef DEF_TRAVERSE_BINARY_EXPR | ||
|
||
DEF_TRAVERSE_TYPE(ExprOpHasAttr, { | ||
TRY_TO_TRAVERSE(T->e); | ||
for (auto &E : T->attrPath) | ||
if (!E.symbol) | ||
TRY_TO_TRAVERSE(E.expr); | ||
}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprOpNot, { TRY_TO_TRAVERSE(T->e); }) | ||
|
||
DEF_TRAVERSE_TYPE(ExprPath, {}) | ||
DEF_TRAVERSE_TYPE(ExprPos, {}) | ||
DEF_TRAVERSE_TYPE(ExprSelect, { | ||
TRY_TO_TRAVERSE(T->def); | ||
TRY_TO_TRAVERSE(T->e); | ||
for (auto &E : T->attrPath) { | ||
if (!E.symbol) | ||
TRY_TO_TRAVERSE(E.expr); | ||
} | ||
}) | ||
|
||
DEF_TRAVERSE_TYPE(ExprString, {}) | ||
DEF_TRAVERSE_TYPE(ExprVar, {}) | ||
DEF_TRAVERSE_TYPE(ExprWith, { | ||
TRY_TO_TRAVERSE(T->attrs); | ||
TRY_TO_TRAVERSE(T->body); | ||
}) | ||
|
||
#endif // DEF_TRAVERSE_TYPE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/// Visitor.h, describe how to traverse upon nix::Expr * nodes. | ||
#pragma once | ||
|
||
#include <nix/nixexpr.hh> | ||
#include <nix/symbol-table.hh> | ||
|
||
namespace nixt { | ||
|
||
template <class Derived> struct RecursiveASTVisitor { | ||
|
||
bool shouldTraversePostOrder() { return false; } | ||
|
||
bool visitExpr(const nix::Expr *) { return true; } | ||
|
||
#define NIX_EXPR(EXPR) bool traverse##EXPR(const nix::EXPR *E); | ||
#include "Nodes.inc" | ||
#undef NIX_EXPR | ||
|
||
#define NIX_EXPR(EXPR) \ | ||
bool visit##EXPR(const nix::EXPR *E) { return getDerived().visitExpr(E); } | ||
#include "Nodes.inc" | ||
#undef NIX_EXPR | ||
|
||
Derived &getDerived() { return *static_cast<Derived *>(this); } | ||
|
||
bool traverseExpr(const nix::Expr *E) { | ||
if (!E) | ||
return true; | ||
#define NIX_EXPR(EXPR) \ | ||
if (auto CE = dynamic_cast<const nix::EXPR *>(E)) { \ | ||
return getDerived().traverse##EXPR(CE); \ | ||
} | ||
#include "Nodes.inc" | ||
#undef NIX_EXPR | ||
assert(false && "We are missing some nix AST Nodes!"); | ||
return true; | ||
} | ||
}; | ||
|
||
#define TRY_TO(CALL_EXPR) \ | ||
do { \ | ||
if (!getDerived().CALL_EXPR) \ | ||
return false; \ | ||
} while (false) | ||
|
||
#define TRY_TO_TRAVERSE(EXPR) TRY_TO(traverseExpr(EXPR)) | ||
|
||
#define DEF_TRAVERSE_TYPE(TYPE, CODE) \ | ||
template <typename Derived> \ | ||
bool RecursiveASTVisitor<Derived>::traverse##TYPE(const nix::TYPE *T) { \ | ||
if (!getDerived().shouldTraversePostOrder()) \ | ||
TRY_TO(visit##TYPE(T)); \ | ||
{ CODE; } \ | ||
if (getDerived().shouldTraversePostOrder()) \ | ||
TRY_TO(visit##TYPE(T)); \ | ||
return true; \ | ||
} | ||
#include "Traverse.inc" | ||
#undef DEF_TRAVERSE_TYPE | ||
#undef TRY_TO_TRAVERSE | ||
|
||
} // namespace nixt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include "nixt/Displacement.h" | ||
|
||
namespace nixt { | ||
|
||
nix::PosIdx displOf(const nix::Expr *E, nix::Displacement Displ) { | ||
if (const auto *CE = dynamic_cast<const nix::ExprAttrs *>(E)) | ||
return displOf(CE, Displ); | ||
if (const auto *CE = dynamic_cast<const nix::ExprLet *>(E)) | ||
return displOf(CE, Displ); | ||
if (const auto *CE = dynamic_cast<const nix::ExprLambda *>(E)) | ||
return displOf(CE, Displ); | ||
|
||
assert(false && "The requested expr is not an env creator"); | ||
return nix::noPos; // unreachable | ||
} | ||
|
||
nix::PosIdx displOf(const nix::ExprAttrs *E, nix::Displacement Displ) { | ||
assert(E->recursive && "Only recursive ExprAttr has displacement values"); | ||
|
||
auto DefIt = E->attrs.begin(); | ||
std::advance(DefIt, Displ); | ||
|
||
return DefIt->second.pos; | ||
} | ||
|
||
nix::PosIdx displOf(const nix::ExprLet *E, nix::Displacement Displ) { | ||
auto DefIt = E->attrs->attrs.begin(); | ||
std::advance(DefIt, Displ); | ||
|
||
return DefIt->second.pos; | ||
} | ||
|
||
nix::PosIdx displOf(const nix::ExprLambda *E, nix::Displacement Displ) { | ||
if (E->arg) { | ||
if (Displ == 0) | ||
// It is just a symbol, so noPos. | ||
return nix::noPos; | ||
Displ--; | ||
} | ||
|
||
assert(E->hasFormals() && "Lambda must has formals to create displ"); | ||
return E->formals->formals[Displ].pos; | ||
} | ||
|
||
} // namespace nixt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#include "nixt/Name.h" | ||
|
||
namespace nixt { | ||
|
||
const char *nameOf(const nix::Expr *E) { | ||
#define NIX_EXPR(EXPR) \ | ||
if (dynamic_cast<const nix::EXPR *>(E)) { \ | ||
return #EXPR; \ | ||
} | ||
#include "nixt/Nodes.inc" | ||
assert(false && | ||
"Cannot dynamic-cast to nix::Expr*, missing entries in Nodes.inc?"); | ||
return nullptr; | ||
#undef NIX_EXPR | ||
} | ||
|
||
} // namespace nixt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include "nixt/ParentMap.h" | ||
|
||
namespace nixt { | ||
|
||
ParentMap parentMap(const nix::Expr *Root) { | ||
ParentMap Ret; | ||
struct VisitorClass : RecursiveASTVisitor<VisitorClass> { | ||
/// The parent before traverseExpr | ||
const nix::Expr *ParentExpr; | ||
ParentMap *CapturedRet; | ||
|
||
bool traverseExpr(const nix::Expr *E) { | ||
CapturedRet->insert({E, ParentExpr}); | ||
const auto *OldParent = ParentExpr; | ||
ParentExpr = E; // Set the parent into the visitor, it should be the | ||
// parent when we are traversing child nodes. | ||
if (!RecursiveASTVisitor<VisitorClass>::traverseExpr(E)) | ||
return false; | ||
|
||
// After traversing on childrens finished, set parent expr to previous | ||
// parent. | ||
ParentExpr = OldParent; | ||
return true; | ||
} | ||
|
||
} Visitor; | ||
|
||
Visitor.ParentExpr = Root; | ||
Visitor.CapturedRet = &Ret; | ||
|
||
Visitor.traverseExpr(Root); | ||
|
||
return Ret; | ||
} | ||
|
||
} // namespace nixt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
nix_main = dependency('nix-main') | ||
nix_expr = dependency('nix-expr') | ||
nix_cmd = dependency('nix-cmd') | ||
|
||
libnixtDeps = [ nix_expr, nix_main, nix_cmd, boost ] | ||
|
||
libnixdInc = include_directories('include') | ||
|
||
libnixt = library('nixt', | ||
'lib/Displacement.cpp', | ||
'lib/Name.cpp', | ||
'lib/ParentMap.cpp', | ||
include_directories: libnixdInc, | ||
dependencies: libnixtDeps, | ||
install: true | ||
) | ||
|
||
pkgconfig.generate(name: 'libnixt', | ||
version: 'nightly', | ||
description: 'nix tooling', | ||
subdirs: [ 'nixt' ], | ||
libraries: libnixt | ||
) | ||
|
||
|
||
nixt = declare_dependency(include_directories: libnixdInc, | ||
dependencies: libnixtDeps, | ||
link_with: libnixt | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters