diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2008-08-14T10·04+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2008-08-14T10·04+0000 |
commit | efe4b690ae4de5f0adea99abb1176a64a099d433 (patch) | |
tree | 3ee26b49848b04b5f6dad8edc06509fe4d4ee067 /src/libexpr/nixexpr.cc | |
parent | c03b729319997b4e38c3f586d7c76352228b22e7 (diff) |
* Refactoring: combine functions that take an attribute set and
functions that take a single argument (plain lambdas) into one AST node (Function) that contains a Pattern node describing the arguments. Current patterns are single lazy arguments (VarPat) and matching against an attribute set (AttrsPat). This refactoring allows other kinds of patterns to be added easily, such as Haskell-style @-patterns, or list pattern matching.
Diffstat (limited to 'src/libexpr/nixexpr.cc')
-rw-r--r-- | src/libexpr/nixexpr.cc | 67 |
1 files changed, 30 insertions, 37 deletions
diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 310f714718fe..4744cdde39ad 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -110,6 +110,25 @@ Expr makeAttrs(const ATermMap & attrs) } +static void varsBoundByPattern(ATermMap & map, Pattern pat) +{ + ATerm name; + ATermList formals; + /* Use makeRemoved() so that it can be used directly in + substitute(). */ + if (matchVarPat(pat, name)) + map.set(name, makeRemoved()); + else if (matchAttrsPat(pat, formals)) { + for (ATermIterator i(formals); i; ++i) { + ATerm d1; + if (!matchFormal(*i, name, d1)) abort(); + map.set(name, makeRemoved()); + } + } + else abort(); +} + + Expr substitute(const Substitution & subs, Expr e) { checkInterrupt(); @@ -135,27 +154,17 @@ Expr substitute(const Substitution & subs, Expr e) /* In case of a function, filter out all variables bound by this function. */ - ATermList formals; + Pattern pat; ATerm body; - if (matchFunction(e, formals, body, pos)) { - ATermMap map(ATgetLength(formals)); - for (ATermIterator i(formals); i; ++i) { - ATerm d1; - if (!matchFormal(*i, name, d1)) abort(); - map.set(name, makeRemoved()); - } + if (matchFunction(e, pat, body, pos)) { + ATermMap map(16); + varsBoundByPattern(map, pat); Substitution subs2(&subs, &map); return makeFunction( - (ATermList) substitute(subs2, (ATerm) formals), + (Pattern) substitute(subs2, (Expr) pat), substitute(subs2, body), pos); } - if (matchFunction1(e, name, body, pos)) { - ATermMap map(1); - map.set(name, makeRemoved()); - return makeFunction1(name, substitute(Substitution(&subs, &map), body), pos); - } - /* Idem for a mutually recursive attribute set. */ ATermList rbnds, nrbnds; if (matchRec(e, rbnds, nrbnds)) { @@ -213,9 +222,9 @@ static void checkVarDefs2(set<Expr> & done, const ATermMap & defs, Expr e) done.insert(e); ATerm name, pos, value; - ATermList formals; ATerm with, body; ATermList rbnds, nrbnds; + Pattern pat; /* Closed terms don't have free variables, so we don't have to check by definition. */ @@ -227,27 +236,11 @@ static void checkVarDefs2(set<Expr> & done, const ATermMap & defs, Expr e) % aterm2String(name)); } - else if (matchFunction(e, formals, body, pos)) { - ATermMap defs2(defs); - for (ATermIterator i(formals); i; ++i) { - ATerm d1; - if (!matchFormal(*i, name, d1)) abort(); - defs2.set(name, (ATerm) ATempty); - } - for (ATermIterator i(formals); i; ++i) { - ATerm deflt; - set<Expr> done2; - if (!matchFormal(*i, name, deflt)) abort(); - checkVarDefs2(done2, defs2, deflt); - } - set<Expr> done2; - checkVarDefs2(done2, defs2, body); - } - - else if (matchFunction1(e, name, body, pos)) { + else if (matchFunction(e, pat, body, pos)) { ATermMap defs2(defs); - defs2.set(name, (ATerm) ATempty); + varsBoundByPattern(defs2, pat); set<Expr> done2; + checkVarDefs2(done2, defs2, pat); checkVarDefs2(done2, defs2, body); } @@ -365,13 +358,13 @@ string showType(Expr e) ATermList l1; ATermBlob b1; int i1; + Pattern p1; if (matchStr(e, t1, l1)) return "a string"; if (matchPath(e, t1)) return "a path"; if (matchNull(e)) return "null"; if (matchInt(e, i1)) return "an integer"; if (matchBool(e, t1)) return "a boolean"; - if (matchFunction(e, l1, t1, t2)) return "a function"; - if (matchFunction1(e, t1, t2, t3)) return "a function"; + if (matchFunction(e, p1, t1, t2)) return "a function"; if (matchAttrs(e, l1)) return "an attribute set"; if (matchList(e, l1)) return "a list"; if (matchPrimOp(e, i1, b1, l1)) return "a partially applied built-in function"; |