]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBinary.java
Merge "Remove unused import in DeleteHandler"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EBinary.java
index 58274a7a0269553521a840af33b5362faf6d8a70..274624aee0e08e97c22ad7c2f7c1ac1183c5d049 100755 (executable)
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.common.names.Names;\r
-import org.simantics.scl.compiler.common.precedence.Associativity;\r
-import org.simantics.scl.compiler.common.precedence.Precedence;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.errors.NotPatternException;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs;\r
-import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;\r
-import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-\r
-\r
-\r
-public class EBinary extends ASTExpression {\r
-    public static final int NEGATION_LEVEL = 6;\r
-    \r
-    public Expression left;\r
-    public ArrayList<EBinaryRightSide> rights = new ArrayList<EBinaryRightSide>();\r
-    public EVar negation;\r
-\r
-    public EBinary(Expression left, EVar negation) {\r
-        this.left = left;\r
-        this.negation = negation;\r
-    }\r
-\r
-    private EBinary(Expression left, EVar operator, Expression right) {\r
-        this.left = left;\r
-        rights.add(new EBinaryRightSide(operator, right));\r
-    }\r
-\r
-    public static EBinary create(Expression left, EVar operator, Expression right) {\r
-        if(left instanceof EBinary) {\r
-            EBinary left_ = (EBinary)left;\r
-            left_.rights.add(new EBinaryRightSide(operator, right));\r
-            return left_;\r
-        }\r
-        else\r
-            return new EBinary(left, operator, right);\r
-    }\r
-\r
-    @Override\r
-    public Expression resolve(TranslationContext context) {\r
-        return parseOperators(context).resolve(context);\r
-    }\r
-    \r
-    public Expression parseOperators(TranslationContext context) {\r
-        ArrayList<Expression> output = new ArrayList<Expression>();\r
-        ArrayList<Expression> ops = new ArrayList<Expression>();\r
-        ArrayList<EVar> opAsts = new ArrayList<EVar>();\r
-        \r
-        EVar negation = this.negation;\r
-        \r
-        output.add(left);\r
-        for(EBinaryRightSide right : rights) {\r
-            // Read op\r
-            Expression op = context.resolveExpression(right.operator.location, right.operator.name);\r
-            if(op == null)\r
-                return new EError(location);\r
-            Precedence opPrec = op.getPrecedence();\r
-            while(!ops.isEmpty()) {\r
-                Expression oldOp = ops.get(ops.size()-1);\r
-                Precedence oldOpPrecedence = oldOp.getPrecedence();\r
-                \r
-                if(oldOpPrecedence.level < opPrec.level)\r
-                    break;\r
-                if(oldOpPrecedence.level == opPrec.level) {\r
-                    if(opPrec.associativity == Associativity.RIGHT)\r
-                        break;\r
-                    if(opPrec.associativity == Associativity.NONASSOC) {\r
-                        context.getErrorLog().log(right.operator.location, \r
-                                "Operator " + right.operator.name + " is not associative.");\r
-                        return new EError(location);    \r
-                    }\r
-                }\r
-                \r
-                // Pop op                \r
-                ops.remove(ops.size()-1);\r
-                Expression r = output.remove(output.size()-1);\r
-                Expression l = output.remove(output.size()-1);\r
-                output.add(binary(l, oldOp, opAsts.remove(opAsts.size()-1), r));\r
-            }\r
-            if(negation != null && ops.isEmpty()) {\r
-                if(opPrec.level <= NEGATION_LEVEL) {      \r
-                    SCLValue neg = context.getEnvironment().getValue(Names.Prelude_neg);\r
-                    if(neg == null) {\r
-                        context.getErrorLog().log(location, \r
-                                "Couldn't resolve variable neg.");\r
-                        return new EError(location);\r
-                    }\r
-                    output.set(0, unary(neg, negation, output.get(0)));\r
-                    negation = null;\r
-                }\r
-            }\r
-            ops.add(op);\r
-            opAsts.add(right.operator);\r
-            \r
-            // Read value\r
-            output.add(right.right);\r
-        }\r
-        \r
-        // Pop rest\r
-        while(!ops.isEmpty()) {            \r
-            Expression oldOp = ops.remove(ops.size()-1);\r
-            Expression r = output.remove(output.size()-1);\r
-            Expression l = output.remove(output.size()-1);\r
-            output.add(binary(l, oldOp, opAsts.remove(opAsts.size()-1), r));\r
-        }\r
-        if(negation != null) {\r
-            SCLValue neg = context.getEnvironment().getValue(Names.Prelude_neg);\r
-            if(neg == null) {\r
-                context.getErrorLog().log(location, \r
-                        "Couldn't resolve variable neg.");\r
-                return new EError(location);\r
-            }\r
-            output.set(0, unary(neg, negation, output.get(0)));\r
-        }\r
-        \r
-        return output.get(0);\r
-        \r
-        //System.out.println("parseOperators: " + this);\r
-        //return parse(context, left, rights.listIterator(), new Precedence(-1, Associativity.NONASSOC));\r
-    }\r
-\r
-    /*\r
-    private Expression parse(TranslationContext context,\r
-            Expression lhs, ListIterator<EBinaryRightSide> it, Precedence minPrec) {\r
-        while(it.hasNext()) {\r
-            EBinaryRightSide right = it.next();\r
-            SCLValue op = context.resolveValue(right.operator.name);\r
-            if(op == null) {\r
-                context.getErrorLog().log(right.operator, \r
-                        "Couldn't resolve variable " + right.operator.name + ".");\r
-                return lhs;\r
-            }\r
-            Precedence opPrec = op.getPrecedence();\r
-            if(minPrec.level > opPrec.level)\r
-                break;\r
-            Expression rhs = right.right;\r
-            while(it.hasNext()) {\r
-                EVar var = it.next().operator;\r
-                SCLValue nextOp = context.resolveValue(var.name);\r
-                if(nextOp == null) {\r
-                    context.getErrorLog().log(var, \r
-                            "Couldn't resolve variable " + var.name + ".");\r
-                    return lhs;\r
-                }\r
-                it.previous();\r
-                Precedence nextPrec = nextOp.getPrecedence();\r
-                int precDiff = opPrec.level - nextPrec.level;\r
-                if(precDiff == 0) {\r
-                    if(opPrec.associativity == Associativity.LEFT)\r
-                        break;\r
-                    else if(opPrec.associativity == Associativity.NONASSOC) {\r
-                        context.getErrorLog().log(it.next().operator, "Nonassociative operator.");\r
-                        return lhs;\r
-                    }\r
-                }\r
-                else if(precDiff > 0)\r
-                    break;\r
-                rhs = parse(context, rhs, it, nextPrec);\r
-            }\r
-            lhs = binary(lhs, op, right.operator, rhs);\r
-        }   \r
-        return lhs;\r
-    }\r
-    */\r
-    private Expression binary(Expression lhs, Expression op, EVar opAst, Expression rhs) {\r
-        return new EApply(Locations.combine(lhs.location, rhs.location), op, lhs, rhs);        \r
-    }\r
-    \r
-    private Expression unary(SCLValue operator, EVar opAst, Expression expression) {\r
-        EConstant op = new EConstant(opAst.location, operator);\r
-        return new EApply(expression.location /*wrong*/, op, expression);\r
-    }\r
-    \r
-    @Override\r
-    public EVar getPatternHead() throws NotPatternException {\r
-        if(rights.size() == 1)\r
-            return rights.get(0).operator;\r
-        else\r
-            throw new NotPatternException(this);\r
-    }\r
-    \r
-    @Override\r
-    public LhsType getLhsType() throws NotPatternException {\r
-        if(rights.size() == 1)\r
-            return new FunctionDefinitionLhs(rights.get(0).operator.name);\r
-        else\r
-            throw new InternalCompilerError();\r
-    }\r
-        \r
-    @Override\r
-    public void getParameters(TranslationContext context,\r
-            ArrayList<Expression> parameters) {\r
-        parseOperators(context).getParameters(context, parameters);\r
-    }\r
-\r
-    public static Expression negate(EVar op, Expression expression) {\r
-        if(expression instanceof EBinary) {\r
-            ((EBinary)expression).negation = op;\r
-            return expression;\r
-        }\r
-        /*else if(expression instanceof EIntegerLiteral) {\r
-            EIntegerLiteral literal = (EIntegerLiteral)expression;\r
-            literal.value = -literal.value;\r
-            return expression;\r
-        }*/\r
-        else\r
-            return new EBinary(expression, op);\r
-    }\r
-    \r
-    @Override\r
-    public int getFunctionDefinitionArity() throws NotPatternException {\r
-        return 2;\r
-    }\r
-    \r
-    @Override\r
-    public void setLocationDeep(long loc) {\r
-        if(location == Locations.NO_LOCATION) {\r
-            location = loc;\r
-            left.setLocationDeep(loc);\r
-            if(negation != null)\r
-                negation.setLocationDeep(loc);\r
-            for(EBinaryRightSide right : rights)\r
-                right.setLocationDeep(loc);\r
-        }\r
-    }\r
-    \r
-    @Override\r
-    public Expression accept(ExpressionTransformer transformer) {\r
-        return transformer.transform(this);\r
-    }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.common.names.Names;
+import org.simantics.scl.compiler.common.precedence.Associativity;
+import org.simantics.scl.compiler.common.precedence.Precedence;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs;
+import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;
+import org.simantics.scl.compiler.errors.Locations;
+
+
+
+public class EBinary extends ASTExpression {
+    public static final int NEGATION_LEVEL = 6;
+    
+    public Expression left;
+    public ArrayList<EBinaryRightSide> rights = new ArrayList<EBinaryRightSide>();
+    public EVar negation;
+
+    public EBinary(Expression left, EVar negation) {
+        this.left = left;
+        this.negation = negation;
+    }
+
+    private EBinary(Expression left, EVar operator, Expression right) {
+        this.left = left;
+        rights.add(new EBinaryRightSide(operator, right));
+    }
+
+    public static EBinary create(Expression left, EVar operator, Expression right) {
+        if(left instanceof EBinary) {
+            EBinary left_ = (EBinary)left;
+            left_.rights.add(new EBinaryRightSide(operator, right));
+            return left_;
+        }
+        else
+            return new EBinary(left, operator, right);
+    }
+
+    @Override
+    public Expression resolve(TranslationContext context) {
+        return parseOperators(context).resolve(context);
+    }
+    
+    public Expression parseOperators(TranslationContext context) {
+        ArrayList<Expression> output = new ArrayList<Expression>();
+        ArrayList<Expression> ops = new ArrayList<Expression>();
+        ArrayList<EVar> opAsts = new ArrayList<EVar>();
+        
+        EVar negation = this.negation;
+        
+        output.add(left);
+        for(EBinaryRightSide right : rights) {
+            // Read op
+            Expression op = context.resolveExpression(right.operator.location, right.operator.name);
+            if(op == null)
+                return new EError(location);
+            Precedence opPrec = op.getPrecedence();
+            while(!ops.isEmpty()) {
+                Expression oldOp = ops.get(ops.size()-1);
+                Precedence oldOpPrecedence = oldOp.getPrecedence();
+                
+                if(oldOpPrecedence.level < opPrec.level)
+                    break;
+                if(oldOpPrecedence.level == opPrec.level) {
+                    if(opPrec.associativity == Associativity.RIGHT)
+                        break;
+                    if(opPrec.associativity == Associativity.NONASSOC) {
+                        context.getErrorLog().log(right.operator.location, 
+                                "Operator " + right.operator.name + " is not associative.");
+                        return new EError(location);    
+                    }
+                }
+                
+                // Pop op                
+                ops.remove(ops.size()-1);
+                Expression r = output.remove(output.size()-1);
+                Expression l = output.remove(output.size()-1);
+                output.add(binary(l, oldOp, opAsts.remove(opAsts.size()-1), r));
+            }
+            if(negation != null && ops.isEmpty()) {
+                if(opPrec.level <= NEGATION_LEVEL) {      
+                    SCLValue neg = context.getEnvironment().getValue(Names.Prelude_neg);
+                    if(neg == null) {
+                        context.getErrorLog().log(location, 
+                                "Couldn't resolve variable neg.");
+                        return new EError(location);
+                    }
+                    output.set(0, unary(neg, negation, output.get(0)));
+                    negation = null;
+                }
+            }
+            ops.add(op);
+            opAsts.add(right.operator);
+            
+            // Read value
+            output.add(right.right);
+        }
+        
+        // Pop rest
+        while(!ops.isEmpty()) {            
+            Expression oldOp = ops.remove(ops.size()-1);
+            Expression r = output.remove(output.size()-1);
+            Expression l = output.remove(output.size()-1);
+            output.add(binary(l, oldOp, opAsts.remove(opAsts.size()-1), r));
+        }
+        if(negation != null) {
+            SCLValue neg = context.getEnvironment().getValue(Names.Prelude_neg);
+            if(neg == null) {
+                context.getErrorLog().log(location, 
+                        "Couldn't resolve variable neg.");
+                return new EError(location);
+            }
+            output.set(0, unary(neg, negation, output.get(0)));
+        }
+        
+        return output.get(0);
+        
+        //System.out.println("parseOperators: " + this);
+        //return parse(context, left, rights.listIterator(), new Precedence(-1, Associativity.NONASSOC));
+    }
+
+    /*
+    private Expression parse(TranslationContext context,
+            Expression lhs, ListIterator<EBinaryRightSide> it, Precedence minPrec) {
+        while(it.hasNext()) {
+            EBinaryRightSide right = it.next();
+            SCLValue op = context.resolveValue(right.operator.name);
+            if(op == null) {
+                context.getErrorLog().log(right.operator, 
+                        "Couldn't resolve variable " + right.operator.name + ".");
+                return lhs;
+            }
+            Precedence opPrec = op.getPrecedence();
+            if(minPrec.level > opPrec.level)
+                break;
+            Expression rhs = right.right;
+            while(it.hasNext()) {
+                EVar var = it.next().operator;
+                SCLValue nextOp = context.resolveValue(var.name);
+                if(nextOp == null) {
+                    context.getErrorLog().log(var, 
+                            "Couldn't resolve variable " + var.name + ".");
+                    return lhs;
+                }
+                it.previous();
+                Precedence nextPrec = nextOp.getPrecedence();
+                int precDiff = opPrec.level - nextPrec.level;
+                if(precDiff == 0) {
+                    if(opPrec.associativity == Associativity.LEFT)
+                        break;
+                    else if(opPrec.associativity == Associativity.NONASSOC) {
+                        context.getErrorLog().log(it.next().operator, "Nonassociative operator.");
+                        return lhs;
+                    }
+                }
+                else if(precDiff > 0)
+                    break;
+                rhs = parse(context, rhs, it, nextPrec);
+            }
+            lhs = binary(lhs, op, right.operator, rhs);
+        }   
+        return lhs;
+    }
+    */
+    private Expression binary(Expression lhs, Expression op, EVar opAst, Expression rhs) {
+        return new EApply(Locations.combine(lhs.location, rhs.location), op, lhs, rhs);        
+    }
+    
+    private Expression unary(SCLValue operator, EVar opAst, Expression expression) {
+        EConstant op = new EConstant(opAst.location, operator);
+        return new EApply(expression.location /*wrong*/, op, expression);
+    }
+    
+    @Override
+    public EVar getPatternHead() throws NotPatternException {
+        if(rights.size() == 1)
+            return rights.get(0).operator;
+        else
+            throw new NotPatternException(this);
+    }
+    
+    @Override
+    public LhsType getLhsType() throws NotPatternException {
+        if(rights.size() == 1)
+            return new FunctionDefinitionLhs(rights.get(0).operator.name);
+        else
+            throw new InternalCompilerError();
+    }
+        
+    @Override
+    public void getParameters(TranslationContext context,
+            ArrayList<Expression> parameters) {
+        parseOperators(context).getParameters(context, parameters);
+    }
+
+    public static Expression negate(EVar op, Expression expression) {
+        if(expression instanceof EBinary) {
+            ((EBinary)expression).negation = op;
+            return expression;
+        }
+        /*else if(expression instanceof EIntegerLiteral) {
+            EIntegerLiteral literal = (EIntegerLiteral)expression;
+            literal.value = -literal.value;
+            return expression;
+        }*/
+        else
+            return new EBinary(expression, op);
+    }
+    
+    @Override
+    public int getFunctionDefinitionPatternArity() throws NotPatternException {
+        return 2;
+    }
+    
+    @Override
+    public void setLocationDeep(long loc) {
+        if(location == Locations.NO_LOCATION) {
+            location = loc;
+            left.setLocationDeep(loc);
+            if(negation != null)
+                negation.setLocationDeep(loc);
+            for(EBinaryRightSide right : rights)
+                right.setLocationDeep(loc);
+        }
+    }
+    
+    @Override
+    public Expression accept(ExpressionTransformer transformer) {
+        return transformer.transform(this);
+    }
+
+}