use of ast.Ast.Path in project L42 by ElvisResearchGroup.
the class EvilPushed method _reducePath.
default default Path _reducePath(Path p, CtxL ctx) {
if (p.isPrimitive()) {
return null;
}
if (p.outerNumber() == 0) {
return null;
}
if (p.outerNumber() > 1) {
Path p1 = p.setNewOuter(p.outerNumber() - 1);
Path p2 = this.pop()._reducePath(p1);
if (p2 == null) {
return null;
}
assert p2.outerNumber() == p1.outerNumber() - 1;
return p2.setNewOuter(p2.outerNumber() + 1);
}
assert p.outerNumber() == 1;
List<Ast.C> cs = p.getCBar();
if (cs.isEmpty()) {
return null;
}
ClassB.Member m = ctx.originalCtxM();
if (!(m instanceof ClassB.NestedClass)) {
return null;
}
Ast.C ncName = ((ClassB.NestedClass) m).getName();
if (!ncName.equals(cs.get(0))) {
return null;
}
return Path.outer(0, cs.subList(1, cs.size()));
}
use of ast.Ast.Path in project L42 by ElvisResearchGroup.
the class EvilPushed method equiv.
//hint for testing: p.equiv(p0,p1)==p.navigate(p0).equals(p.navigate(p1))
//provided both navigates do not throw evilPush errors
//and p0, p1 already exists (not still to metaprogram their outers)
default default boolean equiv(Ast.Path p, Ast.Path p1) {
if (p.equals(p1)) {
return true;
}
if (p.isPrimitive() || p1.isPrimitive()) {
return false;
}
if (p.outerNumber() == p1.outerNumber()) {
return false;
}
if (p.outerNumber() < p1.outerNumber()) {
//swap
Path aux = p1;
//swap
p1 = p;
//swap
p = aux;
}
assert p.outerNumber() > p1.outerNumber();
Path reduced = p;
while (true) {
reduced = this._reducePath(reduced);
if (reduced == null) {
return false;
}
if (reduced.outerNumber() == p1.outerNumber()) {
return reduced.equals(p1);
}
}
}
use of ast.Ast.Path in project L42 by ElvisResearchGroup.
the class MakeMethod method addMethod.
public static ClassB addMethod(ClassB _lib, List<Ast.C> path, MethodSelector ms, String mdfs, int excNumber) {
Errors42.checkExistsPathMethod(_lib, path, Optional.empty());
ClassB innerLib = _lib.getClassB(path);
String[] _mdfs = mdfs.split(" ");
assert _mdfs.length == ms.getNames().size() + 2;
List<String> nc = new ArrayList<>();
Type retT = new Type(Mdf.valueOf(_mdfs[1]), Path.outer(0, Arrays.asList(C.of("$0"))), Doc.empty());
nc.add("$0");
List<Type> ts = new ArrayList<>();
List<Doc> docs = new ArrayList<>();
int count = 1;
for (String n : ms.getNames()) {
String cn = "$" + count;
ts.add(new Type(Mdf.valueOf(_mdfs[count + 1]), Path.outer(0, Arrays.asList(C.of(cn))), Doc.empty()));
nc.add(cn);
count++;
}
List<Path> exceptions = new ArrayList<>();
for (int i = 0; i < excNumber; i++) {
String cn = "$" + count++;
exceptions.add(Path.outer(0, Arrays.asList(C.of(cn))));
nc.add(cn);
}
MethodType mt = new MethodType(false, Mdf.valueOf(_mdfs[0]), ts, retT, Map.of(pi -> pi.toImmNT(), exceptions));
MethodWithType mwt = new MethodWithType(Doc.empty(), ms, mt, Optional.empty(), innerLib.getP());
Optional<Member> optM = Functions.getIfInDom(innerLib.getMs(), ms);
if (optM.isPresent()) {
throw Errors42.errorMethodClash(path, mwt, optM.get(), false, Collections.emptyList(), false, false, false);
}
ClassB emptyCb = ClassB.membersClass(Collections.emptyList(), innerLib.getP(), innerLib.getPhase());
return _lib.onClassNavigateToPathAndDo(path, cbi -> {
List<Member> mem = new ArrayList<>(cbi.getMs());
mem.add(mwt);
for (String s : nc) {
mem.add(new NestedClass(Doc.empty(), C.of(s), emptyCb, cbi.getP()));
}
return cbi.withMs(mem);
});
}
use of ast.Ast.Path in project L42 by ElvisResearchGroup.
the class Redirect method redirectOkAux.
private static void redirectOkAux(Program p, PathSPath current, ClassB cbTop, List<PathSPath> ambiguities, List<SPathSPath> exceptions) {
assert current.getPathsSet().size() == 1;
List<Ast.C> cs = current.getPath().getCBar();
if (cs.isEmpty()) {
throw Errors42.errorInvalidOnTopLevel();
}
Errors42.checkExistsPathMethod(cbTop, cs, Optional.empty());
//Boolean[] csPrivate=new Boolean[]{false};
ClassB currentIntCb = cbTop.getClassB(cs);
//path exists by construction.
Path path = current.getPathsSet().iterator().next();
ClassB currentExtCb;
if (path.isCore()) {
assert path.outerNumber() > 0 : path;
currentExtCb = p.extractClassB(path);
} else {
assert path.isPrimitive();
currentExtCb = ClassB.membersClass(Collections.emptyList(), Position.noInfo, cbTop.getPhase()).withInterface(path.equals(Path.Any()));
}
assert cs.stream().allMatch(c -> !c.isUnique());
boolean isPrivateState = ExtractInfo.hasPrivateState(currentIntCb);
boolean isNoImplementation = ExtractInfo.isNoImplementation(currentIntCb);
boolean headerOk = currentIntCb.isInterface() == currentExtCb.isInterface();
ClassKind kindSrc = ExtractInfo.classKind(cbTop, cs, currentIntCb, null, isPrivateState, isNoImplementation);
if (!headerOk && !currentIntCb.isInterface()) {
if (kindSrc == ClassKind.FreeTemplate) {
headerOk = true;
}
}
ClassKind kindDest = ExtractInfo.classKind(null, null, currentExtCb, null, null, null);
if (isPrivateState || !isNoImplementation) {
//unexpectedMembers stay empty if there is implementation
assert kindSrc != ClassKind.FreeTemplate || kindSrc != ClassKind.Template || kindSrc != ClassKind.Interface : kindSrc;
throw Errors42.errorSourceUnfit(current.getPath().getCBar(), path, kindSrc, kindDest, Collections.emptyList(), headerOk, Collections.emptyList());
}
redirectOkImpl(kindSrc, kindDest, ambiguities, current, currentIntCb, currentExtCb);
List<Member> unexpectedMembers = new ArrayList<>();
for (Member mi : currentIntCb.getMs()) {
Optional<Member> miPrime = Functions.getIfInDom(currentExtCb.getMs(), mi);
if (miPrime.isPresent() && miPrime.get().getClass().equals(mi.getClass())) {
Member miGet = miPrime.get();
redirectOkMember(ambiguities, exceptions, mi, miGet, current);
} else {
unexpectedMembers.add(mi);
}
}
if (unexpectedMembers.isEmpty() && headerOk) {
return;
}
if (kindSrc == null) {
kindSrc = ExtractInfo.classKind(cbTop, cs, currentIntCb, null, isPrivateState, isNoImplementation);
}
if (kindDest == null) {
kindDest = ExtractInfo.classKind(null, null, currentExtCb, null, null, null);
}
throw Errors42.errorSourceUnfit(cs, path, kindSrc, kindDest, unexpectedMembers, headerOk, Collections.emptyList());
}
use of ast.Ast.Path in project L42 by ElvisResearchGroup.
the class Redirect method redirectOkImpl.
private static void redirectOkImpl(ClassKind kindSrc, ClassKind kindDest, List<PathSPath> ambiguities, PathSPath current, ClassB currentIntCb, ClassB currentExtCb) {
// List<Path>unexpectedInterfaces=new ArrayList<>(unexpectedI);
// Collections.sort(unexpectedInterfaces,(pa,pb)->pa.toString().compareTo(pb.toString()));
List<Path> extPs = currentExtCb.getSuperPaths();
Path destP = current.getPathsSet().iterator().next();
extPs = Map.of(pi -> From.fromP(pi, destP), extPs);
List<Path> unexpectedInterfaces = new ArrayList<>();
for (Path pi : currentIntCb.getSuperPaths()) {
Path pif = From.fromP(pi, current.getPath());
if (extPs.isEmpty()) {
unexpectedInterfaces.add(pif);
} else if (pif.isPrimitive() || pif.outerNumber() > 0) {
if (!extPs.contains(pif)) {
unexpectedInterfaces.add(pif);
}
} else {
plusEqual(ambiguities, pif, extPs);
}
}
if (unexpectedInterfaces.isEmpty()) {
return;
}
throw Errors42.errorSourceUnfit(current.getPath().getCBar(), current.getPathsSet().iterator().next(), kindSrc, kindDest, Collections.emptyList(), true, unexpectedInterfaces);
}
Aggregations