aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc9
-rw-r--r--src/libexpr/print.cc20
-rw-r--r--src/libexpr/print.hh6
3 files changed, 31 insertions, 4 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index e2b455b91..af9d037ec 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -94,7 +94,6 @@ RootValue allocRootValue(Value * v)
#endif
}
-
void Value::print(const SymbolTable & symbols, std::ostream & str,
std::set<const void *> * seen) const
{
@@ -122,7 +121,13 @@ void Value::print(const SymbolTable & symbols, std::ostream & str,
else {
str << "{ ";
for (auto & i : attrs->lexicographicOrder(symbols)) {
- str << symbols[i->name] << " = ";
+ // Quote reserved keywords so that the output can be
+ // re-evaluated later without upsetting the lexer.
+ if (isReservedKeyword(symbols[i->name])) {
+ str << "\"" << symbols[i->name] << "\" = ";
+ } else {
+ str << symbols[i->name] << " = ";
+ }
i->value->print(symbols, str, seen);
str << "; ";
}
diff --git a/src/libexpr/print.cc b/src/libexpr/print.cc
index d08672cfc..53ba70bdd 100644
--- a/src/libexpr/print.cc
+++ b/src/libexpr/print.cc
@@ -1,4 +1,5 @@
#include "print.hh"
+#include <unordered_set>
namespace nix {
@@ -25,11 +26,26 @@ printLiteralBool(std::ostream & str, bool boolean)
return str;
}
+// Returns `true' is a string is a reserved keyword which requires quotation
+// when printing attribute set field names.
+//
+// This list should generally be kept in sync with `./lexer.l'.
+// You can test if a keyword needs to be added by running:
+// $ nix eval --expr '{ <KEYWORD> = 1; }'
+// For example `or' doesn't need to be quoted.
+bool isReservedKeyword(const std::string_view str)
+{
+ static const std::unordered_set<std::string_view> reservedKeywords = {
+ "if", "then", "else", "assert", "with", "let", "in", "rec", "inherit"
+ };
+ return reservedKeywords.contains(str);
+}
+
std::ostream &
printIdentifier(std::ostream & str, std::string_view s) {
if (s.empty())
str << "\"\"";
- else if (s == "if") // FIXME: handle other keywords
+ else if (isReservedKeyword(s))
str << '"' << s << '"';
else {
char c = s[0];
@@ -50,10 +66,10 @@ printIdentifier(std::ostream & str, std::string_view s) {
return str;
}
-// FIXME: keywords
static bool isVarName(std::string_view s)
{
if (s.size() == 0) return false;
+ if (isReservedKeyword(s)) return false;
char c = s[0];
if ((c >= '0' && c <= '9') || c == '-' || c == '\'') return false;
for (auto & i : s)
diff --git a/src/libexpr/print.hh b/src/libexpr/print.hh
index f9cfc3964..3b72ae201 100644
--- a/src/libexpr/print.hh
+++ b/src/libexpr/print.hh
@@ -36,6 +36,12 @@ namespace nix {
std::ostream & printAttributeName(std::ostream & o, std::string_view s);
/**
+ * Returns `true' is a string is a reserved keyword which requires quotation
+ * when printing attribute set field names.
+ */
+ bool isReservedKeyword(const std::string_view str);
+
+ /**
* Print a string as an identifier in the Nix expression language syntax.
*
* FIXME: "identifier" is ambiguous. Identifiers do not have a single