Skip to content
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

Replace M.cases and M.casesFix with > 2 cases of appl with a switch on the constructor name #102

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 76 additions & 49 deletions statix.solver/src/main/java/mb/statix/arithmetic/ArithTerms.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,68 +4,95 @@

import java.io.Serializable;
import java.util.Arrays;
import java.util.Optional;

import org.metaborg.util.functions.Function2;
import org.metaborg.util.functions.Predicate2;

import mb.nabl2.terms.IApplTerm;
import mb.nabl2.terms.matching.TermMatch.IMatcher;
import mb.statix.spoofax.StatixTerms;

public class ArithTerms {

public static IMatcher<ArithTest> matchTest() {
// @formatter:off
return M.<ArithTest>cases(
M.appl0("Equal", (t) -> {
return new ArithTest("=", new Eq(), true);
}),
M.appl0("NotEqual", (t) -> {
return new ArithTest("\\=", new Neq(), false);
}),
M.appl0("GreaterThanEqual", (t) -> {
return new ArithTest(">=", new Gte(), false);
}),
M.appl0("LessThanEqual", (t) -> {
return new ArithTest("=<", new Lte(), false);
}),
M.appl0("GreaterThan", (t) -> {
return new ArithTest(">", new Ge(), false);
}),
M.appl0("LessThan", (t) -> {
return new ArithTest("<", new Le(), false);
})
);
// @formatter:on
return (subj, u) -> {
if(subj instanceof IApplTerm) {
final IApplTerm applTerm = (IApplTerm) subj;
final String termOp = applTerm.getOp();
switch(termOp) {
case "Equal":
return M.appl0("Equal", (t) -> {
return new ArithTest("=", new Eq(), true);
}).match(subj, u);
case "NotEqual":
return M.appl0("NotEqual", (t) -> {
return new ArithTest("\\=", new Neq(), false);
}).match(subj, u);
case "GreaterThanEqual":
return M.appl0("GreaterThanEqual", (t) -> {
return new ArithTest(">=", new Gte(), false);
}).match(subj, u);
case "LessThanEqual":
return M.appl0("LessThanEqual", (t) -> {
return new ArithTest("=<", new Lte(), false);
}).match(subj, u);
case "GreaterThan":
return M.appl0("GreaterThan", (t) -> {
return new ArithTest(">", new Ge(), false);
}).match(subj, u);
case "LessThan":
return M.appl0("LessThan", (t) -> {
return new ArithTest("<", new Le(), false);
}).match(subj, u);
}
}
return Optional.empty();
};
}

public static IMatcher<ArithExpr> matchExpr() {
// @formatter:off
return M.<ArithExpr>casesFix(m -> Arrays.asList(
StatixTerms.varTerm().map(TermExpr::new),
StatixTerms.intTerm().map(TermExpr::new),
M.appl2("Add", m, m, (t, ae1, ae2) -> {
return new BinExpr("+", ae1, ae2, new Add());
}),
M.appl2("Mul", m, m, (t, ae1, ae2) -> {
return new BinExpr("*", ae1, ae2, new Mul());
}),
M.appl2("Sub", m, m, (t, ae1, ae2) -> {
return new BinExpr("-", ae1, ae2, new Sub());
}),
M.appl2("Min", m, m, (t, ae1, ae2) -> {
return new BinExpr("min", ae1, ae2, new Min());
}),
M.appl2("Max", m, m, (t, ae1, ae2) -> {
return new BinExpr("max", ae1, ae2, new Max());
}),
M.appl2("Mod", m, m, (t, ae1, ae2) -> {
return new BinExpr("mod", ae1, ae2, new Mod());
}),
M.appl2("Div", m, m, (t, ae1, ae2) -> {
return new BinExpr("div", ae1, ae2, new Div());
})
));
// @formatter:on
return (subj, u) -> {
if(subj instanceof IApplTerm) {
final IApplTerm applTerm = (IApplTerm) subj;
final String termOp = applTerm.getOp();
switch(termOp) {
case "Var":
return StatixTerms.varTerm().map(t -> (ArithExpr) new TermExpr(t)).match(subj, u);
case "Int":
return StatixTerms.intTerm().map(t -> (ArithExpr) new TermExpr(t)).match(subj, u);
case "Add":
return M.appl2("Add", matchExpr(), matchExpr(), (t, ae1, ae2) -> {
return (ArithExpr) new BinExpr("+", ae1, ae2, new Add());
}).match(subj, u);
case "Mul":
return M.appl2("Mul", matchExpr(), matchExpr(), (t, ae1, ae2) -> {
return (ArithExpr) new BinExpr("*", ae1, ae2, new Mul());
}).match(subj, u);
case "Sub":
return M.appl2("Sub", matchExpr(), matchExpr(), (t, ae1, ae2) -> {
return (ArithExpr) new BinExpr("-", ae1, ae2, new Sub());
}).match(subj, u);
case "Min":
return M.appl2("Min", matchExpr(), matchExpr(), (t, ae1, ae2) -> {
return (ArithExpr) new BinExpr("min", ae1, ae2, new Min());
}).match(subj, u);
case "Max":
return M.appl2("Max", matchExpr(), matchExpr(), (t, ae1, ae2) -> {
return (ArithExpr) new BinExpr("max", ae1, ae2, new Max());
}).match(subj, u);
case "Mod":
return M.appl2("Mod", matchExpr(), matchExpr(), (t, ae1, ae2) -> {
return (ArithExpr) new BinExpr("mod", ae1, ae2, new Mod());
}).match(subj, u);
case "Div":
return M.appl2("Div", matchExpr(), matchExpr(), (t, ae1, ae2) -> {
return (ArithExpr) new BinExpr("div", ae1, ae2, new Div());
}).match(subj, u);
}
}
return Optional.empty();
};
}

private static class Add implements Function2<Integer, Integer, Integer>, Serializable {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package mb.statix.spoofax;

import static mb.nabl2.terms.build.TermBuild.B;
import static mb.nabl2.terms.matching.TermMatch.M;

import java.util.List;
import java.util.Optional;

Expand All @@ -14,12 +11,16 @@
import com.google.common.collect.Streams;
import com.google.inject.Inject;

import mb.nabl2.terms.IApplTerm;
import mb.nabl2.terms.IStringTerm;
import mb.nabl2.terms.ITerm;
import mb.nabl2.terms.matching.TermMatch.IMatcher;
import mb.nabl2.terms.stratego.TermIndex;
import mb.statix.solver.ITermProperty;
import mb.statix.solver.persistent.SolverResult;

import static mb.nabl2.terms.build.TermBuild.B;
import static mb.nabl2.terms.matching.TermMatch.M;

public class STX_get_ast_property extends StatixPrimitive {

@Inject public STX_get_ast_property() {
Expand Down Expand Up @@ -61,16 +62,29 @@ public class STX_get_ast_property extends StatixPrimitive {
}

private void warnOnInvalidProp(ITerm prop) {
// @formatter:off
IMatcher<ITerm> propMatcher = M.cases(
M.appl0("Type"),
M.appl0("Ref"),
M.appl1("Prop", M.string())
);
// @formatter:on
if(!propMatcher.match(prop).isPresent()) {
logger.warn("Expected Type(), Ref() or Prop(\"<name>\") as property, but got {}.", prop);
if(prop instanceof IApplTerm) {
final IApplTerm applTerm = (IApplTerm) prop;
final String termOp = applTerm.getOp();
switch(termOp) {
case "Type":
if(applTerm.getArity() == 0) {
return;
}
break;
case "Ref":
if(applTerm.getArity() == 0) {
return;
}
break;
case "Prop":
if(applTerm.getArity() == 1 && applTerm.getArgs()
.get(0) instanceof IStringTerm) {
return;
}
break;
}
}
logger.warn("Expected Type(), Ref() or Prop(\"<name>\") as property, but got {}.", prop);
}

}
Loading