From d308aeaf53b7324af98dfa949a747526c241ef30 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 19 Aug 2013 12:35:03 +0200 Subject: [PATCH] Store Nix integers as longs So on 64-bit systems, integers are now 64-bit. Fixes #158. --- src/libexpr/eval.cc | 4 ++-- src/libexpr/eval.hh | 2 +- src/libexpr/lexer.l | 6 ++++-- src/libexpr/nixexpr.hh | 4 ++-- src/libexpr/parser.y | 2 +- src/libexpr/primops.cc | 2 +- src/libexpr/value.hh | 13 ++++++++----- src/libutil/util.cc | 8 -------- src/libutil/util.hh | 7 ++++++- 9 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index b1100a6623..efcb438766 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -968,7 +968,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) { PathSet context; std::ostringstream s; - int n = 0; + NixInt n = 0; bool first = true; ValueType firstType; @@ -1021,7 +1021,7 @@ void EvalState::strictForceValue(Value & v) } -int EvalState::forceInt(Value & v) +NixInt EvalState::forceInt(Value & v) { forceValue(v); if (v.type != tInt) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 5e98f5404b..9717fb66d9 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -159,7 +159,7 @@ public: void strictForceValue(Value & v); /* Force `v', and then verify that it has the expected type. */ - int forceInt(Value & v); + NixInt forceInt(Value & v); bool forceBool(Value & v); inline void forceAttrs(Value & v); inline void forceList(Value & v); diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l index 3b7c6bb57a..76cd372013 100644 --- a/src/libexpr/lexer.l +++ b/src/libexpr/lexer.l @@ -110,8 +110,10 @@ or { return OR_KW; } \+\+ { return CONCAT; } {ID} { yylval->id = strdup(yytext); return ID; } -{INT} { int n = atoi(yytext); /* !!! overflow */ - yylval->n = n; +{INT} { errno = 0; + yylval->n = strtol(yytext, 0, 10); + if (errno != 0) + throw ParseError(format("invalid integer `%1%'") % yytext); return INT; } diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 8256605b5c..f6dcb39357 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -75,9 +75,9 @@ std::ostream & operator << (std::ostream & str, Expr & e); struct ExprInt : Expr { - int n; + NixInt n; Value v; - ExprInt(int n) : n(n) { mkInt(v, n); }; + ExprInt(NixInt n) : n(n) { mkInt(v, n); }; COMMON_METHODS Value * maybeThunk(EvalState & state, Env & env); }; diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index cd1b0e21fa..7690271a86 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -238,7 +238,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err nix::ExprAttrs * attrs; nix::Formals * formals; nix::Formal * formal; - int n; + nix::NixInt n; char * id; // !!! -> Symbol char * path; char * uri; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 149c7ca399..deb66fd69f 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1024,7 +1024,7 @@ static void prim_mul(EvalState & state, Value * * args, Value & v) static void prim_div(EvalState & state, Value * * args, Value & v) { - int i2 = state.forceInt(*args[1]); + NixInt i2 = state.forceInt(*args[1]); if (i2 == 0) throw EvalError("division by zero"); mkInt(v, state.forceInt(*args[0]) / i2); } diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh index d49381a591..ee5c7397b3 100644 --- a/src/libexpr/value.hh +++ b/src/libexpr/value.hh @@ -31,14 +31,17 @@ struct PrimOp; struct Symbol; +typedef long NixInt; + + struct Value { ValueType type; - union + union { - int integer; + NixInt integer; bool boolean; - + /* Strings in the evaluator carry a so-called `context' which is a list of strings representing store paths. This is to allow users to write things like @@ -63,7 +66,7 @@ struct Value const char * s; const char * * context; // must be in sorted order } string; - + const char * path; Bindings * attrs; struct { @@ -97,7 +100,7 @@ static inline void clearValue(Value & v) } -static inline void mkInt(Value & v, int n) +static inline void mkInt(Value & v, NixInt n) { clearValue(v); v.type = tInt; diff --git a/src/libutil/util.cc b/src/libutil/util.cc index bc07a84f4d..5a88a158c3 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1083,14 +1083,6 @@ bool statusOk(int status) } -string int2String(int n) -{ - std::ostringstream str; - str << n; - return str.str(); -} - - bool hasSuffix(const string & s, const string & suffix) { return s.size() >= suffix.size() && string(s, s.size() - suffix.size()) == suffix; diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 6c83987c5d..86c65b763d 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -319,7 +319,12 @@ template bool string2Int(const string & s, N & n) return str && str.get() == EOF; } -string int2String(int n); +template string int2String(N n) +{ + std::ostringstream str; + str << n; + return str.str(); +} /* Return true iff `s' ends in `suffix'. */