Commit 70a503a3 authored by Allan MILHOMME's avatar Allan MILHOMME

r

parent 2cf98c38
void main(Array<String> args)
{
Int i = 0;
while (i.inf(10)) {
i = i.add(1);
}
System:.out.println(i);
test3(i);
Int j = i.add(3);
if (j.inf(6))
test3(i);
}
void test3(Int i)
[
i.inf(3).not();
i.inf(3);
]
{
......
void main(Array<String> args)
{
Int i = 0;
i = 0;
i = i.add(1);
while (i.inf(10)) {
i = i.add(1);
}
System:.out.println(i);
test3(i);
}
void test3(Int i)
[
i.inf(3).not();
]
{
}
\ No newline at end of file
......@@ -3,7 +3,11 @@ package compiler;
import java.util.Arrays;
import java.util.stream.Stream;
import inflow.AndInfo;
import inflow.HigherInfo;
import inflow.LoopInflow;
import inflow.OperationList;
import inflow.VariableValue;
import language.parser.parser.ParserString;
import language.parser.tokens.Access;
import language.parser.tokens.Assignation;
......@@ -76,12 +80,34 @@ public class ExpressionCompiler {
Reference r = assignation.ref;
if (r.isLocalVariableOnly()) {
currentSpace.removeInfosOn(r.toOperationList());
currentSpace.addInfo(
r.toOperationList().getInfos(currentSpace.getCurrentInfo(), false).copyTo(r.toOperationList()));
currentSpace.addInfo(assignation.secondExp.toOperationList().knowing(
r.toOperationList().getInfos(currentSpace.getCurrentInfo(), false), currentSpace.getCurrentInfo()));
currentSpace.removeInfosOn(r.toOperationList());
HigherInfo oldInfos = r.toOperationList().getInfos(currentSpace.getCurrentInfo(), false).removeInfosDependingOn(r.toOperationList(), currentSpace.getCurrentInfo());
LoopInflow closest = currentSpace.getClosestLoopInflow();
if (closest != null)
currentSpace.removeInfosOn((VariableValue)r.toOperationList().getLastValue());
HigherInfo onResult = assignation.secondExp.toOperationList().getInfos(currentSpace.getCurrentInfo(), false).copyTo(r.toOperationList());
if (closest != null) {
onResult = onResult.toLoop(closest.value, oldInfos).normalize();
}
HigherInfo deducedInfos = assignation.secondExp.toOperationList().knowing(
HigherInfo.getSelfInfo((VariableValue)r.toOperationList().getLastValue(), r.completedTypes[r.completedTypes.length - 1].getAccess()), currentSpace.getCurrentInfo());
if (closest != null)
deducedInfos = deducedInfos.removeInfosDependingOn(r.toOperationList(), currentSpace.getCurrentInfo());
HigherInfo addedInfo = new AndInfo(onResult,
deducedInfos);
if (closest == null)
addedInfo = addedInfo.removeInfosDependingOn(r.toOperationList(), currentSpace.getCurrentInfo());
currentSpace.removeInfosDependingOn(r.toOperationList());
currentSpace.removeInfosOn((VariableValue)r.toOperationList().getLastValue());
currentSpace.addInfo(addedInfo.normalize());
Logger.debug("Out : "+currentSpace.getCurrentInfo().normalize());
}
if (!isTypeParentOf(assignation.ref.getLastType(), t))
......
......@@ -65,8 +65,8 @@ public class AndInfo extends HigherInfo {
}
@Override
public HigherInfo removeInfosOn(OperationList var, HigherInfo refInfos) {
return new AndInfo(this.info1.removeInfosOn(var, refInfos), this.info2.removeInfosOn(var, refInfos));
public HigherInfo removeInfosDependingOn(OperationList var, HigherInfo refInfos) {
return new AndInfo(this.info1.removeInfosDependingOn(var, refInfos), this.info2.removeInfosDependingOn(var, refInfos));
}
@Override
......@@ -111,7 +111,12 @@ public class AndInfo extends HigherInfo {
}
@Override
public HigherInfo toLoop(LoopValue value) {
return new AndInfo(this.info1.toLoop(value), this.info2.toLoop(value));
public HigherInfo toLoop(LoopValue value, HigherInfo oldInfo) {
return new AndInfo(this.info1.toLoop(value, oldInfo), this.info2.toLoop(value, oldInfo));
}
@Override
public HigherInfo removeInfosOn(VariableValue val) {
return new AndInfo(this.info1.removeInfosOn(val), this.info2.removeInfosOn(val));
}
}
......@@ -68,10 +68,27 @@ public class BasicInflow extends Inflow {
}
@Override
public void removeInfosOn(OperationList list) {
public void removeInfosDependingOn(OperationList list) {
if (this.childInflow != null)
this.childInflow.removeInfosDependingOn(list);
else
this.currentInfos = this.currentInfos.removeInfosDependingOn(list, this.currentInfos);
}
@Override
public void removeInfosOn(VariableValue list) {
if (this.childInflow != null)
this.childInflow.removeInfosOn(list);
else
this.currentInfos = this.currentInfos.removeInfosOn(list, this.currentInfos);
this.currentInfos = this.currentInfos.removeInfosOn(list);
}
@Override
public LoopInflow getClosestLoopInflow() {
if (this.childInflow != null) {
LoopInflow closest = this.childInflow.getClosestLoopInflow();
return closest;
}
return null;
}
}
......@@ -8,6 +8,10 @@ public class ConstantValue implements Value {
public ConstantValue(Info value) {
this.value = new ValueInfo(value);
}
public ConstantValue(HigherInfo value) {
this.value = value;
}
public ConstantValue() {
this.value = NoInfo.instance;
......
......@@ -89,18 +89,23 @@ public class FieldInfo extends HigherInfo {
}
@Override
public HigherInfo toLoop(LoopValue value) {
return new FieldInfo(this.var, this.info.toLoop(value));
public HigherInfo toLoop(LoopValue value, HigherInfo oldInfo) {
return new FieldInfo(this.var, this.info.toLoop(value, oldInfo));
}
@Override
public HigherInfo removeInfosOn(OperationList var, HigherInfo refInfos) {
public HigherInfo removeInfosDependingOn(OperationList var, HigherInfo refInfos) {
if (!var.operationList.isEmpty())
if (var.operationList.getLast() instanceof FieldAccess) {
FieldAccess op = (FieldAccess) var.operationList.getLast();
if (op.var.equals(this.var))
return new FieldInfo(this.var, this.info.removeInfosOn(var.removeLast(), refInfos));
return new FieldInfo(this.var, this.info.removeInfosDependingOn(var.removeLast(), refInfos));
}
return this;
}
@Override
public HigherInfo removeInfosOn(VariableValue val) {
return new FieldInfo(var, this.info.removeInfosOn(val));
}
}
......@@ -24,7 +24,8 @@ public abstract class HigherInfo {
public abstract HigherInfo copyTo(OperationList list);
public abstract HigherInfo removeInfosOn(OperationList list, HigherInfo refInfos);
public abstract HigherInfo removeInfosDependingOn(OperationList list, HigherInfo refInfos);
public abstract HigherInfo removeInfosOn(VariableValue val);
public abstract HigherInfo access(Variable v);
......@@ -51,14 +52,14 @@ public abstract class HigherInfo {
public abstract HigherInfo normalize();
public abstract HigherInfo toLoop(LoopValue value);
public abstract HigherInfo toLoop(LoopValue value, HigherInfo oldInfo);
public abstract HigherInfo inverse();
// Do not remove, used for if info to avoid recursion
public abstract HigherInfo removeInfo(HigherInfo inf);
public static HigherInfo getSelfInfo(VariableValue value, Access access) {
public static HigherInfo getSelfInfo(Value value, Access access) {
if (access.equals(Access.intAccess))
return new ValueInfo(value, new IntRangeInfo(new Calcul(value), new Calcul(value)));
......
......@@ -82,7 +82,18 @@ public class IfInflow extends Inflow {
}
@Override
public void removeInfosOn(OperationList list) {
public void removeInfosDependingOn(OperationList list) {
this.getCurrentInflow().removeInfosDependingOn(list);
}
@Override
public void removeInfosOn(VariableValue list) {
this.getCurrentInflow().removeInfosOn(list);
}
@Override
public LoopInflow getClosestLoopInflow() {
return this.getCurrentInflow().getClosestLoopInflow();
}
}
\ No newline at end of file
......@@ -44,9 +44,9 @@ public class IfInfo extends HigherInfo {
}
@Override
public HigherInfo removeInfosOn(OperationList var, HigherInfo refInfos) {
return new IfInfo(this.condition, this.then.removeInfosOn(var, refInfos),
this.els.removeInfosOn(var, refInfos));
public HigherInfo removeInfosDependingOn(OperationList var, HigherInfo refInfos) {
return new IfInfo(this.condition, this.then.removeInfosDependingOn(var, refInfos),
this.els.removeInfosDependingOn(var, refInfos));
}
@Override
......@@ -117,7 +117,12 @@ public class IfInfo extends HigherInfo {
}
@Override
public HigherInfo toLoop(LoopValue value) {
return new IfInfo(this.condition, this.then.toLoop(value), this.els.toLoop(value));
public HigherInfo toLoop(LoopValue value, HigherInfo oldInfo) {
return new IfInfo(this.condition, this.then.toLoop(value, oldInfo), this.els.toLoop(value, oldInfo));
}
@Override
public HigherInfo removeInfosOn(VariableValue val) {
return new IfInfo(this.condition, this.then.removeInfosOn(val), this.els.removeInfosOn(val));
}
}
......@@ -24,5 +24,8 @@ public abstract class Inflow {
public abstract void newIfInflow(IfElseStructure ifElse, OperationList[] conditions);
public abstract void removeInfosOn(OperationList list);
public abstract void removeInfosDependingOn(OperationList list);
public abstract void removeInfosOn(VariableValue list);
public abstract LoopInflow getClosestLoopInflow();
}
\ No newline at end of file
......@@ -10,24 +10,30 @@ public class LoopInflow extends BasicInflow {
public LoopInflow(BasicInflow p, Expression e) {
super(p);
this.condition = e;
this.currentInfos = p.currentInfos;
}
public Expression getConditionExp() {return this.condition;}
public HigherInfo updateInfos() {
HigherInfo loopedInfos = this.currentInfos.normalize().toLoop(value).normalize();
Logger.debug(""+loopedInfos);
HigherInfo deduced = this.getConditionExp().toOperationList().knowing(false, loopedInfos);
HigherInfo newInfos = new AndInfo(loopedInfos, deduced);
Logger.debug("" + newInfos.removeInfosOn(new OperationList(value), newInfos).normalize());
return newInfos.removeInfosOn(new OperationList(value), newInfos).normalize();
HigherInfo deduced = this.getConditionExp().toOperationList().knowing(true, this.currentInfos);
Logger.debug("Deduced : "+deduced+" from "+this.currentInfos);
HigherInfo newInfos = new AndInfo(this.currentInfos, deduced);
Logger.debug("" + newInfos.removeInfosDependingOn(new OperationList(value), newInfos).normalize());
return newInfos.removeInfosDependingOn(new OperationList(value), newInfos).normalize();
}
@Override
public void setInfo(HigherInfo info) {
Logger.debug("Hey : "+info);
Logger.debug("Hey : "+info.toLoop(value));
super.setInfo(info);
}
@Override
public LoopInflow getClosestLoopInflow() {
if (this.childInflow != null) {
LoopInflow closest = this.childInflow.getClosestLoopInflow();
return closest;
}
return this;
}
}
package inflow;
import language.parser.tokens.Access;
public class LoopValue implements Value {
public final LoopInflow loop;
......@@ -10,4 +12,9 @@ public class LoopValue implements Value {
public String toString() {
return "loopIndex";
}
public HigherInfo getInfos(HigherInfo refInfos) {
return new AndInfo(refInfos.getInfosOn(this),
HigherInfo.getSelfInfo(this, Access.intAccess));
}
}
......@@ -80,7 +80,7 @@ public class NoInfo extends HigherInfo {
}
@Override
public HigherInfo removeInfosOn(OperationList var, HigherInfo refInfos) {
public HigherInfo removeInfosDependingOn(OperationList var, HigherInfo refInfos) {
return this;
}
......@@ -90,7 +90,12 @@ public class NoInfo extends HigherInfo {
}
@Override
public HigherInfo toLoop(LoopValue value) {
public HigherInfo toLoop(LoopValue value, HigherInfo oldInfo) {
return this;
}
@Override
public HigherInfo removeInfosOn(VariableValue val) {
return NoInfo.instance;
}
}
......@@ -101,8 +101,8 @@ public class OrInfo extends HigherInfo {
}
@Override
public HigherInfo removeInfosOn(OperationList var, HigherInfo refInfos) {
return new OrInfo(this.info1.removeInfosOn(var, null), this.info2.removeInfosOn(var, null));
public HigherInfo removeInfosDependingOn(OperationList var, HigherInfo refInfos) {
return new OrInfo(this.info1.removeInfosDependingOn(var, null), this.info2.removeInfosDependingOn(var, null));
}
@Override
......@@ -111,7 +111,12 @@ public class OrInfo extends HigherInfo {
}
@Override
public HigherInfo toLoop(LoopValue value) {
return new OrInfo(this.info1.toLoop(value), this.info2.toLoop(value));
public HigherInfo toLoop(LoopValue value, HigherInfo oldInfo) {
return new OrInfo(this.info1.toLoop(value, oldInfo), this.info2.toLoop(value, oldInfo));
}
@Override
public HigherInfo removeInfosOn(VariableValue val) {
return new OrInfo(this.info1.removeInfosOn(val), this.info2.removeInfosOn(val));
}
}
package inflow;
public interface OtherValue extends Value {
}
......@@ -39,7 +39,7 @@ public class ValueInfo extends HigherInfo {
if (arg == null)
return this.info.apply(thisExp, otherExp, opType, null, refInfos);
return arg.apply(thisExp, otherExp, opType, this, refInfos);
return otherExp.getInfos(refInfos, false).apply(thisExp, otherExp, opType, this, refInfos);
}
@Override
......@@ -110,7 +110,7 @@ public class ValueInfo extends HigherInfo {
}
@Override
public HigherInfo removeInfosOn(OperationList var, HigherInfo refInfos) {
public HigherInfo removeInfosDependingOn(OperationList var, HigherInfo refInfos) {
if (var.operationList.isEmpty())
if (var.getLastValue() instanceof VariableValue)
if (this.info.use((VariableValue) var.getLastValue()))
......@@ -124,7 +124,14 @@ public class ValueInfo extends HigherInfo {
}
@Override
public HigherInfo toLoop(LoopValue value) {
return new ValueInfo(this.value, info.toLoop(this.value, value));
public HigherInfo toLoop(LoopValue value, HigherInfo oldInfo) {
return info.toLoop(this.value, value, oldInfo);
}
@Override
public HigherInfo removeInfosOn(VariableValue val) {
if (val == value)
return NoInfo.instance;
return this;
}
}
package info;
import compiler.Variable;
import inflow.*;
import inflow.AndInfo;
import inflow.HigherInfo;
import inflow.LoopValue;
import inflow.OperationEnum;
import inflow.OperationList;
import inflow.OrInfo;
import inflow.Value;
import inflow.ValueInfo;
import inflow.VariableValue;
import main.Logger;
public class BooleanValueInfo extends Info {
public final boolean value;
......@@ -65,12 +73,13 @@ public class BooleanValueInfo extends Info {
}
}
else if (opType == OperationEnum.INT_INF) {
if (this.value)
if (this.value) {
return new AndInfo(
argExp.getInfos(refInfos, true).apply(argExp, null, OperationEnum.INT_UP_TO_1, null, refInfos)
.setValue(refExp.getLastValue()),
refExp.getInfos(refInfos, true).apply(refExp, null, OperationEnum.INT_DOWN_TO_1, null, refInfos)
.setValue(argExp.getLastValue()));
}
else {
return new AndInfo(
argExp.getInfos(refInfos, true).apply(argExp, null, OperationEnum.INT_DOWN_TO, null, refInfos)
......@@ -114,7 +123,7 @@ public class BooleanValueInfo extends Info {
}
@Override
public Info toLoop(Value assignedTo, LoopValue value) {
return this;
public HigherInfo toLoop(Value assignedTo, LoopValue value, HigherInfo oldInfos) {
return new ValueInfo(assignedTo, this);
}
}
package info;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import inflow.*;
import inflow.AndInfo;
import inflow.ConstantValue;
import inflow.HigherInfo;
import inflow.LoopValue;
import inflow.MethodUse;
import inflow.NoInfo;
import inflow.OperationEnum;
import inflow.OperationList;
import inflow.Value;
import inflow.ValueInfo;
import inflow.VariableValue;
import main.Logger;
public class Calcul {
public final Ligne calc1, calc2;
......@@ -15,7 +27,7 @@ public class Calcul {
this(new Ligne(i));
}
public Calcul(VariableValue v) {
public Calcul(Value v) {
this(new Ligne(v));
}
......@@ -58,8 +70,8 @@ public class Calcul {
return new Calcul(c1, c2);
}
public Set<VariableValue> getValues() {
Set<VariableValue> value = this.calc1.getValues();
public Set<Value> getValues() {
Set<Value> value = this.calc1.getValues();
value.addAll(this.calc2.getValues());
return value;
}
......@@ -78,6 +90,8 @@ public class Calcul {
@Override
public String toString() {
if (this.calc2.isConstant() && this.calc2.getConstant() == 1)
return this.calc1.toString();
return this.calc1 + " / " + this.calc2;
}
......@@ -101,22 +115,45 @@ public class Calcul {
return this.applyInf0().apply(new MethodUse(OperationEnum.BOOL_NOT));
}
public Calcul toLoop(Value assignedTo, LoopValue value) {
public HigherInfo toLoop(Value assignedTo, LoopValue value, HigherInfo oldInfos) {
if (this.isConstant())
return this;
return new ValueInfo(assignedTo, new IntRangeInfo(this, this));
LinkedList<Value> values = new LinkedList<>();
values.add(assignedTo);
if (this.calc2.isConstant() && this.calc2.getConstant() == 1 && this.calc1.elements.size() == 2)
if (this.calc1.getMult(values) == 1 && this.calc1.getMult(new LinkedList<>()) != 0) {
Element e1 = new Element((VariableValue)assignedTo);
Element e2 = new Element(this.calc1.getMult(new LinkedList<>()));
LinkedList<Element> els = new LinkedList<>();
els.add(e1); els.add(e2);
return new Calcul(new Ligne(els));
if (this.calc2.isConstant() && this.calc2.getConstant() == 1 && this.calc1.elements.size() == 2) {
Element e = null;
for (Element ee : this.calc1.elements)
if (ee.var.size() == 1 &&
assignedTo instanceof VariableValue &&
ee.var.get(0) instanceof VariableValue &&
((VariableValue)ee.var.get(0)).possessedBy == ((VariableValue)assignedTo).possessedBy)
e = ee;
if (e != null && e.multiplicateur == 1 && this.calc1.getMult(new LinkedList<>()) != 0) {
Element e2 = new Element(from(value), this.calc1.getMult(new LinkedList<>()));
Arrays.asList(e2);
HigherInfo i = oldInfos.apply(new OperationList(assignedTo),
new OperationList(new ConstantValue(new IntRangeInfo(
new Calcul(new Ligne(from(e2))), new Calcul(new Ligne(from(e2)))
))),
OperationEnum.INT_ADD, NoInfo.instance, oldInfos).setValue(assignedTo);
OperationList deduced = new OperationList(assignedTo)
.apply(new MethodUse(OperationEnum.INT_DIV, new OperationList(new ConstantValue(new IntRangeInfo(
new Calcul(this.calc1.getMult(new LinkedList<>())), new Calcul(this.calc1.getMult(new LinkedList<>())))
))));
HigherInfo i2 = deduced.getInfos(NoInfo.instance, false).apply(deduced, new OperationList(new ConstantValue(oldInfos)), OperationEnum.INT_SUB, NoInfo.instance, oldInfos).setValue(value);
return new AndInfo(i, i2);
}
}
return null;
return NoInfo.instance;
}
@SuppressWarnings("unchecked")
public static <T> LinkedList<T> from(T ele) {
LinkedList list = new LinkedList<>();
list.add(ele);
return list;
}
}
......@@ -129,7 +166,7 @@ class Ligne {
this.elements.add(new Element(value));
}
public Ligne(VariableValue var) {
public Ligne(Value var) {
this.elements = new LinkedList<>();
this.elements.add(new Element(var));
}
......@@ -170,8 +207,8 @@ class Ligne {
return new Ligne(newList).normalize();
}
public Set<VariableValue> getValues() {
Set<VariableValue> set = new HashSet<>();
public Set<Value> getValues() {
Set<Value> set = new HashSet<>();
this.elements.stream().forEach(e -> e.var.forEach(v -> set.add(v)));
return set;
}
......@@ -199,7 +236,7 @@ class Ligne {
public Ligne normalize() {
LinkedList<Element> newList = new LinkedList<>();
loop: for (Element e : this.elements) {
LinkedList<VariableValue> vars = e.var;
LinkedList<Value> vars = e.var;
for (Element newEl : newList)
if (newEl.var.equals(vars))
......@@ -247,9 +284,13 @@ class Ligne {
public String toString() {
String s = "";
for (Element e : this.elements) {
for (VariableValue v : e.var)
s += v + " * ";
s += e.multiplicateur;
for (Value v : e.var)
if (v == e.var.getLast() && e.multiplicateur == 1)
s += v;
else
s += v + " * ";
if (e.multiplicateur != 1 || e.var.size() == 0)
s += e.multiplicateur;
if (e != this.elements.getLast())
s += " + ";
}
......@@ -258,15 +299,15 @@ class Ligne {
}
class Element {
public final LinkedList<VariableValue> var;
public final LinkedList<Value> var;
public final int multiplicateur;
protected Element(LinkedList<VariableValue> var, int m) {
protected Element(LinkedList<Value> var, int m) {
this.var = var;
this.multiplicateur = m;
}
public Element(VariableValue var) {
public Element(Value var) {
this.var = new LinkedList<>();
this.var.add(var);
this.multiplicateur = 1;
......@@ -280,7 +321,7 @@ class Element {
public OperationList toOperationList() {
OperationList list = new OperationList(new ConstantValue(new IntRangeInfo(this.multiplicateur)));
for (VariableValue v : this.var)
for (Value v : this.var)
list.apply(new MethodUse(OperationEnum.INT_MUL, new OperationList(v)));
return list;
......
package info;
import compiler.Variable;
import inflow.*;
import inflow.HigherInfo;
import inflow.LoopValue;
import inflow.OperationEnum;
import inflow.OperationList;
import inflow.Value;
import inflow.VariableValue;
public abstract class Info {
......@@ -26,7 +30,7 @@ public abstract class Info {
return this.knowing1(caller, thisExp, otherExp, opType, refInfos);
}
public abstract Info toLoop(Value assignedTo, LoopValue value);
public abstract HigherInfo toLoop(Value assignedTo, LoopValue value, HigherInfo oldInfos);
public abstract