@Override public DirectCompilerResult visitExpressionTextual(FEEL_1_1Parser.ExpressionTextualContext ctx) { DirectCompilerResult expr = visit( ctx.expr ); return expr; }
@Override public DirectCompilerResult visitPowExpression(FEEL_1_1Parser.PowExpressionContext ctx) { DirectCompilerResult left = visit(ctx.powerExpression()); DirectCompilerResult right = visit(ctx.filterPathExpression()); String opText = ctx.op.getText(); InfixOperator op = InfixOperator.determineOperator(opText); if (op == InfixOperator.POW) { return visitPow(left, right); } else { throw new UnsupportedOperationException("this was a visitPowExpression but unrecognized op: " + opText); // parser problem. } }
@Override public DirectCompilerResult visitSignedUnaryExpressionPlus(FEEL_1_1Parser.SignedUnaryExpressionPlusContext ctx) { DirectCompilerResult unaryExpr = visit(ctx.unaryExpressionNotPlusMinus()); return unaryExpr; }
@Override public DirectCompilerResult visitUnaryTestsRoot(FEEL_1_1Parser.UnaryTestsRootContext ctx) { return visit(ctx.unaryTests()); }
@Override public DirectCompilerResult visitParametersPositional(FEEL_1_1Parser.ParametersPositionalContext ctx) { return visit(ctx.positionalParameters()); }
@Override public DirectCompilerResult visitFormalParameters(FEEL_1_1Parser.FormalParametersContext ctx) { List<DirectCompilerResult> exprs = new ArrayList<>(); for (FEEL_1_1Parser.FormalParameterContext fpc : ctx.formalParameter()) { exprs.add(visit(fpc)); } MethodCallExpr list = new MethodCallExpr(null, "list"); exprs.stream().map(DirectCompilerResult::getExpression).forEach(list::addArgument); return DirectCompilerResult.of(list, BuiltInType.LIST, DirectCompilerResult.mergeFDs(exprs.toArray(new DirectCompilerResult[]{}))); }
@Override public DirectCompilerResult visitPositionalParameters(FEEL_1_1Parser.PositionalParametersContext ctx) { List<DirectCompilerResult> exprs = new ArrayList<>(); for (FEEL_1_1Parser.ExpressionContext ec : ctx.expression()) { exprs.add(visit(ec)); } MethodCallExpr list = new MethodCallExpr(null, "list"); exprs.stream().map(DirectCompilerResult::getExpression).forEach(list::addArgument); return DirectCompilerResult.of(list, BuiltInType.LIST, DirectCompilerResult.mergeFDs(exprs.toArray(new DirectCompilerResult[]{}))); }
@Override public DirectCompilerResult visitPositiveUnaryTestIneq(FEEL_1_1Parser.PositiveUnaryTestIneqContext ctx) { DirectCompilerResult endpoint = visit(ctx.endpoint()); String opText = ctx.op.getText(); UnaryOperator op = UnaryOperator.determineOperator(opText); return createUnaryTestExpression(ctx, endpoint, op); }
@Override public DirectCompilerResult visitFunctionDefinition(FEEL_1_1Parser.FunctionDefinitionContext ctx) { boolean external = ctx.external != null; DirectCompilerResult body = visit(ctx.body); return external ? declareExternalFunction(ctx) : declareInternalFunction(ctx.body, ctx.formalParameters()); }
@Override public DirectCompilerResult visitContext(FEEL_1_1Parser.ContextContext ctx) { if (ctx.contextEntries() == null) { return DirectCompilerResult.of(EMPTY_MAP, BuiltInType.CONTEXT); } else { return visit(ctx.contextEntries()); } }
@Override public DirectCompilerResult visitList(FEEL_1_1Parser.ListContext ctx) { if (ctx.expressionList() == null) { // empty list -> children are [ ] return DirectCompilerResult.of(EMPTY_LIST, BuiltInType.LIST); } else { // returns actual list return visit(ctx.expressionList()); } }
@Override public DirectCompilerResult visitRelExpressionInstanceOf(FEEL_1_1Parser.RelExpressionInstanceOfContext ctx) { DirectCompilerResult expr = visit(ctx.val); DirectCompilerResult type = visit(ctx.type()); MethodCallExpr isInstanceOfCall = new MethodCallExpr(type.getExpression(), "isInstanceOf"); isInstanceOfCall.addArgument(expr.getExpression()); return DirectCompilerResult.of(isInstanceOfCall, BuiltInType.BOOLEAN, mergeFDs(expr, type)); }
@Override public DirectCompilerResult visitUenpmPrimary(FEEL_1_1Parser.UenpmPrimaryContext ctx) { DirectCompilerResult expr = visit(ctx.primary()); if (ctx.qualifiedName() != null) { List<String> names = ctx.qualifiedName().nameRef().stream().map(nameRefContext -> ParserHelper.getOriginalText(nameRefContext)).collect(Collectors.toList()); expr = telescopePathAccessor(expr, names); } if (ctx.parameters() != null) { expr = buildFunctionCall(ctx, expr, ctx.parameters()); } return expr; }
@Override public DirectCompilerResult visitCondOr(FEEL_1_1Parser.CondOrContext ctx) { DirectCompilerResult left = visit( ctx.left ); DirectCompilerResult right = visit( ctx.right ); MethodCallExpr result = new MethodCallExpr(null, "or"); result.addArgument(left.getExpression()); result.addArgument(right.getExpression()); return DirectCompilerResult.of(result, BuiltInType.BOOLEAN).withFD(left).withFD(right); }
@Override public DirectCompilerResult visitCondAnd(FEEL_1_1Parser.CondAndContext ctx) { DirectCompilerResult left = visit( ctx.left ); DirectCompilerResult right = visit( ctx.right ); MethodCallExpr result = new MethodCallExpr(null, "and"); result.addArgument(left.getExpression()); result.addArgument(right.getExpression()); return DirectCompilerResult.of(result, BuiltInType.BOOLEAN).withFD(left).withFD(right); }
@Override public DirectCompilerResult visitPrimaryName(FEEL_1_1Parser.PrimaryNameContext ctx) { DirectCompilerResult name = visit(ctx.qualifiedName()); // fixme this should be handled in DirectCompilerResult but we should bring it up the entire tree. use global for now -ev // this.subExpressionContainsWildcard = ctx.qualifiedName().n1.getText().equals("?"); if (ctx.parameters() != null) { return buildFunctionCall(ctx, name, ctx.parameters()); } else { return name; } }
@Override public DirectCompilerResult visitSignedUnaryExpressionMinus(FEEL_1_1Parser.SignedUnaryExpressionMinusContext ctx) { DirectCompilerResult unaryExpr = visit(ctx.unaryExpression()); if ( unaryExpr.resultType != BuiltInType.NUMBER ) { throw new IllegalArgumentException("signedunary should be only over a FEEL NUMBER (bigdecimal)."); } // therefore, unaryExpr is a bigdecimal and operator is `-`. MethodCallExpr result = new MethodCallExpr(castToBigDecimal(unaryExpr.getExpression()), "negate"); return DirectCompilerResult.of(result, unaryExpr.resultType, unaryExpr.getFieldDeclarations() ); }
@Override public DirectCompilerResult visitRelExpressionBetween(FEEL_1_1Parser.RelExpressionBetweenContext ctx) { DirectCompilerResult value = visit(ctx.val); DirectCompilerResult start = visit(ctx.start); DirectCompilerResult end = visit(ctx.end); MethodCallExpr betweenCall = new MethodCallExpr(null, "between"); betweenCall.addArgument(new NameExpr("feelExprCtx")); betweenCall.addArgument(value.getExpression()); betweenCall.addArgument(start.getExpression()); betweenCall.addArgument(end.getExpression()); return DirectCompilerResult.of(betweenCall, BuiltInType.BOOLEAN).withFD(value).withFD(start).withFD(end); }
@Override public DirectCompilerResult visitPrimaryParens(FEEL_1_1Parser.PrimaryParensContext ctx) { DirectCompilerResult expr = visit( ctx.expression() ); EnclosedExpr result = new EnclosedExpr(expr.getExpression()); return DirectCompilerResult.of(result, expr.resultType, expr.getFieldDeclarations()); }
private DirectCompilerResult buildFunctionCall(ParserRuleContext ctx, DirectCompilerResult name, ParseTree params) { DirectCompilerResult parameters = visit(params); MethodCallExpr invokeCall = new MethodCallExpr(new NameExpr(CompiledFEELSupport.class.getSimpleName()), "invoke"); invokeCall.addArgument(new NameExpr("feelExprCtx")); invokeCall.addArgument(name.getExpression()); invokeCall.addArgument(parameters.getExpression()); return DirectCompilerResult.of(invokeCall, name.resultType).withFD(name).withFD(parameters); }