X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fderiving%2FIODeriver.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fderiving%2FIODeriver.java;h=1726d7d02127792da3842bf8ce8541b8b05bf5f4;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/IODeriver.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/IODeriver.java new file mode 100644 index 000000000..1726d7d02 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/IODeriver.java @@ -0,0 +1,187 @@ +package org.simantics.scl.compiler.internal.deriving; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.common.datatypes.Constructor; +import org.simantics.scl.compiler.common.names.Name; +import org.simantics.scl.compiler.constants.ByteConstant; +import org.simantics.scl.compiler.constants.IntegerConstant; +import org.simantics.scl.compiler.elaboration.errors.NotPatternException; +import org.simantics.scl.compiler.elaboration.expressions.Case; +import org.simantics.scl.compiler.elaboration.expressions.EApply; +import org.simantics.scl.compiler.elaboration.expressions.EBlock; +import org.simantics.scl.compiler.elaboration.expressions.EConstant; +import org.simantics.scl.compiler.elaboration.expressions.ELiteral; +import org.simantics.scl.compiler.elaboration.expressions.EMatch; +import org.simantics.scl.compiler.elaboration.expressions.EPreLet; +import org.simantics.scl.compiler.elaboration.expressions.EVar; +import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement; +import org.simantics.scl.compiler.elaboration.modules.SCLValue; +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 IODeriver implements InstanceDeriver { + + private static final Name WRITE = Name.create("Serialization", "write"); + private static final Name READ = Name.create("Serialization", "read"); + private static final Name IO_SIZE = Name.create("Serialization", "ioSize"); + + @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 IO 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; + } + + DInstanceAst instanceAst = new DInstanceAst(der.location, der.context, der.name, der.types); + ValueRepository valueDefs = new ValueRepository(); + + SCLValue write = environment.getValue(WRITE); + SCLValue read = environment.getValue(READ); + SCLValue ioSize = environment.getValue(IO_SIZE); + + // Generate write + for(int id=0;id statements = new ArrayList(); + statements.add( + new EApply(new EConstant(write), new EVar("s"), + new ELiteral(new ByteConstant((byte)id)))); + for(int i=0;iemptyList()));*/ + } catch (NotPatternException e) { + errorLog.log(e.getExpression().location, "Not a pattern."); + } + } + + // Generate read + { + Expression lhs = new EApply( + new EVar("read"), + new EVar("s") + ); + Case[] cases = new Case[tcon.constructors.length]; + for(int id=0;id assignments = new ArrayList(l); + for(int i=0;iemptyList()));*/ + } catch (NotPatternException e) { + errorLog.log(e.getExpression().location, "Not a pattern."); + } + } + + // Generate ioSize + for(int id=0;idemptyList()));*/ + } catch (NotPatternException e) { + errorLog.log(e.getExpression().location, "Not a pattern."); + } + } + + instancesAst.add(new ProcessedDInstanceAst(instanceAst, valueDefs)); + } + +}