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