From: Hannu Niemistö Date: Wed, 21 Sep 2016 11:27:57 +0000 (+0300) Subject: Check that do block is not empty. X-Git-Tag: v1.25.0~103 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=cd25d2a522265d13a159babac67a3430eaa23ec2;p=simantics%2Fplatform.git Check that do block is not empty. A new check is needed, because parser was modified before to allow empty blocks. Change-Id: I7fa51c7ef25cae6a51e69f9a39378780094c0d8e --- diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java index 295f3c176..ff1312540 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java @@ -1,98 +1,100 @@ -package org.simantics.scl.compiler.elaboration.expressions; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; -import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; -import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement; -import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement; -import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement; -import org.simantics.scl.compiler.elaboration.expressions.block.Statement; -import org.simantics.scl.compiler.errors.Locations; - -public class EBlock extends ASTExpression { - - LinkedList statements = new LinkedList(); - boolean monadic; - - public EBlock() { - } - - public void addStatement(Statement statement) { - statements.add(statement); - } - - public void setMonadic(boolean monadic) { - this.monadic = monadic; - } - - public LinkedList getStatements() { - return statements; - } - - @Override - public Expression resolve(TranslationContext context) { - if(statements.isEmpty()) - throw new InternalCompilerError(); - int i = statements.size()-1; - Statement last = statements.get(i); - if(!(last instanceof GuardStatement)) { - context.getErrorLog().log(last.location, "Block should end with an expression"); - return new EError(location); - } - - Expression in = ((GuardStatement)last).value; - while(--i >= 0) { - Statement cur = statements.get(i); - if(cur instanceof RuleStatement) { - int endId = i+1; - while(i>0 && statements.get(i-1) instanceof RuleStatement) - --i; - in = extractRules(i, endId, in); - } - else if(cur instanceof LetStatement && ((LetStatement)cur).pattern.isFunctionPattern()) { - int endId = i+1; - while(i>0 && (cur = statements.get(i-1)) instanceof LetStatement && - ((LetStatement)cur).pattern.isFunctionPattern()) - --i; - in = extractLet(i, endId, in); - } - else - in = cur.toExpression(context, monadic, in); - } - return in.resolve(context); - } - - private Expression extractRules(int begin, int end, Expression in) { - return new EPreRuleset(statements.subList(begin, end).toArray(new RuleStatement[end-begin]), in); - } - - @SuppressWarnings("unchecked") - private Expression extractLet(int begin, int end, Expression in) { - return new EPreLet((List)(List)statements.subList(begin, end), in); - } - - public static Expression create(ArrayList statements) { - EBlock block = new EBlock(); - for(Expression statement : statements) - block.addStatement(new GuardStatement(statement)); - return block; - } - - @Override - public void setLocationDeep(long loc) { - if(location == Locations.NO_LOCATION) { - location = loc; - for(Statement statement : statements) - statement.setLocationDeep(loc); - } - } - - @Override - public Expression accept(ExpressionTransformer transformer) { - return transformer.transform(this); - } - -} +package org.simantics.scl.compiler.elaboration.expressions; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; +import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; +import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement; +import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement; +import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement; +import org.simantics.scl.compiler.elaboration.expressions.block.Statement; +import org.simantics.scl.compiler.errors.Locations; + +public class EBlock extends ASTExpression { + + LinkedList statements = new LinkedList(); + boolean monadic; + + public EBlock() { + } + + public void addStatement(Statement statement) { + statements.add(statement); + } + + public void setMonadic(boolean monadic) { + this.monadic = monadic; + } + + public LinkedList getStatements() { + return statements; + } + + @Override + public Expression resolve(TranslationContext context) { + if(statements.isEmpty()) { + context.getErrorLog().log(location, "Block must contain at least one statement."); + return new EError(location); + } + int i = statements.size()-1; + Statement last = statements.get(i); + if(!(last instanceof GuardStatement)) { + context.getErrorLog().log(last.location, "Block should end with an expression"); + return new EError(location); + } + + Expression in = ((GuardStatement)last).value; + while(--i >= 0) { + Statement cur = statements.get(i); + if(cur instanceof RuleStatement) { + int endId = i+1; + while(i>0 && statements.get(i-1) instanceof RuleStatement) + --i; + in = extractRules(i, endId, in); + } + else if(cur instanceof LetStatement && ((LetStatement)cur).pattern.isFunctionPattern()) { + int endId = i+1; + while(i>0 && (cur = statements.get(i-1)) instanceof LetStatement && + ((LetStatement)cur).pattern.isFunctionPattern()) + --i; + in = extractLet(i, endId, in); + } + else + in = cur.toExpression(context, monadic, in); + } + return in.resolve(context); + } + + private Expression extractRules(int begin, int end, Expression in) { + return new EPreRuleset(statements.subList(begin, end).toArray(new RuleStatement[end-begin]), in); + } + + @SuppressWarnings("unchecked") + private Expression extractLet(int begin, int end, Expression in) { + return new EPreLet((List)(List)statements.subList(begin, end), in); + } + + public static Expression create(ArrayList statements) { + EBlock block = new EBlock(); + for(Expression statement : statements) + block.addStatement(new GuardStatement(statement)); + return block; + } + + @Override + public void setLocationDeep(long loc) { + if(location == Locations.NO_LOCATION) { + location = loc; + for(Statement statement : statements) + statement.setLocationDeep(loc); + } + } + + @Override + public Expression accept(ExpressionTransformer transformer) { + return transformer.transform(this); + } + +}