private ScopeComputer(A4Reporter rep, Iterable<Sig> sigs, Command cmd) throws Err {
this.rep = rep;
this.cmd = cmd;
// Process each sig listed in the command
for(CommandScope entry:cmd.scope) {
Sig s = entry.sig;
int scope = entry.startingScope;
boolean exact = entry.isExact;
if (s==UNIV) throw new ErrorSyntax(cmd.pos, "You cannot set a scope on \"univ\".");
if (s==SIGINT) throw new ErrorSyntax(cmd.pos,
"You can no longer set a scope on \"Int\". "
+"The number of atoms in Int is always exactly equal to 2^(integer bitwidth).\n");
if (s==SEQIDX) throw new ErrorSyntax(cmd.pos,
"You cannot set a scope on \"seq/Int\". "
+"To set the maximum allowed sequence length, use the seq keyword.\n");
if (s==STRING) {
if (maxstring>=0) throw new ErrorSyntax(cmd.pos, "Sig \"String\" already has a scope of "+maxstring+", so we cannot set it to be "+scope);
if (!exact) throw new ErrorSyntax(cmd.pos, "Sig \"String\" must have an exact scope.");
maxstring = scope;
continue;
}
if (s==NONE) throw new ErrorSyntax(cmd.pos, "You cannot set a scope on \"none\".");
if (s.isEnum!=null) throw new ErrorSyntax(cmd.pos, "You cannot set a scope on the enum \""+s.label+"\"");
if (s.isOne!=null && scope!=1) throw new ErrorSyntax(cmd.pos,
"Sig \""+s+"\" has the multiplicity of \"one\", so its scope must be 1, and cannot be "+scope);
if (s.isLone!=null && scope>1) throw new ErrorSyntax(cmd.pos,
"Sig \""+s+"\" has the multiplicity of \"lone\", so its scope must 0 or 1, and cannot be "+scope);
if (s.isSome!=null && scope<1) throw new ErrorSyntax(cmd.pos,
"Sig \""+s+"\" has the multiplicity of \"some\", so its scope must 1 or above, and cannot be "+scope);
sig2scope(s, scope);
if (exact) makeExact(cmd.pos, s);
}
// Force "one" sigs to be exactly one, and "lone" to be at most one
for(Sig s:sigs) if (s instanceof PrimSig) {
if (s.isOne!=null) { makeExact(cmd.pos, s); sig2scope(s,1); } else if (s.isLone!=null && sig2scope(s)!=0) sig2scope(s,1);
}
// Derive the implicit scopes
while(true) {
if (derive_abstract_scope(sigs)) { do {} while(derive_abstract_scope(sigs)); continue; }
if (derive_overall_scope(sigs)) { do {} while(derive_overall_scope(sigs)); continue; }
if (derive_scope_from_parent(sigs)) { do {} while(derive_scope_from_parent(sigs)); continue; }
break;
}
// Set the initial scope on "int" and "Int" and "seq"
int maxseq=cmd.maxseq, bitwidth=cmd.bitwidth;
if (bitwidth<0) bitwidth=4;
setBitwidth(cmd.pos, bitwidth);
if (maxseq<0) {
if (cmd.overall>=0) maxseq=cmd.overall; else maxseq=4;
int max = (1<<(bitwidth-1))-1;
if (maxseq > max) maxseq = max;
}
setMaxSeq(cmd.pos, maxseq);
// Generate the atoms and the universe
for(Sig s:sigs) if (s.isTopLevel()) computeLowerBound((PrimSig)s);
for(int max=max(), i=min(); i<=max; i++) atoms.add(""+i);
}