package org.simantics.scl.compiler.internal.deriving; import java.util.ArrayList; import org.simantics.scl.compiler.common.datatypes.Constructor; import org.simantics.scl.compiler.elaboration.errors.NotPatternException; import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EVar; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.elaboration.modules.TypeConstructor; import org.simantics.scl.compiler.environment.AmbiguousNameException; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.environment.Environments; import org.simantics.scl.compiler.errors.ErrorLog; import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst; import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst; import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst; import org.simantics.scl.compiler.internal.parsing.expressions.Expressions; import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst; import org.simantics.scl.compiler.internal.parsing.translation.ValueRepository; import org.simantics.scl.compiler.internal.parsing.types.TVarAst; import org.simantics.scl.compiler.types.TCon; class EqDeriver implements InstanceDeriver { @Override public void derive( ErrorLog errorLog, Environment environment, ArrayList instancesAst, DDerivingInstanceAst der) { // Analyze if(der.types.length != 1) { errorLog.log(der.location, "Invalid number of parameters to " + der.name); return; } TVarAst headType = DerivingUtils.getHeadType(der.types[0]); if(headType == null) { errorLog.log(der.types[0].location, "Cannot derive Eq instance for the type " + headType + "."); return; } TCon con; try { con = Environments.getTypeConstructorName(environment, headType.name); } catch (AmbiguousNameException e1) { errorLog.log(headType.location, e1.getMessage()); return; } if(con == null) { errorLog.log(headType.location, "Couldn't resolve " + headType.name); return; } TypeConstructor tcon = environment.getTypeConstructor(con); if(tcon == null) { errorLog.log(headType.location, "Didn't find type constructor for " + headType.name); return; } if(tcon.isOpen) { errorLog.log(headType.location, "Cannot derive instance for open data types."); return; } // Generate DInstanceAst instanceAst = new DInstanceAst(der.location, der.context, der.name, der.types); ValueRepository valueDefs = new ValueRepository(); for(Constructor constructor : tcon.constructors) { int l = constructor.parameterTypes.length; String[] par1 = new String[l]; String[] par2 = new String[l]; for(int i=0;i=0;--i) value = new EApply( new EVar("&&"), new EApply( new EVar("=="), new EVar(par1[i]), new EVar(par2[i])), value); try { DValueAst valueAst = new DValueAst(lhs, value); valueAst.setLocationDeep(der.location); valueDefs.add(valueAst); } catch (NotPatternException e) { errorLog.log(e.getExpression().location, "Not a pattern."); } } { Expression lhs = new EApply( new EVar("=="), new EVariable(new Variable("_")), new EVariable(new Variable("_"))); Expression value = new EVar("False"); try { DValueAst valueAst = new DValueAst(lhs, value); valueAst.setLocationDeep(der.location); valueDefs.add(valueAst); /*valueDefs.addAnnotation("==", new DAnnotationAst(new EVar("@private"), Collections.emptyList()));*/ } catch (NotPatternException e) { errorLog.log(e.getExpression().location, "Not a pattern."); } } instancesAst.add(new ProcessedDInstanceAst(instanceAst, valueDefs)); } }