Search in sources :

Example 1 with FunctionParam

use of com.googlecode.aviator.runtime.FunctionParam in project aviatorscript by killme2008.

the class ASMCodeGeneratorUnitTest method testOnLambdaDefine.

@Test
public void testOnLambdaDefine() throws Exception {
    this.codeGenerator.setParser(new Parser() {

        @Override
        public void setCodeGenerator(final CodeGenerator codeGenerator) {
        }

        @Override
        public void restoreScope(final ScopeInfo info) {
        }

        @Override
        public SymbolTable getSymbolTable() {
            return null;
        }

        @Override
        public CodeGenerator getCodeGenerator() {
            return ASMCodeGeneratorUnitTest.this.codeGenerator;
        }

        @Override
        public ScopeInfo enterScope(final boolean inForLoop) {
            return null;
        }
    });
    assertNull(this.codeGenerator.getLambdaGenerator());
    this.codeGenerator.onLambdaDefineStart(new Variable("lambda", 0, 0));
    LambdaGenerator lambdaGenerator = this.codeGenerator.getLambdaGenerator();
    assertNotNull(lambdaGenerator);
    this.codeGenerator.onLambdaArgument(new Variable("x", 0, 1), new FunctionParam(0, "x", false));
    this.codeGenerator.onLambdaArgument(new Variable("y", 0, 2), new FunctionParam(1, "y", false));
    this.codeGenerator.onLambdaBodyStart(new Variable(">", 0, 3));
    lambdaGenerator.onConstant(new Variable("x", 0, 4));
    lambdaGenerator.onConstant(new Variable("y", 0, 5));
    lambdaGenerator.onAdd(null);
    this.codeGenerator.onLambdaBodyEnd(new Variable("end", 0, 7));
    HashMap<String, Object> env = new HashMap<String, Object>();
    env.put("x", 2);
    env.put("y", 3);
    Object result = eval(env);
    assertTrue(result instanceof LambdaFunction);
    assertEquals(5, ((LambdaFunction) result).call(env, new AviatorJavaType("x"), new AviatorJavaType("y")).getValue(env));
    assertNull(this.codeGenerator.getLambdaGenerator());
}
Also used : LambdaGenerator(com.googlecode.aviator.code.LambdaGenerator) Variable(com.googlecode.aviator.lexer.token.Variable) HashMap(java.util.HashMap) SymbolTable(com.googlecode.aviator.lexer.SymbolTable) ScopeInfo(com.googlecode.aviator.parser.ScopeInfo) LambdaFunction(com.googlecode.aviator.runtime.function.LambdaFunction) CodeGenerator(com.googlecode.aviator.code.CodeGenerator) Parser(com.googlecode.aviator.parser.Parser) AviatorJavaType(com.googlecode.aviator.runtime.type.AviatorJavaType) FunctionParam(com.googlecode.aviator.runtime.FunctionParam) Test(org.junit.Test)

Example 2 with FunctionParam

use of com.googlecode.aviator.runtime.FunctionParam in project aviatorscript by killme2008.

the class ExpressionParser method lambda.

private void lambda(final boolean fn) {
    ensureFeatureEnabled(Feature.Lambda);
    this.scope.enterLambda();
    getCodeGeneratorWithTimes().onLambdaDefineStart(getPrevToken());
    this.scope.enterParen();
    move(true);
    int paramIndex = 0;
    FunctionParam lastParam = null;
    List<FunctionParam> variadicParams = new ArrayList<>(2);
    if (!expectChar(')')) {
        lastParam = lambdaArgument(paramIndex++);
        if (lastParam.isVariadic()) {
            variadicParams.add(lastParam);
        }
        while (expectChar(',')) {
            move(true);
            lastParam = lambdaArgument(paramIndex++);
            if (lastParam.isVariadic()) {
                variadicParams.add(lastParam);
            }
        }
    }
    // assert only one variadic param and it's the last one.
    if (variadicParams.size() > 1) {
        reportSyntaxError("The variadic parameter must be the last parameter: `" + variadicParams.get(0).getName() + "`");
    }
    if (variadicParams.size() > 0 && variadicParams.get(0) != lastParam) {
        reportSyntaxError("The variadic parameter must be the last parameter: `" + variadicParams.get(0).getName() + "`");
    }
    if (expectChar(')')) {
        this.scope.leaveParen();
        move(true);
        if (fn) {
            if (!expectChar('{')) {
                reportSyntaxError("expect '{'");
            }
        } else {
            if (!expectChar('-')) {
                reportSyntaxError("expect '->' for lambda body");
            }
            move(true);
            if (!expectChar('>')) {
                reportSyntaxError("expect '->' for lambda body");
            }
        }
        move(true);
        getCodeGeneratorWithTimes().onLambdaBodyStart(this.lookhead);
        statements();
        if (fn) {
            if (!expectChar('}')) {
                reportSyntaxError("missing '}' to close function body");
            }
        } else {
            if (this.lookhead != Variable.END) {
                reportSyntaxError("expect lambda 'end'");
            }
        }
        getCodeGeneratorWithTimes().onLambdaBodyEnd(this.lookhead);
        this.scope.leaveLambda();
        move(true);
    }
}
Also used : ArrayList(java.util.ArrayList) FunctionParam(com.googlecode.aviator.runtime.FunctionParam)

Example 3 with FunctionParam

use of com.googlecode.aviator.runtime.FunctionParam in project aviatorscript by killme2008.

the class LambdaFunction method newEnv.

protected Map<String, Object> newEnv(final Map<String, Object> parentEnv, final AviatorObject... args) {
    Env env = null;
    if (!this.inheritEnv) {
        final Env contextEnv = new Env(parentEnv, this.context);
        contextEnv.configure(this.context.getInstance(), this.expression);
        env = new Env(contextEnv);
        env.configure(this.context.getInstance(), this.expression);
    } else {
        assert (parentEnv == this.context);
        env = (Env) parentEnv;
    }
    if (args.length != this.params.size()) {
        throw new IllegalArgumentException("Wrong number of args(" + args.length + ") passed to " + getName() + "(" + this.params.size() + ")");
    }
    for (int i = 0; i < this.params.size(); i++) {
        FunctionParam param = this.params.get(i);
        final AviatorObject arg = args[i];
        Object value = arg.getValue(parentEnv);
        if (value == null && arg.getAviatorType() == AviatorType.JavaType && !parentEnv.containsKey(((AviatorJavaType) arg).getName())) {
            value = RuntimeUtils.getInstance(parentEnv).getFunction(((AviatorJavaType) arg).getName());
        }
        env.override(param.getName(), value);
    }
    return env;
}
Also used : AviatorObject(com.googlecode.aviator.runtime.type.AviatorObject) AviatorJavaType(com.googlecode.aviator.runtime.type.AviatorJavaType) AviatorObject(com.googlecode.aviator.runtime.type.AviatorObject) Env(com.googlecode.aviator.utils.Env) FunctionParam(com.googlecode.aviator.runtime.FunctionParam)

Example 4 with FunctionParam

use of com.googlecode.aviator.runtime.FunctionParam in project aviatorscript by killme2008.

the class ExpressionParser method lambdaArgument0.

private FunctionParam lambdaArgument0(final int index, final boolean isVariadic) {
    if (!isJavaIdentifier(this.lookhead.getLexeme())) {
        reportSyntaxError("illegal argument name: " + currentTokenLexeme());
    }
    final FunctionParam param = new FunctionParam(index, this.lookhead.getLexeme(), isVariadic);
    getCodeGeneratorWithTimes().onLambdaArgument(this.lookhead, param);
    move(true);
    return param;
}
Also used : FunctionParam(com.googlecode.aviator.runtime.FunctionParam)

Aggregations

FunctionParam (com.googlecode.aviator.runtime.FunctionParam)4 AviatorJavaType (com.googlecode.aviator.runtime.type.AviatorJavaType)2 CodeGenerator (com.googlecode.aviator.code.CodeGenerator)1 LambdaGenerator (com.googlecode.aviator.code.LambdaGenerator)1 SymbolTable (com.googlecode.aviator.lexer.SymbolTable)1 Variable (com.googlecode.aviator.lexer.token.Variable)1 Parser (com.googlecode.aviator.parser.Parser)1 ScopeInfo (com.googlecode.aviator.parser.ScopeInfo)1 LambdaFunction (com.googlecode.aviator.runtime.function.LambdaFunction)1 AviatorObject (com.googlecode.aviator.runtime.type.AviatorObject)1 Env (com.googlecode.aviator.utils.Env)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Test (org.junit.Test)1