public static ForExpressionNode newForExpression(ParserRuleContext ctx, ListNode list, BaseNode expr) { return new ForExpressionNode( ctx, list, expr ); }
private ForIteration[] initializeContexts(EvaluationContext ctx, List<IterationContextNode> iterationContexts) { ForIteration[] ictx = new ForIteration[iterationContexts.size()]; int i = 0; for ( IterationContextNode icn : iterationContexts ) { ictx[i] = createQuantifiedExpressionIterationContext( ctx, icn ); if( i < iterationContexts.size()-1 && ictx[i].hasNextValue() ) { setValueIntoContext( ctx, ictx[i] ); } i++; } return ictx; }
@Override public DirectCompilerResult visit(ForExpressionNode n) { DirectCompilerResult expr = n.getExpression().accept(this); HashSet<FieldDeclaration> fds = new HashSet<>(); Expressions.NamedLambda namedLambda = Expressions.namedLambda( expr.getExpression(), n.getExpression().getText()); fds.add(namedLambda.field()); fds.addAll(expr.getFieldDeclarations()); List<Expression> expressions = n.getIterationContexts() .stream() .map(iter -> iter.accept(this)) .peek(r -> fds.addAll(r.getFieldDeclarations())) .map(DirectCompilerResult::getExpression) .collect(Collectors.toList()); // .satisfies(expr) return DirectCompilerResult.of( Expressions.ffor(expressions, namedLambda.name()), expr.resultType, fds); }
@Override public Object evaluate(EvaluationContext ctx) { try { ctx.enterFrame(); List results = new ArrayList( ); ctx.setValue("partial", results); ForIteration[] ictx = initializeContexts( ctx, iterationContexts); while ( nextIteration( ctx, ictx ) ) { Object result = expression.evaluate( ctx ); results.add( result ); } return results; } catch (EndpointOfRangeNotOfNumberException e) { // ast error already reported return null; } finally { ctx.exitFrame(); } }
public static boolean nextIteration(EvaluationContext ctx, ForIteration[] ictx) { int i = ictx.length-1; while ( i >= 0 && i < ictx.length ) { if ( ictx[i].hasNextValue() ) { setValueIntoContext( ctx, ictx[i] ); i++; } else { i--; } } return i >= 0; }
public Object rreturn(Function<EvaluationContext, Object> expression) { try { ctx.enterFrame(); List results = new ArrayList(); ctx.setValue("partial", results); ForIteration[] ictx = initializeContexts(ctx, iterationContexts); while (ForExpressionNode.nextIteration(ctx, ictx)) { Object result = expression.apply(ctx); results.add(result); } return results; } catch (EndpointOfRangeNotOfNumberException e) { // ast error already reported return null; } finally { ctx.exitFrame(); } }
private ForIteration createQuantifiedExpressionIterationContext(EvaluationContext ctx, IterationContextNode icn) { ForIteration fi = null; String name = icn.evaluateName( ctx ); Object result = icn.evaluate( ctx ); Object rangeEnd = icn.evaluateRangeEnd(ctx); if (rangeEnd == null) { Iterable values = result instanceof Iterable ? (Iterable) result : Collections.singletonList(result); fi = new ForIteration(name, values); } else { valueMustBeANumber(ctx, result); BigDecimal start = (BigDecimal) result; valueMustBeANumber(ctx, rangeEnd); BigDecimal end = (BigDecimal) rangeEnd; fi = new ForIteration(name, start, end); } return fi; }
private void valueMustBeANumber(EvaluationContext ctx, Object value) { if (!(value instanceof BigDecimal)) { ctx.notifyEvt(astEvent(Severity.ERROR, Msg.createMessage(Msg.VALUE_X_NOT_A_VALID_ENDPOINT_FOR_RANGE_BECAUSE_NOT_A_NUMBER, value), null)); throw new EndpointOfRangeNotOfNumberException(); } }
@Test public void testForExpression() { String inputExpression = "for item in order.items return item.price * item.quantity"; BaseNode forbase = parse( inputExpression ); assertThat( forbase, is( instanceOf( ForExpressionNode.class ) ) ); assertThat( forbase.getText(), is( inputExpression ) ); assertThat( forbase.getResultType(), is( BuiltInType.LIST ) ); ForExpressionNode forExpr = (ForExpressionNode) forbase; assertThat( forExpr.getIterationContexts().size(), is( 1 ) ); assertThat( forExpr.getExpression(), is( instanceOf( InfixOpNode.class ) ) ); assertThat( forExpr.getExpression().getText(), is( "item.price * item.quantity" ) ); IterationContextNode ic = forExpr.getIterationContexts().get( 0 ); assertThat( ic.getName().getText(), is("item") ); assertThat( ic.getExpression(), is( instanceOf( QualifiedNameNode.class ) ) ); assertThat( ic.getExpression().getText(), is("order.items") ); }
private ForIteration[] initializeContexts(EvaluationContext ctx, List<IterationContextCompiled> iterationContexts) { ForIteration[] ictx = new ForIteration[iterationContexts.size()]; int i = 0; for (IterationContextCompiled icn : iterationContexts) { ictx[i] = createQuantifiedExpressionIterationContext(ctx, icn); if (i < iterationContexts.size() - 1 && ictx[i].hasNextValue()) { ForExpressionNode.setValueIntoContext(ctx, ictx[i]); } i++; } return ictx; }