* String/path concatenation operator (`+').
This commit is contained in:
parent
ee401afad8
commit
9fa07b376d
6 changed files with 43 additions and 5 deletions
5
NEWS
5
NEWS
|
@ -49,8 +49,13 @@ Major changes include the following:
|
||||||
|
|
||||||
* Nix expression language changes:
|
* 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.
|
* Added a `map' function.
|
||||||
|
|
||||||
|
* Various new operators (e.g., string concatenation).
|
||||||
|
|
||||||
* An Emacs mode for editing Nix expressions (with syntax highlighting
|
* An Emacs mode for editing Nix expressions (with syntax highlighting
|
||||||
and indentation) has been added.
|
and indentation) has been added.
|
||||||
|
|
||||||
|
|
|
@ -338,6 +338,20 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
return makeBool(attrs.get(name) != 0);
|
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. */
|
/* Barf. */
|
||||||
throw badTerm("invalid expression", e);
|
throw badTerm("invalid expression", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,3 +364,15 @@ Expr makeBool(bool b)
|
||||||
{
|
{
|
||||||
return b ? ATmake("Bool(True)") : ATmake("Bool(False)");
|
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());
|
||||||
|
}
|
||||||
|
|
|
@ -92,5 +92,11 @@ void checkVarDefs(const ATermMap & def, Expr e);
|
||||||
/* Create an expression representing a boolean. */
|
/* Create an expression representing a boolean. */
|
||||||
Expr makeBool(bool b);
|
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 */
|
#endif /* !__NIXEXPR_H */
|
||||||
|
|
|
@ -53,6 +53,7 @@ ATerm makePos(YYLTYPE * loc, void * data)
|
||||||
%nonassoc EQ NEQ
|
%nonassoc EQ NEQ
|
||||||
%right UPDATE
|
%right UPDATE
|
||||||
%left NEG
|
%left NEG
|
||||||
|
%left '+'
|
||||||
%nonassoc '?'
|
%nonassoc '?'
|
||||||
%nonassoc '~'
|
%nonassoc '~'
|
||||||
|
|
||||||
|
@ -90,6 +91,7 @@ expr_op
|
||||||
| expr_op UPDATE expr_op { $$ = ATmake("OpUpdate(<term>, <term>)", $1, $3); }
|
| expr_op UPDATE expr_op { $$ = ATmake("OpUpdate(<term>, <term>)", $1, $3); }
|
||||||
| expr_op '~' expr_op { $$ = ATmake("SubPath(<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 '?' ID { $$ = ATmake("OpHasAttr(<term>, <term>)", $1, $3); }
|
||||||
|
| expr_op '+' expr_op { $$ = ATmake("OpPlus(<term>, <term>)", $1, $3); }
|
||||||
| expr_app
|
| expr_app
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -273,8 +273,8 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args)
|
||||||
|
|
||||||
attrs.set("outPath", ATmake("(Path(<str>), NoPos)", outPath.c_str()));
|
attrs.set("outPath", ATmake("(Path(<str>), NoPos)", outPath.c_str()));
|
||||||
attrs.set("drvPath", ATmake("(Path(<str>), NoPos)", drvPath.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("drvHash", ATmake("(<term>, NoPos)", makeString(drvHash)));
|
||||||
attrs.set("type", ATmake("(Str(\"derivation\"), NoPos)"));
|
attrs.set("type", ATmake("(<term>, NoPos)", makeString("derivation")));
|
||||||
|
|
||||||
return makeAttrs(attrs);
|
return makeAttrs(attrs);
|
||||||
}
|
}
|
||||||
|
@ -284,8 +284,7 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args)
|
||||||
following the last slash. */
|
following the last slash. */
|
||||||
static Expr primBaseNameOf(EvalState & state, const ATermVector & args)
|
static Expr primBaseNameOf(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
string s = evalString(state, args[0]);
|
return makeString(baseNameOf(evalString(state, args[0])));
|
||||||
return ATmake("Str(<str>)", baseNameOf(s).c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -298,7 +297,7 @@ static Expr primToString(EvalState & state, const ATermVector & args)
|
||||||
if (atMatch(m, arg) >> "Str" >> s ||
|
if (atMatch(m, arg) >> "Str" >> s ||
|
||||||
atMatch(m, arg) >> "Path" >> s ||
|
atMatch(m, arg) >> "Path" >> s ||
|
||||||
atMatch(m, arg) >> "Uri" >> s)
|
atMatch(m, arg) >> "Uri" >> s)
|
||||||
return ATmake("Str(<str>)", s.c_str());
|
return makeString(s);
|
||||||
else throw Error("cannot coerce value to string");
|
else throw Error("cannot coerce value to string");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue