diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2004-10-26T17·01+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2004-10-26T17·01+0000 |
commit | 9fa07b376dd52ee8bbcc074e59d36af3f3f2536d (patch) | |
tree | ef2d6d8d32b8a7c87c5396ab3b34b7fafa3810f1 | |
parent | ee401afad81dc7759c66829372826f98268ae606 (diff) |
* String/path concatenation operator (`+').
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | src/libexpr/eval.cc | 14 | ||||
-rw-r--r-- | src/libexpr/nixexpr.cc | 12 | ||||
-rw-r--r-- | src/libexpr/nixexpr.hh | 6 | ||||
-rw-r--r-- | src/libexpr/parser.y | 2 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 9 |
6 files changed, 43 insertions, 5 deletions
diff --git a/NEWS b/NEWS index b130b4c50064..c4d84740bd7f 100644 --- a/NEWS +++ b/NEWS @@ -49,8 +49,13 @@ Major changes include the following: * Nix expression language changes: + * New language construct: `with E1; E2' brings all attributes + defined in the attribute set E1 in scope in E2. + * Added a `map' function. + * Various new operators (e.g., string concatenation). + * An Emacs mode for editing Nix expressions (with syntax highlighting and indentation) has been added. diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 215692aeb313..4454aaec452f 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -338,6 +338,20 @@ Expr evalExpr2(EvalState & state, Expr e) return makeBool(attrs.get(name) != 0); } + /* String or path concatenation. */ + if (atMatch(m, e) >> "OpPlus" >> e1 >> e2) { + e1 = evalExpr(state, e1); + e2 = evalExpr(state, e2); + string s1, s2; + if (atMatch(m, e1) >> "Str" >> s1 && + atMatch(m, e2) >> "Str" >> s2) + return makeString(s1 + s2); + else if (atMatch(m, e1) >> "Path" >> s1 && + atMatch(m, e2) >> "Path" >> s2) + return makeString(canonPath(s1 + "/" + s2)); + else throw Error("wrong argument types in `+' operator"); + } + /* Barf. */ throw badTerm("invalid expression", e); } diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 78f89db5e5d3..37288804d0eb 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -364,3 +364,15 @@ Expr makeBool(bool b) { return b ? ATmake("Bool(True)") : ATmake("Bool(False)"); } + + +Expr makeString(const string & s) +{ + return ATmake("Str(<str>)", s.c_str()); +} + + +Expr makePath(const Path & path) +{ + return ATmake("Path(<str>)", path.c_str()); +} diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 30145c87b344..657e6055c40e 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -92,5 +92,11 @@ void checkVarDefs(const ATermMap & def, Expr e); /* Create an expression representing a boolean. */ Expr makeBool(bool b); +/* Create an expression representing a string. */ +Expr makeString(const string & s); + +/* Create an expression representing a path. */ +Expr makePath(const Path & path); + #endif /* !__NIXEXPR_H */ diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 88ee8326b8d3..c56d89809f49 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -53,6 +53,7 @@ ATerm makePos(YYLTYPE * loc, void * data) %nonassoc EQ NEQ %right UPDATE %left NEG +%left '+' %nonassoc '?' %nonassoc '~' @@ -90,6 +91,7 @@ expr_op | expr_op UPDATE expr_op { $$ = ATmake("OpUpdate(<term>, <term>)", $1, $3); } | expr_op '~' expr_op { $$ = ATmake("SubPath(<term>, <term>)", $1, $3); } | expr_op '?' ID { $$ = ATmake("OpHasAttr(<term>, <term>)", $1, $3); } + | expr_op '+' expr_op { $$ = ATmake("OpPlus(<term>, <term>)", $1, $3); } | expr_app ; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 938d9bb8c13b..ade483dc703d 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -273,8 +273,8 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args) attrs.set("outPath", ATmake("(Path(<str>), NoPos)", outPath.c_str())); attrs.set("drvPath", ATmake("(Path(<str>), NoPos)", drvPath.c_str())); - attrs.set("drvHash", ATmake("(Str(<str>), NoPos)", ((string) drvHash).c_str())); - attrs.set("type", ATmake("(Str(\"derivation\"), NoPos)")); + attrs.set("drvHash", ATmake("(<term>, NoPos)", makeString(drvHash))); + attrs.set("type", ATmake("(<term>, NoPos)", makeString("derivation"))); return makeAttrs(attrs); } @@ -284,8 +284,7 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args) following the last slash. */ static Expr primBaseNameOf(EvalState & state, const ATermVector & args) { - string s = evalString(state, args[0]); - return ATmake("Str(<str>)", baseNameOf(s).c_str()); + return makeString(baseNameOf(evalString(state, args[0]))); } @@ -298,7 +297,7 @@ static Expr primToString(EvalState & state, const ATermVector & args) if (atMatch(m, arg) >> "Str" >> s || atMatch(m, arg) >> "Path" >> s || atMatch(m, arg) >> "Uri" >> s) - return ATmake("Str(<str>)", s.c_str()); + return makeString(s); else throw Error("cannot coerce value to string"); } |