diff --git a/pom.xml b/pom.xml index b253672b2adb9e35e941ff2a509baf73b48a4020..e956045b26c53c9980bb8bba96fa9caa5d80f4cf 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ <groupId>fr.insarennes.nperier</groupId> <artifactId>minichamo</artifactId> - <version>1.0-SNAPSHOT</version> + <version>0.7</version> <build> <plugins> @@ -19,6 +19,20 @@ </configuration> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>3.2.2</version> + <configuration> + <archive> + <manifest> + <addClasspath>true</addClasspath> + <mainClass>fr.insarennes.nperier.minichamo.Main</mainClass> + </manifest> + </archive> + </configuration> + </plugin> + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/definition/FunctionDef.java b/src/main/java/fr/insarennes/nperier/minichamo/language/definition/FunctionDef.java index 6f4582cfab61a43ee7c8cc444220e0c6b27a4f7a..4b23ff28c005504fcb5754e58d0f7b98960cc4c0 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/definition/FunctionDef.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/definition/FunctionDef.java @@ -1,6 +1,8 @@ package fr.insarennes.nperier.minichamo.language.definition; +import fr.insarennes.nperier.minichamo.language.Context; import fr.insarennes.nperier.minichamo.language.assignement.param.VarParam; +import fr.insarennes.nperier.minichamo.language.expressions.Expression; import fr.insarennes.nperier.minichamo.language.typing.FunctionType; import fr.insarennes.nperier.minichamo.language.typing.GenericType; import fr.insarennes.nperier.minichamo.language.typing.Type; @@ -10,6 +12,7 @@ import fr.insarennes.nperier.minichamo.utils.SymbolPosition; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class FunctionDef extends VariableDef { @@ -37,6 +40,24 @@ public class FunctionDef extends VariableDef { return this; } + @Override + public Type getType() { + List<Type> sp = new ArrayList<>(); + for(VarParam p : params) { + sp.add(p.getType()); + } + sp.add(expr.getType()); + return new FunctionType(sp); + } + + @Override + public void setExpression(final Expression e) { + expr = e; + Type effective = e.getType(); + Map<String, Type> mapping = Type.unifyTwoMapping(returnType, effective); + replaceTypes(new ReplaceGenericsVisitor(mapping)); + } + public boolean isRecursive() { return recursive; } @@ -49,6 +70,10 @@ public class FunctionDef extends VariableDef { return params; } + public VarParam getParam(int i) { + return params.get(i); + } + public Type getReturnType() { return returnType; } @@ -64,6 +89,7 @@ public class FunctionDef extends VariableDef { for(VarParam p : params) { sp.add(p.getType()); } + sp.add(returnType); return new FunctionType(sp); } @@ -80,6 +106,11 @@ public class FunctionDef extends VariableDef { return new FunctionDef(this); } + @Override + public VariableDef evalIfPossible(Context ctx) { + return this; + } + @Override public boolean equals(Object o) { if(!(o instanceof FunctionDef)) { diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/definition/ValueDef.java b/src/main/java/fr/insarennes/nperier/minichamo/language/definition/ValueDef.java index 75499999acdc00b30fac7b0408bc99f1b6f180d0..f7827a85d37337f791cb72ace71a4dc0a79ad7b2 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/definition/ValueDef.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/definition/ValueDef.java @@ -1,7 +1,8 @@ package fr.insarennes.nperier.minichamo.language.definition; +import fr.insarennes.nperier.minichamo.language.Context; +import fr.insarennes.nperier.minichamo.language.expressions.Expression; import fr.insarennes.nperier.minichamo.language.typing.Type; -import fr.insarennes.nperier.minichamo.language.typing.visitor.ReplaceGenericsVisitor; import fr.insarennes.nperier.minichamo.language.typing.visitor.TypeVisitor; import fr.insarennes.nperier.minichamo.utils.SymbolPosition; @@ -14,11 +15,21 @@ public class ValueDef extends VariableDef { type = t; } + public ValueDef(String n, Expression e) { + super(n, null); + expr = e; + } + public ValueDef(ValueDef vd) { super(vd); type = vd.type; } + @Override + public Type getType() { + return expr.getType(); + } + @Override protected Type getDeclaredType() { return type; @@ -34,6 +45,12 @@ public class ValueDef extends VariableDef { return new ValueDef(this); } + @Override + public VariableDef evalIfPossible(Context ctx) { + setExpression(expr.evaluate(ctx)); + return this; + } + @Override protected void nameToDisplay(StringBuilder builder, String indent) { builder.append("let ").append(name).append(" : ").append(type); diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/definition/VariableDef.java b/src/main/java/fr/insarennes/nperier/minichamo/language/definition/VariableDef.java index 844e76f80795cb6682c42328c6c52e74a8098f85..2f24ca78a1c7de13c17d40560c997f030c57da7e 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/definition/VariableDef.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/definition/VariableDef.java @@ -1,5 +1,6 @@ package fr.insarennes.nperier.minichamo.language.definition; +import fr.insarennes.nperier.minichamo.language.Context; import fr.insarennes.nperier.minichamo.language.expressions.Expression; import fr.insarennes.nperier.minichamo.language.typing.Type; import fr.insarennes.nperier.minichamo.language.typing.visitor.ReplaceGenericsVisitor; @@ -13,7 +14,7 @@ import java.util.*; public abstract class VariableDef implements Displayable, Positioned { protected final String name; - private Expression expr; + protected Expression expr; private final List<NestedDefinition> nested; protected final SymbolPosition pos; @@ -76,12 +77,16 @@ public abstract class VariableDef implements Displayable, Positioned { getExpression().replaceTypes(visitor); } + abstract public Type getType(); + abstract public void completeDeclaredType(TypeVisitor<Type> visitor); abstract protected void nameToDisplay(StringBuilder builder, String indent); abstract public VariableDef duplicate(); + abstract public VariableDef evalIfPossible(Context ctx); + abstract protected Type getDeclaredType(); @Override diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/ConditionExpression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/ConditionExpression.java index 79b450da91c4c0c8fb7bec351488f927c22588f4..df935d4bb4db5908fab67d95c208acae996ce8e4 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/ConditionExpression.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/ConditionExpression.java @@ -68,6 +68,11 @@ public class ConditionExpression extends Expression { return condition.isComplex() || yes.isComplex() || no.isComplex(); } + @Override + public boolean isSeveralWords() { + return true; + } + @Override public void toDisplay(StringBuilder builder, String indent) { if(isComplex()) { diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/ConstructorExpression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/ConstructorExpression.java new file mode 100644 index 0000000000000000000000000000000000000000..5edd5d5d3f6849903a25a7bbca908209a8082c18 --- /dev/null +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/ConstructorExpression.java @@ -0,0 +1,5 @@ +package fr.insarennes.nperier.minichamo.language.expressions; + +public class ConstructorExpression { + +} diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/Expression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/Expression.java index 1cfc48391a57b306124e0a2818ef0306ca9d10a7..905420efe478ac7ef99ff705d72e4d728b642107 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/Expression.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/Expression.java @@ -21,6 +21,8 @@ public abstract class Expression implements Displayable { public abstract boolean isComplex(); + public abstract boolean isSeveralWords(); + public Expression duplicate() { return acceptVisitor(new DuplicateExpressionVisitor()); } diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/FunctionCallExpression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/FunctionCallExpression.java new file mode 100644 index 0000000000000000000000000000000000000000..3ec071216e9c31cd0a69694b4a3e50dd35df6263 --- /dev/null +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/FunctionCallExpression.java @@ -0,0 +1,88 @@ +package fr.insarennes.nperier.minichamo.language.expressions; + +import fr.insarennes.nperier.minichamo.language.Context; +import fr.insarennes.nperier.minichamo.language.definition.FunctionDef; +import fr.insarennes.nperier.minichamo.language.definition.ValueDef; +import fr.insarennes.nperier.minichamo.language.expressions.visitor.ExpressionArgVisitor; +import fr.insarennes.nperier.minichamo.language.expressions.visitor.ExpressionVisitor; +import fr.insarennes.nperier.minichamo.language.typing.FunctionType; +import fr.insarennes.nperier.minichamo.language.typing.Type; + +import java.util.ArrayList; +import java.util.List; + +public class FunctionCallExpression extends Expression { + + private final FunctionDef fun; + private final List<Expression> args; + + public FunctionCallExpression(final FunctionDef f, final List<Expression> el) { + fun = f; + args = new ArrayList<>(el); + // TODO unification + } + + public FunctionDef getFunction() { + return fun; + } + + public List<Expression> getArgs() { + return args; + } + + @Override + public Expression evaluate(Context ctx) { + Context ctx1 = ctx.duplicate(); + for(int i = 0; i < fun.getNbParams(); i++) { + Expression val = args.get(i).evaluate(ctx); + String n = fun.getParam(i).getVar(); + ctx1.addVariable(new ValueDef(n, val)); + } + return fun.getExpression().evaluate(ctx1); + } + + @Override + public Type getType() { + List<Type> sp = new ArrayList<>(); + for(Expression arg : args) { + sp.add(arg.getType()); + } + sp.add(fun.getReturnType()); + return new FunctionType(sp); + } + + @Override + public <T> T acceptVisitor(ExpressionVisitor<T> visitor) { + return null; + } + + @Override + public <V, T> T acceptVisitor(ExpressionArgVisitor<V, T> visitor, V arg) { + return null; + } + + @Override + public boolean isComplex() { + return args.stream().anyMatch(Expression::isComplex); + } + + @Override + public boolean isSeveralWords() { + return true; + } + + @Override + public void toDisplay(StringBuilder builder, String indent) { + builder.append(fun.getName()); + for(Expression e : args) { + builder.append(" "); + if(e.isSeveralWords()) { + builder.append("("); + e.toDisplay(builder, indent); + builder.append(")"); + } else { + e.toDisplay(builder, indent); + } + } + } +} diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/MatchExpression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/MatchExpression.java new file mode 100644 index 0000000000000000000000000000000000000000..1fbe68f6dbddd31d81250f9ef39544f125f44203 --- /dev/null +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/MatchExpression.java @@ -0,0 +1,4 @@ +package fr.insarennes.nperier.minichamo.language.expressions; + +public class MatchExpression { +} diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/NameExpression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/NameExpression.java index 8d692738862a2892168ce27949eccbff12bec7fd..be9c76fe2d4ce72c5da4f0e53aad831ee2d1d68c 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/NameExpression.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/NameExpression.java @@ -72,6 +72,11 @@ public class NameExpression extends Expression { return false; } + @Override + public boolean isSeveralWords() { + return false; + } + @Override public void toDisplay(StringBuilder builder, String indent) { builder.append(name); diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/NupleExpression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/NupleExpression.java index 687d83f869acb361baf1420f827ef3016e413223..62743ff0d8de07c11e247b3bf8111a1ea2e716e8 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/NupleExpression.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/NupleExpression.java @@ -35,12 +35,12 @@ public class NupleExpression extends Expression { @Override public <T> T acceptVisitor(ExpressionVisitor<T> visitor) { - return null; + return visitor.visitNuple(this); } @Override public <V, T> T acceptVisitor(ExpressionArgVisitor<V, T> visitor, V arg) { - return null; + return visitor.visitNuple(this, arg); } @Override @@ -48,25 +48,27 @@ public class NupleExpression extends Expression { return streamElements().anyMatch(Expression::isComplex); } + @Override + public boolean isSeveralWords() { + return true; + } + @Override public void toDisplay(StringBuilder builder, String indent) { if(isComplex()) { String indent1 = indent + "\t"; - builder.append("(\n").append(indent1); + builder.append("\n").append(indent1); elts.get(0).toDisplay(builder, indent1); for(int i = 1; i < elts.size(); i++) { builder.append(",\n").append(indent1); elts.get(i).toDisplay(builder, indent1); - } - builder.append("\n").append(indent).append(")"); + }; } else { - builder.append("("); elts.get(0).toDisplay(builder, indent); for(int i = 1; i < elts.size(); i++) { builder.append(", "); elts.get(i).toDisplay(builder, indent); } - builder.append(")"); } } } diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/PartialFunctionCallExpression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/PartialFunctionCallExpression.java new file mode 100644 index 0000000000000000000000000000000000000000..3d966269482f024a4de8185061c3c935a2831595 --- /dev/null +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/PartialFunctionCallExpression.java @@ -0,0 +1,4 @@ +package fr.insarennes.nperier.minichamo.language.expressions; + +public class PartialFunctionCallExpression { +} diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/VarExpression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/VarExpression.java index e33dbb3144431366a21c8d2f96d95add8a01549a..4b2091dfbe38c03f68fd2c35b182a844726a2024 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/VarExpression.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/VarExpression.java @@ -28,7 +28,7 @@ public class VarExpression extends Expression { @Override public Type getType() { - return vard.getExpression().getType(); + return vard.getType(); } @Override @@ -55,6 +55,11 @@ public class VarExpression extends Expression { return false; } + @Override + public boolean isSeveralWords() { + return false; + } + @Override public void toDisplay(StringBuilder builder, String indent) { builder.append(vard.getName()); diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/base/BaseExpression.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/base/BaseExpression.java index 51ea64f898257d1cdfa690e34de7e8daba485d54..67267ff38ddaaed2f8f007bca71e2f93872f668f 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/base/BaseExpression.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/base/BaseExpression.java @@ -27,6 +27,11 @@ public abstract class BaseExpression extends Expression { return false; } + @Override + public boolean isSeveralWords() { + return false; + } + @Override public void toDisplay(StringBuilder builder, String indent) { builder.append(toString()); diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/DuplicateExpressionVisitor.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/DuplicateExpressionVisitor.java index 6e059629638b3a01acce5c89f66ec02aa845b5b5..a118e2dd741ac1011a5576c3993ba9760ec58555 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/DuplicateExpressionVisitor.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/DuplicateExpressionVisitor.java @@ -1,5 +1,6 @@ package fr.insarennes.nperier.minichamo.language.expressions.visitor; +import fr.insarennes.nperier.minichamo.language.definition.FunctionDef; import fr.insarennes.nperier.minichamo.language.expressions.*; import fr.insarennes.nperier.minichamo.language.expressions.base.BaseExpression; @@ -35,4 +36,12 @@ public class DuplicateExpressionVisitor extends SimpleExpressionVisitor<Expressi public Expression visitNuple(NupleExpression e) { return new NupleExpression(e.streamElements().map(elt -> elt.acceptVisitor(this)).collect(Collectors.toList())); } + + @Override + public Expression visitFunction(FunctionCallExpression e) { + return new FunctionCallExpression( + (FunctionDef) e.getFunction().duplicate(), + e.getArgs().stream().map(arg -> arg.acceptVisitor(this)).collect(Collectors.toList()) + ); + } } diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/ExpressionArgVisitor.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/ExpressionArgVisitor.java index c883681ca17dd7181749558e7907feedd41b4382..54ecdf6569307c09c58e59b4b80fedd268fab21f 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/ExpressionArgVisitor.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/ExpressionArgVisitor.java @@ -1,9 +1,6 @@ package fr.insarennes.nperier.minichamo.language.expressions.visitor; -import fr.insarennes.nperier.minichamo.language.expressions.ConditionExpression; -import fr.insarennes.nperier.minichamo.language.expressions.NameExpression; -import fr.insarennes.nperier.minichamo.language.expressions.NupleExpression; -import fr.insarennes.nperier.minichamo.language.expressions.VarExpression; +import fr.insarennes.nperier.minichamo.language.expressions.*; import fr.insarennes.nperier.minichamo.language.expressions.base.*; public interface ExpressionArgVisitor<V,T> { @@ -28,4 +25,6 @@ public interface ExpressionArgVisitor<V,T> { T visitNuple(NupleExpression e, V arg); + T visitFunction(FunctionCallExpression e, V arg); + } diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/ExpressionVisitor.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/ExpressionVisitor.java index aa11146e8c34187c6a512ef037830c215e9de818..9b1695a0bfd4d09080bdea9a40476de1cfa48b8a 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/ExpressionVisitor.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/ExpressionVisitor.java @@ -1,9 +1,6 @@ package fr.insarennes.nperier.minichamo.language.expressions.visitor; -import fr.insarennes.nperier.minichamo.language.expressions.ConditionExpression; -import fr.insarennes.nperier.minichamo.language.expressions.NameExpression; -import fr.insarennes.nperier.minichamo.language.expressions.NupleExpression; -import fr.insarennes.nperier.minichamo.language.expressions.VarExpression; +import fr.insarennes.nperier.minichamo.language.expressions.*; import fr.insarennes.nperier.minichamo.language.expressions.base.*; public interface ExpressionVisitor<T> { @@ -28,4 +25,6 @@ public interface ExpressionVisitor<T> { T visitNuple(NupleExpression e); + T visitFunction(FunctionCallExpression e); + } diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/GetNamesVisitor.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/GetNamesVisitor.java index 14bfb1f2d2203805e494033dddf184ad3ce9b9da..6b2da8eb587c1e3360efa27902a93f64ce005c57 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/GetNamesVisitor.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/GetNamesVisitor.java @@ -1,13 +1,12 @@ package fr.insarennes.nperier.minichamo.language.expressions.visitor; -import fr.insarennes.nperier.minichamo.language.expressions.ConditionExpression; -import fr.insarennes.nperier.minichamo.language.expressions.NameExpression; -import fr.insarennes.nperier.minichamo.language.expressions.NupleExpression; -import fr.insarennes.nperier.minichamo.language.expressions.VarExpression; +import fr.insarennes.nperier.minichamo.language.assignement.param.VarParam; +import fr.insarennes.nperier.minichamo.language.expressions.*; import fr.insarennes.nperier.minichamo.language.expressions.base.BaseExpression; import java.util.HashSet; import java.util.Set; +import java.util.stream.Collectors; public class GetNamesVisitor extends SimpleExpressionVisitor<Set<String>> { @@ -42,4 +41,12 @@ public class GetNamesVisitor extends SimpleExpressionVisitor<Set<String>> { return res; } + @Override + public Set<String> visitFunction(FunctionCallExpression e) { + final Set<String> res = new HashSet<>(); + for(Expression arg : e.getArgs()) { + res.addAll(arg.acceptVisitor(this)); + } + return res; + } } diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/TypeReplacementVisitor.java b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/TypeReplacementVisitor.java index b0e1b686ca9fbcbddbbb7d752aa348ccdeb1358b..55c274632f9c41482323c92cf903a4fb5cf5969f 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/TypeReplacementVisitor.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/expressions/visitor/TypeReplacementVisitor.java @@ -1,9 +1,6 @@ package fr.insarennes.nperier.minichamo.language.expressions.visitor; -import fr.insarennes.nperier.minichamo.language.expressions.ConditionExpression; -import fr.insarennes.nperier.minichamo.language.expressions.NameExpression; -import fr.insarennes.nperier.minichamo.language.expressions.NupleExpression; -import fr.insarennes.nperier.minichamo.language.expressions.VarExpression; +import fr.insarennes.nperier.minichamo.language.expressions.*; import fr.insarennes.nperier.minichamo.language.expressions.base.BaseExpression; import fr.insarennes.nperier.minichamo.language.typing.Type; import fr.insarennes.nperier.minichamo.language.typing.visitor.ReplaceGenericsVisitor; @@ -53,4 +50,11 @@ public class TypeReplacementVisitor extends SimpleExpressionVisitor<Void> { e.streamElements().forEach(elt -> elt.acceptVisitor(this)); return null; } + + @Override + public Void visitFunction(FunctionCallExpression e) { + e.getArgs().forEach(arg -> arg.acceptVisitor(this)); + e.getFunction().replaceTypes(visitor); + return null; + } } diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/typing/AliasType.java b/src/main/java/fr/insarennes/nperier/minichamo/language/typing/AliasType.java index e80e7a32000ea8e2c4f95a29d5e4541b52d8f677..b30a804a148977e2cca459f2d07645c944585292 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/typing/AliasType.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/typing/AliasType.java @@ -29,7 +29,7 @@ public class AliasType extends Type { } @Override - public Type specify(Type[] sp) { // TODO propagate + public Type specify(Type[] sp) { int arity = getArity(); if(sp.length != arity) { throw new ParsingException("Alias type " + getName() + " has an arity of " + arity + " but got " + sp.length + " types"); diff --git a/src/main/java/fr/insarennes/nperier/minichamo/language/typing/SumType.java b/src/main/java/fr/insarennes/nperier/minichamo/language/typing/SumType.java index aa927a99686ae552098ac2c5ddb8d08ef6a773ac..798c08e823937a2e58a5e0ec80bc08201a7d9758 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/language/typing/SumType.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/language/typing/SumType.java @@ -144,13 +144,6 @@ public class SumType extends Type { public boolean equals(Object o) { if(super.equals(o)) { SumType t = (SumType) o; - - for(int i = 0; i < lconstructors.size(); i++) { - if(! getConstructor(i).equals(t.getConstructor(i))) { - System.out.println(getConstructor(i)); - System.out.println(t.getConstructor(i)); - } - } return getConstructors().equals(t.getConstructors()); } return false; diff --git a/src/main/java/fr/insarennes/nperier/minichamo/parsing/AssignementParser.java b/src/main/java/fr/insarennes/nperier/minichamo/parsing/AssignementParser.java index 2cad1bb61878e51edcaedb828b1bff4d69d2bd9c..0845227f0481fd4a70d094d612cf4b0b748b66c3 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/parsing/AssignementParser.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/parsing/AssignementParser.java @@ -5,7 +5,6 @@ import fr.insarennes.nperier.minichamo.language.Context; import fr.insarennes.nperier.minichamo.language.assignement.param.VarParam; import fr.insarennes.nperier.minichamo.language.definition.FunctionDef; import fr.insarennes.nperier.minichamo.language.definition.TypeDef; -import fr.insarennes.nperier.minichamo.language.definition.ValueDef; import fr.insarennes.nperier.minichamo.language.definition.VariableDef; import fr.insarennes.nperier.minichamo.language.expressions.Expression; import fr.insarennes.nperier.minichamo.lexing.tokens.TokenType; @@ -17,7 +16,9 @@ import java.util.stream.Collectors; public class AssignementParser { public static VariableDef parse(final TokenPeekIterator it, final Context context) { - return parse(it, context, true); + VariableDef res = parse(it, context, true); + context.addVariable(res); + return res; } protected static VariableDef parse(final TokenPeekIterator it, final Context context, boolean check) { diff --git a/src/main/java/fr/insarennes/nperier/minichamo/parsing/ExpressionParser.java b/src/main/java/fr/insarennes/nperier/minichamo/parsing/ExpressionParser.java index bed4540a048d33ca538fa87404dd28e1746a776f..b14e9c9bb6054cfbb111d2b1c652c66c9d8ae494 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/parsing/ExpressionParser.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/parsing/ExpressionParser.java @@ -52,16 +52,20 @@ public class ExpressionParser { return new ConditionExpression(cond, e1, e2); } + // public static Expression parseNameThenMaybeFunction(TokenPeekIterator it, Context ctx, Counter cpt) { + // TODO + // } + public static Optional<Expression> parseSimple(TokenPeekIterator it, Context ctx, Counter cpt) { if(it.peekIs(TokenType.NAME)) { return Optional.of(parseName(it, ctx, cpt)); } - if(it.peekIs(TokenType.CONSTRUCT_NAME)) { - // TODO - } - if(it.junkIf(TokenType.LBRACKET)) { - // TODO - } + // if(it.peekIs(TokenType.CONSTRUCT_NAME)) { + // TODO + // } + // if(it.junkIf(TokenType.LBRACKET)) { + // TODO + // } if(it.junkIf(TokenType.LPAREN)) { return Optional.of(parseInParen(it, ctx)); } diff --git a/src/main/java/fr/insarennes/nperier/minichamo/parsing/Parser.java b/src/main/java/fr/insarennes/nperier/minichamo/parsing/Parser.java index e4f902cdaade63d6587106940720a958f9a8ba82..c5e2812f720bee702acbcb38e8bdba0094aaff56 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/parsing/Parser.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/parsing/Parser.java @@ -1,7 +1,11 @@ package fr.insarennes.nperier.minichamo.parsing; +import fr.insarennes.nperier.minichamo.errors.ParsingException; import fr.insarennes.nperier.minichamo.language.Context; +import fr.insarennes.nperier.minichamo.language.definition.FunctionDef; import fr.insarennes.nperier.minichamo.language.definition.TypeDef; +import fr.insarennes.nperier.minichamo.language.definition.VariableDef; +import fr.insarennes.nperier.minichamo.language.typing.Type; import fr.insarennes.nperier.minichamo.lexing.Lexer; import fr.insarennes.nperier.minichamo.lexing.tokens.TokenType; import fr.insarennes.nperier.minichamo.utils.TokenPeekIterator; @@ -17,14 +21,32 @@ public class Parser { public void parse(Lexer lexer) { TokenPeekIterator it = new TokenPeekIterator(lexer); while(it.hasNext()) { - if(it.next().getType() == TokenType.TYPEDEF) { + if(it.junkIf(TokenType.TYPEDEF)) { TypeDef td = TypedefParser.parse(it, ctx); if(it.peek().getType() == TokenType.TERMINATION) { it.junk(); } - System.out.println(td); + td.display(); + } else if(it.junkIf(TokenType.LET)) { + VariableDef vd = AssignementParser.parse(it, ctx); + if(it.peek().getType() == TokenType.TERMINATION) { + it.junk(); + } + vd.display(); + String name = vd.getName(); + if(name.startsWith("_")) { + name = "-"; + } + Type type = vd.getType(); + if(vd instanceof FunctionDef) { + System.out.println(name + " : " + type + " = <fun>"); + } else if(!"()".equals(name)) { + System.out.println(name + " : " + type + " = " + vd.getExpression().evaluate(ctx)); + } + } else { + throw new ParsingException("Expected type declaration or variable assignment, got " + it.peek(), it); } - //System.out.println(TypeParser.parse(it, ctx)); + System.out.println(""); } } diff --git a/src/main/java/fr/insarennes/nperier/minichamo/parsing/TypedefParser.java b/src/main/java/fr/insarennes/nperier/minichamo/parsing/TypedefParser.java index a1bca33f90aee66226c30b71fda655d797e83938..74d711eafe3fcdd8c43f0c63198a7a65e82701dc 100644 --- a/src/main/java/fr/insarennes/nperier/minichamo/parsing/TypedefParser.java +++ b/src/main/java/fr/insarennes/nperier/minichamo/parsing/TypedefParser.java @@ -55,8 +55,6 @@ public class TypedefParser { final Set<String> lgenerics = generics.stream() .map(Type::getName) .collect(Collectors.toSet()); - System.out.println(lgenerics); - System.out.println(rgenerics); Set<String> diff = lgenerics.stream() .filter(s -> !rgenerics.contains(s)) .collect(Collectors.toSet()); diff --git a/src/test/java/fr/insarennes/nperier/minichamo/parsing/ExpressionParserTest.java b/src/test/java/fr/insarennes/nperier/minichamo/parsing/ExpressionParserTest.java index 9999754c8516a5c1382e7138df04e3bdf3ea3cff..739d3ea51fdb5c5dd4b75bd6c5695bb189dc8cf1 100644 --- a/src/test/java/fr/insarennes/nperier/minichamo/parsing/ExpressionParserTest.java +++ b/src/test/java/fr/insarennes/nperier/minichamo/parsing/ExpressionParserTest.java @@ -3,13 +3,12 @@ package fr.insarennes.nperier.minichamo.parsing; import fr.insarennes.nperier.minichamo.errors.ParsingException; import fr.insarennes.nperier.minichamo.language.Context; import fr.insarennes.nperier.minichamo.language.definition.ValueDef; -import fr.insarennes.nperier.minichamo.language.expressions.ConditionExpression; -import fr.insarennes.nperier.minichamo.language.expressions.Expression; -import fr.insarennes.nperier.minichamo.language.expressions.NameExpression; -import fr.insarennes.nperier.minichamo.language.expressions.VarExpression; +import fr.insarennes.nperier.minichamo.language.expressions.*; import fr.insarennes.nperier.minichamo.language.expressions.base.*; import fr.insarennes.nperier.minichamo.language.typing.BuiltinType; import fr.insarennes.nperier.minichamo.language.typing.GenericType; +import fr.insarennes.nperier.minichamo.language.typing.NupleType; +import fr.insarennes.nperier.minichamo.language.typing.Type; import fr.insarennes.nperier.minichamo.lexing.Lexer; import fr.insarennes.nperier.minichamo.lexing.tokens.TokenType; import fr.insarennes.nperier.minichamo.utils.SymbolPosition; @@ -18,6 +17,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.List; + public class ExpressionParserTest { private Context ctx; @@ -127,4 +128,26 @@ public class ExpressionParserTest { Assertions.assertThrows(ParsingException.class, () -> ExpressionParser.parse(it, ctx)); } + /*@Test + public void nupleTest() { + TokenPeekIterator it = new Lexer("(1, \"bonjour\", true);;").wrap(); + Expression e = ExpressionParser.parse(it, ctx); + e.display(); + Expression exp = new NupleExpression(List.of( + new IntExpression(1), + new StringExpression("bonjour"), + new BoolExpression(true) + )); + exp.display(); + Type t = new NupleType(new Type[] { + BuiltinType.integer(), + BuiltinType.str(), + BuiltinType.bool() + }); + Assertions.assertEquals(exp, e); + Assertions.assertEquals(t, e.getType()); + Assertions.assertTrue(it.junkIf(TokenType.TERMINATION)); + Assertions.assertFalse(it.hasNext()); + }*/ + } diff --git a/test.mll b/test.mll new file mode 100644 index 0000000000000000000000000000000000000000..2a850f70762543793b2e68820548526606a7f628 --- /dev/null +++ b/test.mll @@ -0,0 +1,16 @@ + +let a = 1;; + +let f a = a;; + +(* let b = f a;; *) + +let _c = 1.1;; + +type ('a, 'b) t = ('a * 'b) list;; + +type 'a graph = +| Leaf of 'a +| Node of 'a * ('a graph) list;; + +type int_graph = int graph;;