use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.
the class JobC method resolveContainer.
/**
* Compute a series of pointers to get from current part to r.
* Result does not include the variable name itself.
*/
public String resolveContainer(VariableReference r, RendererC context, String base) {
String containers = base;
EquationSet current = context.part;
boolean global = context.global;
int last = r.resolution.size() - 1;
for (int i = 0; i <= last; i++) {
Object o = r.resolution.get(i);
if (// We are following the containment hierarchy.
o instanceof EquationSet) {
EquationSet s = (EquationSet) o;
if (// descend into one of our contained populations
s.container == current) {
if (// descend to the population object
i == last && r.variable.hasAttribute("global")) {
// No need to cast the population instance, because it is explicitly typed
containers += mangle(s.name) + ".";
global = true;
} else // descend to a singleton instance of the population.
{
BackendDataC bed = (BackendDataC) s.backendData;
if (!bed.singleton) {
Backend.err.get().println("ERROR: Down-reference to population with more than one instance is ambiguous.");
throw new AbortRun();
}
containers += mangle(s.name) + ".instance.";
global = false;
}
} else // ascend to our container
{
containers = containerOf(current, i == 0 && context.global, containers);
global = false;
}
current = s;
} else if (// We are following a part reference (which means we are a connection)
o instanceof ConnectionBinding) {
ConnectionBinding c = (ConnectionBinding) o;
containers += mangle(c.alias) + "->";
current = c.endpoint;
global = false;
}
}
if (r.variable.hasAttribute("global") && !global) {
// Must ascend to our container and then descend to our population object.
containers = containerOf(current, false, containers);
containers += mangle(current.name) + ".";
}
return containers;
}
use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.
the class JobC method multiconditional.
/**
* Emit the equations associated with a variable.
* Assumes that phase indicators have already been factored out by simplify().
*/
public void multiconditional(Variable v, RendererC context, String pad) throws Exception {
boolean connect = context.part.getConnect();
boolean init = context.part.getInit();
boolean isType = v.name.equals("$type");
if (v.hasAttribute("temporary"))
context.result.append(pad + type(v) + " " + mangle(v) + ";\n");
// Select the default equation
EquationEntry defaultEquation = null;
for (EquationEntry e : v.equations) if (e.ifString.isEmpty())
defaultEquation = e;
// Initialize static objects, and dump dynamic objects needed by conditions
for (EquationEntry e : v.equations) {
if (e.condition != null)
prepareDynamicObjects(e.condition, context, init, pad);
}
// Write the conditional equations
boolean haveIf = false;
String padIf = pad;
for (EquationEntry e : v.equations) {
// Must skip the default equation, as it will be emitted last.
if (e == defaultEquation)
continue;
if (e.condition != null) {
String ifString;
if (haveIf) {
ifString = "else if (";
} else {
ifString = "if (";
haveIf = true;
padIf = pad + " ";
}
context.result.append(pad + ifString);
e.condition.render(context);
context.result.append(")\n");
context.result.append(pad + "{\n");
}
if (isType) {
// per the N2A language document.
if (!(e.expression instanceof Split)) {
Backend.err.get().println("Unexpected expression for $type");
throw new Backend.AbortRun();
}
int index = context.part.splits.indexOf(((Split) e.expression).parts);
context.result.append(padIf + resolve(v.reference, context, true) + " = " + (index + 1) + ";\n");
} else {
prepareDynamicObjects(e.expression, context, init, pad);
context.result.append(padIf);
renderEquation(context, e);
}
if (haveIf)
context.result.append(pad + "}\n");
}
// Write the default equation
if (defaultEquation == null) {
if (v.hasAttribute("temporary")) {
if (haveIf) {
context.result.append(pad + "else\n");
context.result.append(pad + "{\n");
}
context.result.append(padIf + zero(resolve(v.reference, context, true), v) + ";\n");
if (haveIf)
context.result.append(pad + "}\n");
} else {
String defaultValue = null;
if (isType) {
// always reset $type to 0
defaultValue = "0";
} else if (connect && v.name.equals("$p")) {
defaultValue = "1";
} else {
// to copy forward the current buffered value.
if (v.assignment == Variable.REPLACE && // local to the equation set, not a reference to an outside variable
v.reference.variable.container == v.container && v.equations.size() > 0 && // buffered
v.hasAny("cycle", "externalRead") && !v.hasAttribute("initOnly") && !init && // not in a phase that skips buffering
!connect) {
// copy previous value
defaultValue = resolve(v.reference, context, false);
}
}
if (defaultValue != null) {
if (haveIf) {
context.result.append(pad + "else\n");
context.result.append(pad + "{\n");
}
context.result.append(padIf + resolve(v.reference, context, true) + " = " + defaultValue + ";\n");
if (haveIf)
context.result.append(pad + "}\n");
}
}
} else {
if (haveIf) {
context.result.append(pad + "else\n");
context.result.append(pad + "{\n");
}
if (isType) {
ArrayList<EquationSet> split = ((Split) defaultEquation.expression).parts;
int index = context.part.splits.indexOf(split);
context.result.append(padIf + resolve(v.reference, context, true) + " = " + (index + 1) + ";\n");
} else {
prepareDynamicObjects(defaultEquation.expression, context, init, pad);
context.result.append(padIf);
renderEquation(context, defaultEquation);
}
if (haveIf)
context.result.append(pad + "}\n");
}
}
use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.
the class JobC method findPathToContainer.
public void findPathToContainer(EquationSet s) {
for (EquationSet p : s.parts) {
findPathToContainer(p);
}
if (s.connectionBindings != null) {
for (ConnectionBinding c : s.connectionBindings) {
if (c.endpoint.container == s.container) {
BackendDataC bed = (BackendDataC) s.backendData;
bed.pathToContainer = c.alias;
break;
}
}
}
}
use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.
the class JobC method assembleInstances.
/**
* Generate code to enumerate all instances of a connection endpoint. Handles deep hierarchical
* embedding.
*
* <p>A connection resolution can take 3 kinds of step:
* <ul>
* <li>Up to container
* <li>Down to a population
* <li>Through another connection
* </ul>
*
* @param current EquationSet associated with the context of the current step of resolution.
* @param pointer Name of a pointer to the context for the current step of resolution. Can
* be a chain of pointers. Can be empty if the code is to be emitted in the current context.
* @param depth Position in the resolution array of our next step.
* @param prefix Spaces to insert in front of each line to maintain nice indenting.
*/
public void assembleInstances(EquationSet current, String pointer, List<Object> resolution, int depth, String prefix, StringBuilder result) {
int last = resolution.size() - 1;
for (int i = depth; i <= last; i++) {
Object r = resolution.get(i);
if (r instanceof EquationSet) {
EquationSet s = (EquationSet) r;
if (// ascend to parent
r == current.container) {
pointer = containerOf(current, i == 0, pointer);
} else // descend to child
{
pointer += mangle(s.name) + ".";
if (// Enumerate the instances of child population.
i < last) {
if (depth == 0) {
result.append(prefix + "result->instances = new vector<Part<" + T + "> *>;\n");
result.append(prefix + "result->deleteInstances = true;\n");
}
String it = "it" + i;
result.append(prefix + "for (auto " + it + " : " + pointer + "instances)\n");
result.append(prefix + "{\n");
assembleInstances(s, it + "->", resolution, i + 1, prefix + " ", result);
result.append(prefix + "}\n");
return;
}
}
current = s;
} else if (r instanceof ConnectionBinding) {
ConnectionBinding c = (ConnectionBinding) r;
pointer += mangle(c.alias) + "->";
current = c.endpoint;
}
// else something is broken. This case should never occur.
}
// "pointer" now references the target population.
// Collect its instances.
BackendDataC bed = (BackendDataC) current.backendData;
if (bed.singleton) {
result.append(prefix + "bool newborn = " + pointer + "instance.flags & (" + bed.localFlagType + ") 0x1 << " + bed.newborn + ";\n");
if (depth == 0) {
result.append(prefix + "result->instances = new vector<Part<" + T + "> *>;\n");
result.append(prefix + "result->deleteInstances = true;\n");
}
result.append(prefix + "if (result->firstborn == INT_MAX && newborn) result->firstborn = result->instances->size ();\n");
result.append(prefix + "result->instances->push_back (& " + pointer + "instance);\n");
} else {
if (// No enumerations occurred during the resolution, so no list was created.
depth == 0) {
// Simply reference the existing list of instances.
result.append(prefix + "result->firstborn = " + pointer + "firstborn;\n");
result.append(prefix + "result->instances = (vector<Part<" + T + "> *> *) & " + pointer + "instances;\n");
} else // Enumerations occurred, so we are already accumulating a list.
{
// Append instances to accumulating list.
result.append(prefix + "if (result->firstborn == INT_MAX && " + pointer + "firstborn < " + pointer + "instances.size ()) result->firstborn = result->instances->size () + " + pointer + "firstborn;\n");
result.append(prefix + "result->instances->insert (result->instances->end (), " + pointer + "instances.begin (), " + pointer + "instances.end ());\n");
}
}
// Schedule the population to have its newborn flags cleared.
// We assume that any newborn flags along the path to this population are either unimportant
// or will get cleared elsewhere.
result.append(prefix + "if (! (" + pointer + "flags & (" + bed.globalFlagType + ") 0x1 << " + bed.clearNew + "))\n");
result.append(prefix + "{\n");
result.append(prefix + " " + pointer + "flags |= (" + bed.globalFlagType + ") 0x1 << " + bed.clearNew + ";\n");
pointer = stripDereference(pointer);
if (pointer.isEmpty())
pointer = "this";
else
pointer = "& " + pointer;
result.append(prefix + " Simulator<" + T + ">::instance.clearNew (" + pointer + ");\n");
result.append(prefix + "}\n");
}
use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.
the class JobC method findLiveReferences.
public void findLiveReferences(EquationSet s) {
for (EquationSet p : s.parts) {
findLiveReferences(p);
}
if (s.lethalConnection || s.lethalContainer) {
ArrayList<Object> resolution = new ArrayList<Object>();
NavigableSet<EquationSet> touched = new TreeSet<EquationSet>();
if (!(s.backendData instanceof BackendDataC))
s.backendData = new BackendDataC();
findLiveReferences(s, resolution, touched, ((BackendDataC) s.backendData).localReference, false);
}
}
Aggregations