diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 88231e4b4..202273202 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -107,6 +107,8 @@ std::string showType(const Value & v) switch (v.auxiliary()->type) { case Value::Acb::tExternal: return v.external()->showType(); + case Value::Acb::tFloat: + return std::string(showType(v.type())); } #pragma GCC diagnostic pop case tThunk: return v.isBlackhole() ? "a black hole" : "a thunk"; diff --git a/lix/libexpr/nixexpr.hh b/lix/libexpr/nixexpr.hh index 54be8ed95..009c5767b 100644 --- a/lix/libexpr/nixexpr.hh +++ b/lix/libexpr/nixexpr.hh @@ -177,14 +177,27 @@ protected: public: ExprLiteral(const PosIdx pos, NewValueAs::integer_t, NixInt n) : Expr(pos) { v.mkInt(n); }; - ExprLiteral(const PosIdx pos, NewValueAs::integer_t, NixInt::Inner n) : Expr(pos) { v.mkInt(n); }; - ExprLiteral(const PosIdx pos, NewValueAs::floating_t, NixFloat nf) : Expr(pos) { v.mkFloat(nf); }; + ExprLiteral(const PosIdx pos, NewValueAs::integer_t, NixInt::Inner n) : Expr(pos) + { + v.mkInt(n); + } Value * maybeThunk(EvalState & state, Env & env) override; JSON toJSON(const SymbolTable & symbols) const override; void eval(EvalState & state, Env & env, Value & v) override; void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } }; +struct ExprFloat : ExprLiteral +{ + Value::Float f; + ExprFloat(const PosIdx pos, NewValueAs::floating_t, double f) + : ExprLiteral(pos) + , f{{Value::Acb::tFloat}, f} + { + v = Value(this->f); + } +}; + struct ExprString : ExprLiteral { std::string s; diff --git a/lix/libexpr/parser/parser-impl1.inc.cc b/lix/libexpr/parser/parser-impl1.inc.cc index d698daddb..487b5ff96 100644 --- a/lix/libexpr/parser/parser-impl1.inc.cc +++ b/lix/libexpr/parser/parser-impl1.inc.cc @@ -542,7 +542,7 @@ template<> struct BuildAST { }); } }(); - s.emplaceExpr(ps.at(in), NewValueAs::floating, v); + s.emplaceExpr(ps.at(in), NewValueAs::floating, v); } }; diff --git a/lix/libexpr/value.hh b/lix/libexpr/value.hh index f4d46973d..7bccb785b 100644 --- a/lix/libexpr/value.hh +++ b/lix/libexpr/value.hh @@ -34,7 +34,6 @@ typedef enum { tLambda, tPrimOp, tAuxiliary, - tFloat } InternalType; /** @@ -259,11 +258,13 @@ public: /// Constructs a nix language value of type "float", with the floating /// point value of @ref f. - Value(floating_t, NixFloat f) - : internalType(tFloat) - , _fpoint(f) - , _float_pad(0) - { } + Value(floating_t, NixFloat f) : internalType(tAuxiliary), _aux_pad(0) + { + auto fp = gcAllocType(); + fp->type = Acb::tFloat; + fp->value = f; + _auxiliary = fp; + } /// Constructs a nix language value of type "bool", with the boolean /// value of @ref b. @@ -638,12 +639,17 @@ public: { enum { tExternal, + tFloat, } type; }; struct External : Acb { ExternalValueBase * external; }; + struct Float : Acb + { + NixFloat value; + }; union { @@ -688,10 +694,6 @@ public: const Acb * _auxiliary; uintptr_t _aux_pad; }; - struct { - NixFloat _fpoint; - uintptr_t _float_pad; - }; }; /** @@ -719,8 +721,9 @@ public: switch (_auxiliary->type) { case Acb::tExternal: return nExternal; + case Acb::tFloat: + return nFloat; } - case tFloat: return nFloat; case tThunk: return nThunk; case tApp: @@ -834,9 +837,7 @@ public: inline void mkFloat(NixFloat n) { - clearValue(); - internalType = tFloat; - _fpoint = n; + *this = {NewValueAs::floating, n}; } bool isList() const @@ -954,7 +955,8 @@ public: NixFloat fpoint() const { - return _fpoint; + assert(internalType == tAuxiliary && _auxiliary->type == Acb::tFloat); + return static_cast(_auxiliary)->value; } const Acb * auxiliary() const