-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make a changed(somevar) macro for loops #211
Comments
A related macro |
I wonder if #186 could be given a semantics such that this issue can just use it straight off? |
Just driving by to say I think the |
Much later thought: this feature might be trying to be "too magic" by implicitly deciding when something changed (and injecting code at that point). With variables, it's easy to detect a change, just look for Maybe better to have some convenient syntax when something did change. (Not committing on what.) Then the macro up in the loop could just look for these explicit signals, and the programmer could make sure to remember to explicitly mark the places that change. |
Still much later thought: I actually wrote a loop like this in TypeScript. Let me start by pasting the whole function, showing the loop in its context: export function solve(system: EqnSystem): Array<boolean> {
function refsConst(bvar: BoolExp): boolean {
if (!(bvar instanceof BoolExp.BVar)) {
return false;
}
let eqn = system.eqns.find((e) => e.lhs === bvar.name);
if (eqn === undefined) {
throw new Error(
"Reference to unknown equation -- precondition broken");
}
return eqn.rhs instanceof BoolExp.BConst;
}
let changed: boolean;
do {
changed = false;
for (let eqn of system.eqns) {
let rhs = eqn.rhs;
// simplification rules
if (rhs instanceof BoolExp.All && rhs.operands.some(isFalse)) {
eqn.rhs = new BoolExp.BConst(false);
changed = true;
}
else if (rhs instanceof BoolExp.Any && rhs.operands.some(isTrue)) {
eqn.rhs = new BoolExp.BConst(true);
changed = true;
}
else if (rhs instanceof BoolExp.All && rhs.operands.length === 1) {
eqn.rhs = rhs.operands[0];
changed = true;
}
else if (rhs instanceof BoolExp.Any && rhs.operands.length === 1) {
eqn.rhs = rhs.operands[0];
changed = true;
}
else if (rhs instanceof BoolExp.All && rhs.operands.length === 0) {
eqn.rhs = new BoolExp.BConst(true);
changed = true;
}
else if (rhs instanceof BoolExp.Any && rhs.operands.length === 0) {
eqn.rhs = new BoolExp.BConst(false);
changed = true;
}
if (rhs instanceof BoolExp.All && rhs.operands.every(isTrue)) {
eqn.rhs = new BoolExp.BConst(true);
changed = true;
}
else if (rhs instanceof BoolExp.Any &&
rhs.operands.every(isFalse)) {
eqn.rhs = new BoolExp.BConst(false);
changed = true;
}
else if (rhs instanceof BoolExp.BVar && refsConst(rhs)) {
let otherEqn = system.eqns.find(
(e) => e.lhs === (rhs as BoolExp.BVar).name)!;
eqn.rhs = otherEqn.rhs;
changed = true;
}
else if (rhs instanceof BoolExp.All &&
rhs.operands.some(refsConst)) {
rhs.operands = rhs.operands.map((exp) => {
if (refsConst(exp)) {
let otherEqn = system.eqns.find(
(e) => e.lhs === (exp as BoolExp.BVar).name)!;
return otherEqn.rhs;
}
else {
return exp;
}
});
changed = true;
}
else if (rhs instanceof BoolExp.Any &&
rhs.operands.some(refsConst)) {
rhs.operands = rhs.operands.map((exp) => {
if (refsConst(exp)) {
let otherEqn = system.eqns.find(
(e) => e.lhs === (exp as BoolExp.BVar).name)!;
return otherEqn.rhs;
}
else {
return exp;
}
});
changed = true;
}
}
} while (changed);
return system.eqns.map((eqn) => {
let rhs = eqn.rhs;
return rhs instanceof BoolExp.BConst
? rhs.value
: system.cycleDefault;
});
} Three points:
|
I drove by to say this, which was already said. So I'll say something else instead. Yes, while this is a strictly "local" analysis, it also feels like it'd have to be a contextual macro, in the sense that There's also the slight worry of "how do we know something is an assignment?" — which sounds silly at first, until we realize that anyone can extend the syntax and semantics, and so there isn't a priori a way to ask the question that isn't disrupted by such extensions. Presumably something like an "assignment protocol", or a way to query the control-flow-graph rather than the AST, could be made to work. |
I'm thinking of a loop like this:
This proposed macro would allow us to hide the
stillChanging
boolean and have the macro generate the code to update it properly:The text was updated successfully, but these errors were encountered: