Search in sources :

Example 1 with Statement

use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.

the class ParsedExpression method readPrimaryExpression.

private static ParsedExpression readPrimaryExpression(ZenPosition position, ZenTokener parser, IEnvironmentGlobal environment) {
    switch(parser.peek().getType()) {
        case T_INTVALUE:
            long l = Long.decode(parser.next().getValue());
            return new ParsedExpressionValue(position, new ExpressionInt(position, l, Long.bitCount(l) > 32 ? ZenType.LONG : ZenTypeInt.INSTANCE));
        case T_FLOATVALUE:
            String value = parser.next().getValue();
            ZenType zenType = ZenTypeDouble.INSTANCE;
            if (value.endsWith("f") || value.endsWith("F")) {
                zenType = ZenTypeFloat.INSTANCE;
                value = value.substring(0, value.length() - 1);
            }
            return new ParsedExpressionValue(position, new ExpressionFloat(position, Double.parseDouble(value), zenType));
        case T_STRINGVALUE:
            return new ParsedExpressionValue(position, new ExpressionString(position, unescapeString(parser.next().getValue())));
        /*
             * case T_DOLLAR: { Expression result = new
             * ExpressionDollar(position); if (parser.isNext(T_STRINGVALUE))
             * { return new ExpressionIndexString(position, result,
             * unescapeString(parser.next().getValue())); } return result; }
             */
        case T_ID:
            return new ParsedExpressionVariable(position, parser.next().getValue());
        case T_FUNCTION:
            // function (argname, argname, ...) { ...contents... }
            parser.next();
            parser.required(T_BROPEN, "( expected");
            List<ParsedFunctionArgument> arguments = new ArrayList<>();
            if (parser.optional(T_BRCLOSE) == null) {
                do {
                    String name = parser.required(T_ID, "identifier expected").getValue();
                    ZenType type = ZenTypeAny.INSTANCE;
                    if (parser.optional(T_AS) != null) {
                        type = ZenType.read(parser, environment);
                    }
                    arguments.add(new ParsedFunctionArgument(name, type));
                } while (parser.optional(T_COMMA) != null);
                parser.required(T_BRCLOSE, ") expected");
            }
            ZenType returnType = ZenTypeAny.INSTANCE;
            if (parser.optional(T_AS) != null) {
                returnType = ZenType.read(parser, environment);
            }
            parser.required(T_AOPEN, "{ expected");
            List<Statement> statements = new ArrayList<>();
            if (parser.optional(T_ACLOSE) == null) {
                while (parser.optional(T_ACLOSE) == null) {
                    statements.add(Statement.read(parser, environment, returnType));
                }
            }
            return new ParsedExpressionFunction(position, returnType, arguments, statements);
        case T_LT:
            {
                Token start = parser.next();
                List<Token> tokens = new ArrayList<>();
                Token next = parser.next();
                while (next.getType() != ZenTokener.T_GT) {
                    tokens.add(next);
                    next = parser.next();
                }
                IZenSymbol resolved = parser.getEnvironment().getBracketed(environment, tokens);
                if (resolved == null) {
                    StringBuilder builder = new StringBuilder();
                    builder.append('<');
                    Token last = null;
                    for (Token token : tokens) {
                        if (last != null)
                            builder.append(' ');
                        builder.append(token.getValue());
                        last = token;
                    }
                    builder.append('>');
                    if (!parser.ignoreBracketErrors) {
                        parser.getEnvironment().getErrorLogger().error(start.getPosition(), "Could not resolve " + builder.toString());
                    } else {
                        parser.getEnvironment().getErrorLogger().info(start.getPosition(), "Could not resolve " + builder.toString());
                    }
                    return new ParsedExpressionInvalid(start.getPosition());
                } else {
                    return new ParsedExpressionValue(start.getPosition(), parser.getEnvironment().getBracketed(environment, tokens).instance(start.getPosition()));
                }
            }
        case T_SQBROPEN:
            {
                parser.next();
                List<ParsedExpression> contents = new ArrayList<>();
                if (parser.optional(T_SQBRCLOSE) == null) {
                    while (parser.optional(T_SQBRCLOSE) == null) {
                        contents.add(readAssignExpression(parser, environment));
                        if (parser.optional(T_COMMA) == null) {
                            parser.required(T_SQBRCLOSE, "] or , expected");
                            break;
                        }
                    }
                }
                return new ParsedExpressionArray(position, contents);
            }
        case T_AOPEN:
            {
                parser.next();
                List<ParsedExpression> keys = new ArrayList<>();
                List<ParsedExpression> values = new ArrayList<>();
                if (parser.optional(T_ACLOSE) == null) {
                    while (parser.optional(T_ACLOSE) == null) {
                        keys.add(readAssignExpression(parser, environment));
                        parser.required(T_COLON, ": expected");
                        values.add(readAssignExpression(parser, environment));
                        if (parser.optional(T_COMMA) == null) {
                            parser.required(T_ACLOSE, "} or , expected");
                            break;
                        }
                    }
                }
                return new ParsedExpressionMap(position, keys, values);
            }
        case T_TRUE:
            parser.next();
            return new ParsedExpressionBool(position, true);
        case T_FALSE:
            parser.next();
            return new ParsedExpressionBool(position, false);
        case T_NULL:
            parser.next();
            return new ParsedExpressionNull(position);
        case T_BROPEN:
            parser.next();
            ParsedExpression result = readAssignExpression(parser, environment);
            parser.required(T_BRCLOSE, ") expected");
            return result;
        default:
            Token last = parser.next();
            throw new ParseException(last, "Invalid expression, last token: " + last.getValue());
    }
}
Also used : StringUtil.unescapeString(stanhebben.zenscript.util.StringUtil.unescapeString) ParsedFunctionArgument(stanhebben.zenscript.definitions.ParsedFunctionArgument) IZenSymbol(stanhebben.zenscript.symbols.IZenSymbol) Statement(stanhebben.zenscript.statements.Statement)

Example 2 with Statement

use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.

the class ParsedFunction method parse.

public static ParsedFunction parse(ZenTokener parser, IEnvironmentGlobal environment) {
    parser.next();
    Token tName = parser.required(ZenTokener.T_ID, "identifier expected");
    // function (argname [as type], argname [as type], ...) [as type] {
    // ...contents... }
    parser.required(T_BROPEN, "( expected");
    List<ParsedFunctionArgument> arguments = new ArrayList<>();
    if (parser.optional(T_BRCLOSE) == null) {
        Token argName = parser.required(T_ID, "identifier expected");
        ZenType type = ZenTypeAny.INSTANCE;
        if (parser.optional(T_AS) != null) {
            type = ZenType.read(parser, environment);
        }
        arguments.add(new ParsedFunctionArgument(argName.getValue(), type));
        while (parser.optional(T_COMMA) != null) {
            Token argName2 = parser.required(T_ID, "identifier expected");
            ZenType type2 = ZenTypeAny.INSTANCE;
            if (parser.optional(T_AS) != null) {
                type2 = ZenType.read(parser, environment);
            }
            arguments.add(new ParsedFunctionArgument(argName2.getValue(), type2));
        }
        parser.required(T_BRCLOSE, ") expected");
    }
    ZenType type = ZenTypeAny.INSTANCE;
    if (parser.optional(T_AS) != null) {
        type = ZenType.read(parser, environment);
    }
    parser.required(T_AOPEN, "{ expected");
    Statement[] statements;
    if (parser.optional(T_ACLOSE) != null) {
        statements = new Statement[0];
    } else {
        ArrayList<Statement> statementsAL = new ArrayList<>();
        while (parser.optional(T_ACLOSE) == null) {
            statementsAL.add(Statement.read(parser, environment, type));
        }
        statements = statementsAL.toArray(new Statement[statementsAL.size()]);
    }
    return new ParsedFunction(tName.getPosition(), tName.getValue(), arguments, type, statements);
}
Also used : Statement(stanhebben.zenscript.statements.Statement) Token(stanhebben.zenscript.parser.Token)

Example 3 with Statement

use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.

the class ExpressionFunction method compile.

@Override
public void compile(boolean result, IEnvironmentMethod environment) {
    if (!result)
        return;
    ClassWriter cw = new ZenClassWriter(ClassWriter.COMPUTE_FRAMES);
    cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", new String[0]);
    MethodOutput constructor = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    constructor.start();
    constructor.loadObject(0);
    constructor.invokeSpecial("java/lang/Object", "<init>", "()V");
    constructor.ret();
    constructor.end();
    MethodOutput output = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "accept", makeDescriptor(), null, null);
    IEnvironmentClass environmentClass = new EnvironmentClass(cw, environment);
    IEnvironmentMethod environmentMethod = new EnvironmentMethod(output, environmentClass);
    for (int i = 0; i < arguments.size(); i++) {
        environmentMethod.putValue(arguments.get(i).getName(), new SymbolArgument(i + 1, arguments.get(i).getType()), getPosition());
    }
    output.start();
    for (Statement statement : statements) {
        statement.compile(environmentMethod);
    }
    output.ret();
    output.end();
    environment.putClass(className, cw.toByteArray());
    // make class instance
    environment.getOutput().newObject(className);
    environment.getOutput().dup();
    environment.getOutput().construct(className);
}
Also used : SymbolArgument(stanhebben.zenscript.symbols.SymbolArgument) Statement(stanhebben.zenscript.statements.Statement)

Example 4 with Statement

use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.

the class ExpressionJavaLambdaSimpleGeneric method compile.

@Override
public void compile(boolean result, IEnvironmentMethod environment) {
    if (!result)
        return;
    Method method = interfaceClass.getMethods()[0];
    // generate class
    String clsName = environment.makeClassName();
    ClassWriter cw = new ZenClassWriter(ClassWriter.COMPUTE_FRAMES);
    cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, clsName, createMethodSignature(), "java/lang/Object", new String[] { internal(interfaceClass) });
    MethodOutput constructor = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    constructor.start();
    constructor.loadObject(0);
    constructor.invokeSpecial("java/lang/Object", "<init>", "()V");
    constructor.ret();
    constructor.end();
    MethodOutput output = new MethodOutput(cw, Opcodes.ACC_PUBLIC, method.getName(), descriptor, null, null);
    IEnvironmentClass environmentClass = new EnvironmentClass(cw, environment);
    IEnvironmentMethod environmentMethod = new EnvironmentMethod(output, environmentClass);
    for (int i = 0; i < arguments.size(); i++) {
        ZenType typeToPut = arguments.get(i).getType();
        if (typeToPut.equals(ZenType.ANY))
            typeToPut = environment.getType(method.getGenericParameterTypes()[i]);
        if (typeToPut == null)
            typeToPut = environment.getType(method.getParameterTypes()[i]);
        environmentMethod.putValue(arguments.get(i).getName(), new SymbolArgument(i + 1, typeToPut), getPosition());
    }
    output.start();
    for (Statement statement : statements) {
        statement.compile(environmentMethod);
    }
    output.ret();
    output.end();
    if (!Objects.equals(genericClass, Object.class)) {
        MethodOutput bridge = new MethodOutput(cw, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE, method.getName(), ZenTypeUtil.descriptor(method), null, null);
        bridge.loadObject(0);
        bridge.loadObject(1);
        bridge.checkCast(internal(genericClass));
        if (arguments.size() > 1) {
            for (int i = 1; i < arguments.size(); ) {
                bridge.load(org.objectweb.asm.Type.getType(method.getParameterTypes()[i]), ++i);
            }
        }
        bridge.invokeVirtual(clsName, method.getName(), descriptor);
        bridge.returnType(org.objectweb.asm.Type.getReturnType(method));
        bridge.end();
    }
    environment.putClass(clsName, cw.toByteArray());
    // make class instance
    environment.getOutput().newObject(clsName);
    environment.getOutput().dup();
    environment.getOutput().construct(clsName);
}
Also used : SymbolArgument(stanhebben.zenscript.symbols.SymbolArgument) Statement(stanhebben.zenscript.statements.Statement) MethodOutput(stanhebben.zenscript.util.MethodOutput) Method(java.lang.reflect.Method) ClassWriter(org.objectweb.asm.ClassWriter) ZenType(stanhebben.zenscript.type.ZenType)

Example 5 with Statement

use of stanhebben.zenscript.statements.Statement in project ZenScript by CraftTweaker.

the class ExpressionJavaLambda method compile.

@Override
public void compile(boolean result, IEnvironmentMethod environment) {
    if (!result)
        return;
    Method method = interfaceClass.getMethods()[0];
    // generate class
    String clsName = environment.makeClassName();
    ClassWriter cw = new ZenClassWriter(ClassWriter.COMPUTE_FRAMES);
    cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, clsName, null, "java/lang/Object", new String[] { internal(interfaceClass) });
    MethodOutput constructor = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    constructor.start();
    constructor.loadObject(0);
    constructor.invokeSpecial("java/lang/Object", "<init>", "()V");
    constructor.ret();
    constructor.end();
    MethodOutput output = new MethodOutput(cw, Opcodes.ACC_PUBLIC, method.getName(), descriptor(method), null, null);
    IEnvironmentClass environmentClass = new EnvironmentClass(cw, environment);
    IEnvironmentMethod environmentMethod = new EnvironmentMethod(output, environmentClass);
    for (int i = 0; i < arguments.size(); i++) {
        environmentMethod.putValue(arguments.get(i).getName(), new SymbolArgument(i + 1, environment.getType(method.getGenericParameterTypes()[i])), getPosition());
    }
    output.start();
    for (Statement statement : statements) {
        statement.compile(environmentMethod);
    }
    output.ret();
    output.end();
    environment.putClass(clsName, cw.toByteArray());
    // make class instance
    environment.getOutput().newObject(clsName);
    environment.getOutput().dup();
    environment.getOutput().construct(clsName);
}
Also used : SymbolArgument(stanhebben.zenscript.symbols.SymbolArgument) Statement(stanhebben.zenscript.statements.Statement) Method(java.lang.reflect.Method)

Aggregations

Statement (stanhebben.zenscript.statements.Statement)5 SymbolArgument (stanhebben.zenscript.symbols.SymbolArgument)3 Method (java.lang.reflect.Method)2 ClassWriter (org.objectweb.asm.ClassWriter)1 ParsedFunctionArgument (stanhebben.zenscript.definitions.ParsedFunctionArgument)1 Token (stanhebben.zenscript.parser.Token)1 IZenSymbol (stanhebben.zenscript.symbols.IZenSymbol)1 ZenType (stanhebben.zenscript.type.ZenType)1 MethodOutput (stanhebben.zenscript.util.MethodOutput)1 StringUtil.unescapeString (stanhebben.zenscript.util.StringUtil.unescapeString)1