From 3ad22574da92977b82c5cbb340581a2ecbcb12eb Mon Sep 17 00:00:00 2001 From: Nathan PERIER <periernathan2000@gmail.com> Date: Sun, 1 May 2022 21:16:41 +0200 Subject: [PATCH] Added the rest of the code --- pom.xml | 16 +++- .../language/definition/FunctionDef.java | 31 +++++++ .../language/definition/ValueDef.java | 19 +++- .../language/definition/VariableDef.java | 7 +- .../expressions/ConditionExpression.java | 5 ++ .../expressions/ConstructorExpression.java | 5 ++ .../language/expressions/Expression.java | 2 + .../expressions/FunctionCallExpression.java | 88 +++++++++++++++++++ .../language/expressions/MatchExpression.java | 4 + .../language/expressions/NameExpression.java | 5 ++ .../language/expressions/NupleExpression.java | 16 ++-- .../PartialFunctionCallExpression.java | 4 + .../language/expressions/VarExpression.java | 7 +- .../expressions/base/BaseExpression.java | 5 ++ .../visitor/DuplicateExpressionVisitor.java | 9 ++ .../visitor/ExpressionArgVisitor.java | 7 +- .../visitor/ExpressionVisitor.java | 7 +- .../expressions/visitor/GetNamesVisitor.java | 15 +++- .../visitor/TypeReplacementVisitor.java | 12 ++- .../minichamo/language/typing/AliasType.java | 2 +- .../minichamo/language/typing/SumType.java | 7 -- .../minichamo/parsing/AssignementParser.java | 5 +- .../minichamo/parsing/ExpressionParser.java | 16 ++-- .../nperier/minichamo/parsing/Parser.java | 28 +++++- .../minichamo/parsing/TypedefParser.java | 2 - .../parsing/ExpressionParserTest.java | 31 ++++++- test.mll | 16 ++++ 27 files changed, 319 insertions(+), 52 deletions(-) create mode 100644 src/main/java/fr/insarennes/nperier/minichamo/language/expressions/ConstructorExpression.java create mode 100644 src/main/java/fr/insarennes/nperier/minichamo/language/expressions/FunctionCallExpression.java create mode 100644 src/main/java/fr/insarennes/nperier/minichamo/language/expressions/MatchExpression.java create mode 100644 src/main/java/fr/insarennes/nperier/minichamo/language/expressions/PartialFunctionCallExpression.java create mode 100644 test.mll diff --git a/pom.xml b/pom.xml index b253672..e956045 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 6f4582c..4b23ff2 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 7549999..f7827a8 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 844e76f..2f24ca7 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 79b450d..df935d4 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 0000000..5edd5d5 --- /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 1cfc483..905420e 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 0000000..3ec0712 --- /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 0000000..1fbe68f --- /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 8d69273..be9c76f 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 687d83f..62743ff 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 0000000..3d96626 --- /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 e33dbb3..4b2091d 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 51ea64f..67267ff 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 6e05962..a118e2d 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 c883681..54ecdf6 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 aa11146..9b1695a 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 14bfb1f..6b2da8e 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 b0e1b68..55c2746 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 e80e7a3..b30a804 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 aa927a9..798c08e 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 2cad1bb..0845227 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 bed4540..b14e9c9 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 e4f902c..c5e2812 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 a1bca33..74d711e 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 9999754..739d3ea 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 0000000..2a850f7 --- /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;; -- GitLab