* Implemented inherit.
This commit is contained in:
parent
267dc693d2
commit
d39d3c6264
4 changed files with 34 additions and 29 deletions
|
@ -105,9 +105,12 @@ void run(Strings args)
|
||||||
doTest(state, "map (x: __add 1 x) [ 1 2 3 ]");
|
doTest(state, "map (x: __add 1 x) [ 1 2 3 ]");
|
||||||
doTest(state, "map (builtins.add 1) [ 1 2 3 ]");
|
doTest(state, "map (builtins.add 1) [ 1 2 3 ]");
|
||||||
doTest(state, "builtins.hasAttr \"x\" { x = 1; }");
|
doTest(state, "builtins.hasAttr \"x\" { x = 1; }");
|
||||||
doTest(state, "let x = 1; as = rec { inherit x; y = as.x; }; in as.y");
|
doTest(state, "let x = 1; as = { inherit x; y = as.x; }; in as.y");
|
||||||
|
doTest(state, "let x = 1; as = rec { inherit x; y = x; }; in as.y");
|
||||||
doTest(state, "let as = { x = 1; }; bs = rec { inherit (as) x; y = x; }; in bs.y");
|
doTest(state, "let as = { x = 1; }; bs = rec { inherit (as) x; y = x; }; in bs.y");
|
||||||
doTest(state, "let as = rec { inherit (y) x; y = { x = 1; }; }; in as.x");
|
doTest(state, "let as = rec { inherit (y) x; y = { x = 1; }; }; in as.x");
|
||||||
|
doTest(state, "let x = 1; in let inherit x; in x");
|
||||||
|
doTest(state, "with { x = 1; }; let inherit x; y = x; in y");
|
||||||
doTest(state, "builtins.toXML 123");
|
doTest(state, "builtins.toXML 123");
|
||||||
doTest(state, "builtins.toXML { a.b = \"x\" + \"y\"; c = [ 1 2 ] ++ [ 3 4 ]; }");
|
doTest(state, "builtins.toXML { a.b = \"x\" + \"y\"; c = [ 1 2 ] ++ [ 3 4 ]; }");
|
||||||
|
|
||||||
|
|
|
@ -338,7 +338,7 @@ void EvalState::eval(Env & env, Expr * e, Value & v)
|
||||||
char x;
|
char x;
|
||||||
if (&x < deepestStack) deepestStack = &x;
|
if (&x < deepestStack) deepestStack = &x;
|
||||||
|
|
||||||
debug(format("eval: %1%") % *e);
|
//debug(format("eval: %1%") % *e);
|
||||||
|
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
|
@ -390,14 +390,13 @@ void ExprPath::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
state.mkAttrs(v);
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
/* Create a new environment that contains the attributes in
|
/* Create a new environment that contains the attributes in
|
||||||
this `rec'. */
|
this `rec'. */
|
||||||
Env & env2(state.allocEnv(attrs.size() + inherited.size()));
|
Env & env2(state.allocEnv(attrs.size() + inherited.size()));
|
||||||
env2.up = &env;
|
env2.up = &env;
|
||||||
|
|
||||||
v.type = tAttrs;
|
|
||||||
v.attrs = new Bindings;
|
|
||||||
|
|
||||||
unsigned int displ = 0;
|
unsigned int displ = 0;
|
||||||
|
|
||||||
|
@ -409,26 +408,25 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
mkThunk(env2.values[displ++], env2, i->second);
|
mkThunk(env2.values[displ++], env2, i->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* The inherited attributes, on the other hand, are
|
/* The inherited attributes, on the other hand, are
|
||||||
evaluated in the original environment. */
|
evaluated in the original environment. */
|
||||||
foreach (list<Symbol>::iterator, i, inherited) {
|
foreach (list<VarRef>::iterator, i, inherited) {
|
||||||
Value & v2 = env2.bindings[*i];
|
Value & v2 = (*v.attrs)[i->name];
|
||||||
mkCopy(v2, *state.lookupVar(&env, *i));
|
Value * v3 = state.lookupVar(&env, *i);
|
||||||
|
mkCopy(v2, *v3);
|
||||||
|
mkCopy(env2.values[displ++], *v3);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
state.mkAttrs(v);
|
|
||||||
foreach (Attrs::iterator, i, attrs) {
|
foreach (Attrs::iterator, i, attrs) {
|
||||||
Value & v2 = (*v.attrs)[i->first];
|
Value & v2 = (*v.attrs)[i->first];
|
||||||
mkThunk(v2, env, i->second);
|
mkThunk(v2, env, i->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (list<Symbol>::iterator, i, inherited) {
|
foreach (list<VarRef>::iterator, i, inherited) {
|
||||||
Value & v2 = (*v.attrs)[*i];
|
Value & v2 = (*v.attrs)[i->name];
|
||||||
mkCopy(v2, *state.lookupVar(&env, *i));
|
mkCopy(v2, *state.lookupVar(&env, *i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,14 +447,10 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
||||||
foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs)
|
foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs)
|
||||||
mkThunk(env2.values[displ++], env2, i->second);
|
mkThunk(env2.values[displ++], env2, i->second);
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* The inherited attributes, on the other hand, are evaluated in
|
/* The inherited attributes, on the other hand, are evaluated in
|
||||||
the original environment. */
|
the original environment. */
|
||||||
foreach (list<Symbol>::iterator, i, attrs->inherited) {
|
foreach (list<VarRef>::iterator, i, attrs->inherited)
|
||||||
Value & v2 = env2.bindings[*i];
|
mkCopy(env2.values[displ++], *state.lookupVar(&env, *i));
|
||||||
mkCopy(v2, *state.lookupVar(&env, *i));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
state.eval(env2, body, v);
|
state.eval(env2, body, v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,8 @@ void ExprAttrs::show(std::ostream & str)
|
||||||
{
|
{
|
||||||
if (recursive) str << "rec ";
|
if (recursive) str << "rec ";
|
||||||
str << "{ ";
|
str << "{ ";
|
||||||
foreach (list<Symbol>::iterator, i, inherited)
|
foreach (list<VarRef>::iterator, i, inherited)
|
||||||
str << "inherit " << *i << "; ";
|
str << "inherit " << i->name << "; ";
|
||||||
foreach (Attrs::iterator, i, attrs)
|
foreach (Attrs::iterator, i, attrs)
|
||||||
str << i->first << " = " << *i->second << "; ";
|
str << i->first << " = " << *i->second << "; ";
|
||||||
str << "}";
|
str << "}";
|
||||||
|
@ -91,8 +91,8 @@ void ExprLambda::show(std::ostream & str)
|
||||||
void ExprLet::show(std::ostream & str)
|
void ExprLet::show(std::ostream & str)
|
||||||
{
|
{
|
||||||
str << "let ";
|
str << "let ";
|
||||||
foreach (list<Symbol>::iterator, i, attrs->inherited)
|
foreach (list<VarRef>::iterator, i, attrs->inherited)
|
||||||
str << "inherit " << *i << "; ";
|
str << "inherit " << i->name << "; ";
|
||||||
foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs)
|
foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs)
|
||||||
str << i->first << " = " << *i->second << "; ";
|
str << i->first << " = " << *i->second << "; ";
|
||||||
str << "in " << *body;
|
str << "in " << *body;
|
||||||
|
@ -212,16 +212,22 @@ void ExprAttrs::bindVars(const StaticEnv & env)
|
||||||
foreach (ExprAttrs::Attrs::iterator, i, attrs)
|
foreach (ExprAttrs::Attrs::iterator, i, attrs)
|
||||||
newEnv.vars[i->first] = displ++;
|
newEnv.vars[i->first] = displ++;
|
||||||
|
|
||||||
foreach (list<Symbol>::iterator, i, inherited)
|
foreach (list<VarRef>::iterator, i, inherited) {
|
||||||
newEnv.vars[*i] = displ++;
|
newEnv.vars[i->name] = displ++;
|
||||||
|
i->bind(env);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (ExprAttrs::Attrs::iterator, i, attrs)
|
foreach (ExprAttrs::Attrs::iterator, i, attrs)
|
||||||
i->second->bindVars(newEnv);
|
i->second->bindVars(newEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
foreach (ExprAttrs::Attrs::iterator, i, attrs)
|
foreach (ExprAttrs::Attrs::iterator, i, attrs)
|
||||||
i->second->bindVars(env);
|
i->second->bindVars(env);
|
||||||
|
|
||||||
|
foreach (list<VarRef>::iterator, i, inherited)
|
||||||
|
i->bind(env);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprList::bindVars(const StaticEnv & env)
|
void ExprList::bindVars(const StaticEnv & env)
|
||||||
|
@ -258,8 +264,10 @@ void ExprLet::bindVars(const StaticEnv & env)
|
||||||
foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs)
|
foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs)
|
||||||
newEnv.vars[i->first] = displ++;
|
newEnv.vars[i->first] = displ++;
|
||||||
|
|
||||||
foreach (list<Symbol>::iterator, i, attrs->inherited)
|
foreach (list<VarRef>::iterator, i, attrs->inherited) {
|
||||||
newEnv.vars[*i] = displ++;
|
newEnv.vars[i->name] = displ++;
|
||||||
|
i->bind(env);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs)
|
foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs)
|
||||||
i->second->bindVars(newEnv);
|
i->second->bindVars(newEnv);
|
||||||
|
|
|
@ -127,7 +127,7 @@ struct ExprAttrs : Expr
|
||||||
bool recursive;
|
bool recursive;
|
||||||
typedef std::map<Symbol, Expr *> Attrs;
|
typedef std::map<Symbol, Expr *> Attrs;
|
||||||
Attrs attrs;
|
Attrs attrs;
|
||||||
list<Symbol> inherited;
|
list<VarRef> inherited;
|
||||||
ExprAttrs() : recursive(false) { };
|
ExprAttrs() : recursive(false) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue