Show position info in Boolean operations
This commit is contained in:
parent
bd9b1d97b4
commit
4c5faad994
5 changed files with 28 additions and 31 deletions
|
@ -574,6 +574,16 @@ inline bool EvalState::evalBool(Env & env, Expr * e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool EvalState::evalBool(Env & env, Expr * e, const Pos & pos)
|
||||||
|
{
|
||||||
|
Value v;
|
||||||
|
e->eval(*this, env, v);
|
||||||
|
if (v.type != tBool)
|
||||||
|
throwTypeError("value is %1% while a Boolean was expected, at %2%", v, pos);
|
||||||
|
return v.boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v)
|
inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v)
|
||||||
{
|
{
|
||||||
e->eval(*this, env, v);
|
e->eval(*this, env, v);
|
||||||
|
@ -975,7 +985,7 @@ void ExprIf::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
if (!state.evalBool(env, cond))
|
if (!state.evalBool(env, cond, pos))
|
||||||
throwAssertionError("assertion failed at %1%", pos);
|
throwAssertionError("assertion failed at %1%", pos);
|
||||||
body->eval(state, env, v);
|
body->eval(state, env, v);
|
||||||
}
|
}
|
||||||
|
@ -1016,19 +1026,19 @@ void ExprOpNEq::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprOpAnd::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpAnd::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
mkBool(v, state.evalBool(env, e1) && state.evalBool(env, e2));
|
mkBool(v, state.evalBool(env, e1, pos) && state.evalBool(env, e2, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExprOpOr::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpOr::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
mkBool(v, state.evalBool(env, e1) || state.evalBool(env, e2));
|
mkBool(v, state.evalBool(env, e1, pos) || state.evalBool(env, e2, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExprOpImpl::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpImpl::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
mkBool(v, !state.evalBool(env, e1) || state.evalBool(env, e2));
|
mkBool(v, !state.evalBool(env, e1, pos) || state.evalBool(env, e2, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1073,18 +1083,18 @@ void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v)
|
||||||
Value v1; e1->eval(state, env, v1);
|
Value v1; e1->eval(state, env, v1);
|
||||||
Value v2; e2->eval(state, env, v2);
|
Value v2; e2->eval(state, env, v2);
|
||||||
Value * lists[2] = { &v1, &v2 };
|
Value * lists[2] = { &v1, &v2 };
|
||||||
state.concatLists(v, 2, lists);
|
state.concatLists(v, 2, lists, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::concatLists(Value & v, unsigned int nrLists, Value * * lists)
|
void EvalState::concatLists(Value & v, unsigned int nrLists, Value * * lists, const Pos & pos)
|
||||||
{
|
{
|
||||||
nrListConcats++;
|
nrListConcats++;
|
||||||
|
|
||||||
Value * nonEmpty = 0;
|
Value * nonEmpty = 0;
|
||||||
unsigned int len = 0;
|
unsigned int len = 0;
|
||||||
for (unsigned int n = 0; n < nrLists; ++n) {
|
for (unsigned int n = 0; n < nrLists; ++n) {
|
||||||
forceList(*lists[n]);
|
forceList(*lists[n], pos);
|
||||||
unsigned int l = lists[n]->list.length;
|
unsigned int l = lists[n]->list.length;
|
||||||
len += l;
|
len += l;
|
||||||
if (l) nonEmpty = lists[n];
|
if (l) nonEmpty = lists[n];
|
||||||
|
|
|
@ -145,6 +145,7 @@ public:
|
||||||
/* Evaluation the expression, then verify that it has the expected
|
/* Evaluation the expression, then verify that it has the expected
|
||||||
type. */
|
type. */
|
||||||
inline bool evalBool(Env & env, Expr * e);
|
inline bool evalBool(Env & env, Expr * e);
|
||||||
|
inline bool evalBool(Env & env, Expr * e, const Pos & pos);
|
||||||
inline void evalAttrs(Env & env, Expr * e, Value & v);
|
inline void evalAttrs(Env & env, Expr * e, Value & v);
|
||||||
|
|
||||||
/* If `v' is a thunk, enter it and overwrite `v' with the result
|
/* If `v' is a thunk, enter it and overwrite `v' with the result
|
||||||
|
@ -246,7 +247,7 @@ public:
|
||||||
void mkThunk_(Value & v, Expr * expr);
|
void mkThunk_(Value & v, Expr * expr);
|
||||||
void mkPos(Value & v, Pos * pos);
|
void mkPos(Value & v, Pos * pos);
|
||||||
|
|
||||||
void concatLists(Value & v, unsigned int nrLists, Value * * lists);
|
void concatLists(Value & v, unsigned int nrLists, Value * * lists, const Pos & pos);
|
||||||
|
|
||||||
/* Print statistics. */
|
/* Print statistics. */
|
||||||
void printStats();
|
void printStats();
|
||||||
|
|
|
@ -277,28 +277,13 @@ struct ExprBuiltin : Expr
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprApp : Expr
|
|
||||||
{
|
|
||||||
Pos pos;
|
|
||||||
Expr * e1, * e2;
|
|
||||||
ExprApp(Expr * e1, Expr * e2) : e1(e1), e2(e2) { };
|
|
||||||
ExprApp(const Pos & pos, Expr * e1, Expr * e2) : pos(pos), e1(e1), e2(e2) { };
|
|
||||||
void show(std::ostream & str)
|
|
||||||
{
|
|
||||||
str << *e1 << " " << *e2;
|
|
||||||
}
|
|
||||||
void bindVars(const StaticEnv & env)
|
|
||||||
{
|
|
||||||
e1->bindVars(env); e2->bindVars(env);
|
|
||||||
}
|
|
||||||
void eval(EvalState & state, Env & env, Value & v);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MakeBinOp(name, s) \
|
#define MakeBinOp(name, s) \
|
||||||
struct Expr##name : Expr \
|
struct Expr##name : Expr \
|
||||||
{ \
|
{ \
|
||||||
|
Pos pos; \
|
||||||
Expr * e1, * e2; \
|
Expr * e1, * e2; \
|
||||||
Expr##name(Expr * e1, Expr * e2) : e1(e1), e2(e2) { }; \
|
Expr##name(Expr * e1, Expr * e2) : e1(e1), e2(e2) { }; \
|
||||||
|
Expr##name(const Pos & pos, Expr * e1, Expr * e2) : pos(pos), e1(e1), e2(e2) { }; \
|
||||||
void show(std::ostream & str) \
|
void show(std::ostream & str) \
|
||||||
{ \
|
{ \
|
||||||
str << *e1 << " " s " " << *e2; \
|
str << *e1 << " " s " " << *e2; \
|
||||||
|
@ -310,6 +295,7 @@ struct ExprApp : Expr
|
||||||
void eval(EvalState & state, Env & env, Value & v); \
|
void eval(EvalState & state, Env & env, Value & v); \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MakeBinOp(App, "")
|
||||||
MakeBinOp(OpEq, "==")
|
MakeBinOp(OpEq, "==")
|
||||||
MakeBinOp(OpNEq, "!=")
|
MakeBinOp(OpNEq, "!=")
|
||||||
MakeBinOp(OpAnd, "&&")
|
MakeBinOp(OpAnd, "&&")
|
||||||
|
|
|
@ -335,10 +335,10 @@ expr_op
|
||||||
| expr_op LEQ expr_op { $$ = new ExprOpNot(new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("lessThan")), $3), $1)); }
|
| expr_op LEQ expr_op { $$ = new ExprOpNot(new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("lessThan")), $3), $1)); }
|
||||||
| expr_op '>' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("lessThan")), $3), $1); }
|
| expr_op '>' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("lessThan")), $3), $1); }
|
||||||
| expr_op GEQ expr_op { $$ = new ExprOpNot(new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("lessThan")), $1), $3)); }
|
| expr_op GEQ expr_op { $$ = new ExprOpNot(new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("lessThan")), $1), $3)); }
|
||||||
| expr_op AND expr_op { $$ = new ExprOpAnd($1, $3); }
|
| expr_op AND expr_op { $$ = new ExprOpAnd(CUR_POS, $1, $3); }
|
||||||
| expr_op OR expr_op { $$ = new ExprOpOr($1, $3); }
|
| expr_op OR expr_op { $$ = new ExprOpOr(CUR_POS, $1, $3); }
|
||||||
| expr_op IMPL expr_op { $$ = new ExprOpImpl($1, $3); }
|
| expr_op IMPL expr_op { $$ = new ExprOpImpl(CUR_POS, $1, $3); }
|
||||||
| expr_op UPDATE expr_op { $$ = new ExprOpUpdate($1, $3); }
|
| expr_op UPDATE expr_op { $$ = new ExprOpUpdate(CUR_POS, $1, $3); }
|
||||||
| expr_op '?' attrpath { $$ = new ExprOpHasAttr($1, *$3); }
|
| expr_op '?' attrpath { $$ = new ExprOpHasAttr($1, *$3); }
|
||||||
| expr_op '+' expr_op
|
| expr_op '+' expr_op
|
||||||
{ vector<Expr *> * l = new vector<Expr *>;
|
{ vector<Expr *> * l = new vector<Expr *>;
|
||||||
|
@ -349,7 +349,7 @@ expr_op
|
||||||
| expr_op '-' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("sub")), $1), $3); }
|
| expr_op '-' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("sub")), $1), $3); }
|
||||||
| expr_op '*' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("mul")), $1), $3); }
|
| expr_op '*' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("mul")), $1), $3); }
|
||||||
| expr_op '/' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("div")), $1), $3); }
|
| expr_op '/' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprBuiltin(data->symbols.create("div")), $1), $3); }
|
||||||
| expr_op CONCAT expr_op { $$ = new ExprOpConcatLists($1, $3); }
|
| expr_op CONCAT expr_op { $$ = new ExprOpConcatLists(CUR_POS, $1, $3); }
|
||||||
| expr_app
|
| expr_app
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -1042,7 +1042,7 @@ static void prim_elem(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
static void prim_concatLists(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_concatLists(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
state.forceList(*args[0], pos);
|
state.forceList(*args[0], pos);
|
||||||
state.concatLists(v, args[0]->list.length, args[0]->list.elems);
|
state.concatLists(v, args[0]->list.length, args[0]->list.elems, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue