X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Felaboration%2Fmatching%2FPatternMatchingCompiler.java;h=9bf056bef825fe3a6c3db4e0cbef0fed1572c6eb;hp=7f200a11c40167e48875f48ddc97d614ffeb33af;hb=a8758de5bc19e5adb3f618d3038743a164f09912;hpb=12d9af17384d960b75d58c3935d2b7b46d93e87b diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java index 7f200a11c..9bf056bef 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java @@ -1,6 +1,7 @@ package org.simantics.scl.compiler.internal.elaboration.matching; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; @@ -12,6 +13,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EConstant; import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.EViewPattern; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup; import org.simantics.scl.compiler.elaboration.modules.SCLValue; @@ -52,7 +54,7 @@ public class PatternMatchingCompiler { return newVals; } - private static void split(CodeWriter w, final Environment env, IVal[] scrutinee, final ICont success, ICont failure, List rows, int columnId) { + private static void splitByConstructors(CodeWriter w, final Environment env, IVal[] scrutinee, final ICont success, ICont failure, List rows, int columnId) { THashMap matrixMap = new THashMap(); ArrayList branches = new ArrayList(); ArrayList matrices = new ArrayList(); @@ -87,19 +89,34 @@ public class PatternMatchingCompiler { Expression constructor_ = applyConstructor.getFunction(); while(constructor_ instanceof EApplyType) constructor_ = ((EApplyType)constructor_).getExpression(); - SCLValue constructor = ((EConstant)constructor_).getValue(); - // TODO How type parameters are handled??? Expression[] parameters = applyConstructor.getParameters(); - - ExpressionMatrix matrix = matrixMap.get(constructor.getName()); - if(matrix == null) { - CodeWriter newW = w.createBlock(Types.getTypes(parameters)); - branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation())); - matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters())); - matrices.add(matrix); - matrixMap.put(constructor.getName(), matrix); + // TODO How type parameters are handled??? + if(constructor_ instanceof EConstant) { + SCLValue constructor = ((EConstant)constructor_).getValue(); + + ExpressionMatrix matrix = matrixMap.get(constructor.getName()); + if(matrix == null) { + CodeWriter newW = w.createBlock(Types.getTypes(parameters)); + branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation())); + matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters())); + matrices.add(matrix); + matrixMap.put(constructor.getName(), matrix); + } + matrix.rows.add(row.replace(columnId, parameters)); + } + else if(constructor_ instanceof ELiteral) { + Constant constructor = ((ELiteral)constructor_).getValue(); + + ExpressionMatrix matrix = matrixMap.get(constructor); + if(matrix == null) { + CodeWriter newW = w.createBlock(Types.getTypes(parameters)); + branches.add(new Branch(constructor, newW.getContinuation())); + matrix = new ExpressionMatrix(newW, replace(scrutinee, columnId, newW.getParameters())); + matrices.add(matrix); + matrixMap.put(constructor, matrix); + } + matrix.rows.add(row.replace(columnId, parameters)); } - matrix.rows.add(row.replace(columnId, parameters)); } else if(pattern instanceof EConstant) { EConstant applyConstructor = (EConstant)pattern; @@ -160,7 +177,7 @@ public class PatternMatchingCompiler { } catch (MatchException e) { throw new InternalCompilerError(); } - TypeConstructor cons = env.getTypeConstructor(con); + TypeConstructor cons = (TypeConstructor)env.getTypeDescriptor(con); int maxBranchCount = cons.isOpen ? Integer.MAX_VALUE : cons.constructors.length; if(branches.size() < maxBranchCount) @@ -172,21 +189,76 @@ public class PatternMatchingCompiler { w.switch_(scrutinee[columnId], branches.toArray(new Branch[branches.size()])); } + private static void splitByViewPattern(CodeWriter w, Environment env, IVal[] scrutinee, ICont success, + ICont failure, List rows, int viewPatternColumn) { + Row firstRow = rows.get(0); + EViewPattern firstViewPattern = (EViewPattern)firstRow.patterns[viewPatternColumn]; + firstRow.patterns[viewPatternColumn] = firstViewPattern.pattern; + int i; + for(i=1;i rows) { Row firstRow = rows.get(0); Expression[] patterns = firstRow.patterns; if(scrutinee.length != patterns.length) - throw new InternalCompilerError(); + throw new InternalCompilerError("Scrutinee and patterns have a different length"); // Find a non-variable pattern and split by it + int viewPatternColumn = -1; for(int i=0;i= 0) { + splitByViewPattern(w, env, scrutinee, success, failure, rows, viewPatternColumn); + return; + } - // No matching needed + // The first row has only variable patterns: no matching needed for(int i=0;i