Search in sources :

Example 1 with OperatorExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writeUnaryOperator.

Memory writeUnaryOperator(OperatorExprToken operator, boolean returnValue, boolean writeOpcode) {
    if (stackEmpty(true))
        unexpectedToken(operator);
    StackItem o = stackPop();
    ValueExprToken L = o.getToken();
    Memory mem = tryWritePush(o, false, false, true);
    StackItem.Type type = tryGetType(o);
    if (mem != null) {
        Memory result = CompilerUtils.calcUnary(getCompiler().getEnvironment(), operator.toTraceInfo(getCompiler().getContext()), mem, operator);
        if (operator instanceof ValueIfElseToken) {
            ValueIfElseToken valueIfElseToken = (ValueIfElseToken) operator;
            ExprStmtToken ret = valueIfElseToken.getValue();
            if (mem.toBoolean()) {
                if (ret == null)
                    result = mem;
                else
                    result = writeExpression(ret, true, true, false);
            } else {
                result = writeExpression(valueIfElseToken.getAlternative(), true, true, false);
            }
        } else if (operator instanceof ArrayGetExprToken && !(operator instanceof ArrayGetRefExprToken)) {
        // TODO: check!!!
        /*Memory array = mem;
                ArrayGetExprToken arrayGet = (ArrayGetExprToken)operator;
                for(ExprStmtToken expr : arrayGet.getParameters()){
                    Memory key = writeExpression(expr, true, true, false);
                    if (key == null)
                        break;
                    result = array = array.valueOfIndex(key).toImmutable();
                }*/
        }
        if (result != null) {
            stackPush(result);
            setStackPeekAsImmutable();
            return result;
        }
    }
    if (!writeOpcode)
        return null;
    writeLineNumber(operator);
    String name = operator.getCode();
    Class operatorResult = operator.getResultClass();
    LocalVariable variable = null;
    if (L instanceof VariableExprToken) {
        variable = method.getLocalVariable(((VariableExprToken) L).getName());
        if (operator instanceof ArrayPushExprToken || operator instanceof ArrayGetRefExprToken)
            variable.setValue(null);
    }
    if (operator instanceof IncExprToken || operator instanceof DecExprToken) {
        if (variable == null || variable.isReference()) {
            if (operator.getAssociation() == Association.LEFT && returnValue) {
                writePush(o);
                if (stackPeek().type.isConstant())
                    unexpectedToken(operator);
                writePushDup();
                writePopImmutable();
                code.add(new InsnNode(SWAP));
                writePushDup();
            } else {
                writePush(o);
                if (stackPeek().type.isConstant())
                    unexpectedToken(operator);
                writePushDup();
            }
            writeSysDynamicCall(Memory.class, name, operatorResult);
            writeSysDynamicCall(Memory.class, "assign", Memory.class, operatorResult);
            if (!returnValue || operator.getAssociation() == Association.LEFT) {
                writePopAll(1);
            }
        } else {
            writePush(o);
            if (stackPeek().type.isConstant())
                unexpectedToken(operator);
            if (operator.getAssociation() == Association.LEFT && returnValue) {
                writeVarLoad(variable);
            }
            writeSysDynamicCall(Memory.class, name, operatorResult);
            // TODO for constant values
            variable.setValue(null);
            if (operator.getAssociation() == Association.RIGHT)
                writeVarStore(variable, returnValue);
            else {
                writeVarStore(variable, false);
            }
        }
    } else if (operator instanceof AmpersandRefToken) {
        writePush(o, false, false);
        setStackPeekAsImmutable();
        Token token = o.getToken();
        if (token instanceof VariableExprToken) {
            LocalVariable local = method.getLocalVariable(((VariableExprToken) token).getName());
            local.setValue(null);
        }
    } else if (operator instanceof SilentToken) {
        writePushEnv();
        writeSysDynamicCall(Environment.class, "__pushSilent", void.class);
        writePush(o);
        writePushEnv();
        writeSysDynamicCall(Environment.class, "__popSilent", void.class);
    } else if (operator instanceof ValueIfElseToken) {
        writePush(o);
        ValueIfElseToken valueIfElseToken = (ValueIfElseToken) operator;
        LabelNode end = new LabelNode();
        LabelNode elseL = new LabelNode();
        if (valueIfElseToken.getValue() == null) {
            StackItem.Type dup = stackPeek().type;
            writePushDup();
            writePopBoolean();
            code.add(new JumpInsnNode(Opcodes.IFEQ, elseL));
            stackPop();
            writePopBoxing();
            stackPop();
            code.add(new JumpInsnNode(Opcodes.GOTO, end));
            code.add(elseL);
            // remove duplicate of condition value , IMPORTANT!!!
            makePop(dup);
            writeExpression(valueIfElseToken.getAlternative(), true, false);
            writePopBoxing();
            code.add(end);
        } else {
            writePopBoolean();
            code.add(new JumpInsnNode(Opcodes.IFEQ, elseL));
            stackPop();
            writeExpression(valueIfElseToken.getValue(), true, false);
            writePopBoxing();
            stackPop();
            // goto end
            code.add(new JumpInsnNode(Opcodes.GOTO, end));
            // else
            code.add(elseL);
            writeExpression(valueIfElseToken.getAlternative(), true, false);
            writePopBoxing();
            code.add(end);
        }
        setStackPeekAsImmutable(false);
    } else if (operator instanceof ArrayGetExprToken) {
        stackPush(o);
        writeArrayGet((ArrayGetExprToken) operator, returnValue);
    } else if (operator instanceof CallOperatorToken) {
        stackPush(o);
        CallOperatorToken call = (CallOperatorToken) operator;
        writePushParameters(call.getParameters());
        writePushEnv();
        writePushTraceInfo(operator);
        writeSysStaticCall(InvokeHelper.class, "callAny", Memory.class, Memory.class, Memory[].class, Environment.class, TraceInfo.class);
        if (!returnValue)
            writePopAll(1);
    } else {
        writePush(o);
        writePopBoxing();
        if (operator.isEnvironmentNeeded() && operator.isTraceNeeded()) {
            writePushEnv();
            writePushTraceInfo(operator);
            writeSysDynamicCall(Memory.class, name, operatorResult, Environment.class, TraceInfo.class);
        } else if (operator.isEnvironmentNeeded()) {
            writePushEnv();
            writeSysDynamicCall(Memory.class, name, operatorResult, Environment.class);
        } else if (operator.isTraceNeeded()) {
            writePushTraceInfo(operator);
            writeSysDynamicCall(Memory.class, name, operatorResult, TraceInfo.class);
        } else
            writeSysDynamicCall(Memory.class, name, operatorResult);
        if (!returnValue) {
            writePopAll(1);
        }
    }
    return null;
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) Token(org.develnext.jphp.core.tokenizer.token.Token) ClassExprToken(org.develnext.jphp.core.tokenizer.token.expr.ClassExprToken) OpenEchoTagToken(org.develnext.jphp.core.tokenizer.token.OpenEchoTagToken) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken) ObjectInvokeHelper(php.runtime.invoke.ObjectInvokeHelper) InvokeHelper(php.runtime.invoke.InvokeHelper) TraceInfo(php.runtime.env.TraceInfo) StackItem(org.develnext.jphp.core.compiler.common.misc.StackItem) Type(org.objectweb.asm.Type) Environment(php.runtime.env.Environment) CompileClass(php.runtime.ext.support.compile.CompileClass)

Example 2 with OperatorExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writeExpression.

@SuppressWarnings("unchecked")
public Memory writeExpression(ExprStmtToken expression, boolean returnValue, boolean returnMemory, boolean writeOpcode) {
    int initStackSize = method.getStackCount();
    exprStackInit.push(initStackSize);
    if (!expression.isStmtList()) {
        if (expression.getAsmExpr() == null) {
            throw new CriticalException("Invalid expression token without asm expr, on line " + expression.getMeta().getStartLine() + ", expr = " + expression.getWord());
        }
        // new ASMExpression(compiler.getEnvironment(), compiler.getContext(), expression).getResult();
        expression = expression.getAsmExpr();
    }
    List<Token> tokens = expression.getTokens();
    int operatorCount = 0;
    for (Token token : tokens) {
        if (token instanceof OperatorExprToken)
            operatorCount++;
    }
    boolean invalid = false;
    for (Token token : tokens) {
        if (token == null)
            continue;
        writeTickTrigger(token);
        if (writeOpcode) {
            if (token instanceof StmtToken) {
                if (!(token instanceof ReturnStmtToken))
                    method.entity.setImmutable(false);
            }
            BaseStatementCompiler cmp = getCompiler(token.getClass());
            if (cmp != null && !(cmp instanceof BaseExprCompiler)) {
                cmp.write(token);
                continue;
            }
        }
        if (token instanceof ValueExprToken) {
            // mixed, calls, numbers, strings, vars, etc.
            if (token instanceof CallExprToken && ((CallExprToken) token).getName() instanceof OperatorExprToken) {
                if (writeOpcode) {
                    writePush((ValueExprToken) token, true, true);
                    method.entity.setImmutable(false);
                } else
                    break;
            } else
                stackPush((ValueExprToken) token);
        } else if (token instanceof OperatorExprToken) {
            // + - * / % && || or ! and == > < etc.
            operatorCount--;
            if (operatorCount >= 0) {
                Memory result;
                if (operatorCount == 0) {
                    result = writeOperator((OperatorExprToken) token, returnValue, writeOpcode);
                } else
                    result = writeOperator((OperatorExprToken) token, true, writeOpcode);
                if (!writeOpcode && result == null) {
                    invalid = true;
                    break;
                }
                if (result == null)
                    method.entity.setImmutable(false);
            }
        } else
            break;
    }
    Memory result = null;
    if (!invalid && returnMemory && returnValue && !stackEmpty(false) && stackPeek().isConstant()) {
        result = stackPop().memory;
        invalid = true;
    }
    if (!invalid) {
        if (returnValue && !stackEmpty(false) && stackPeek().isKnown()) {
            if (returnMemory)
                result = tryWritePush(stackPop(), writeOpcode, returnValue, true);
            else
                writePush(stackPop());
        } else if (method.getStackCount() > 0) {
            if (stackPeekToken() instanceof CallableExprToken) {
                if (returnMemory)
                    result = tryWritePush(stackPopToken(), returnValue, writeOpcode, true);
                else
                    writePush(stackPopToken(), returnValue, true);
            } else if (stackPeek().isConstant()) {
                stackPop();
            }
        }
    }
    if (!returnValue && writeOpcode) {
        writePopAll(method.getStackCount() - initStackSize);
    } else if (!writeOpcode) {
        int count = method.getStackCount() - initStackSize;
        for (int i = 0; i < count; i++) {
            stackPop();
        }
    }
    exprStackInit.pop();
    return result;
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) Token(org.develnext.jphp.core.tokenizer.token.Token) ClassExprToken(org.develnext.jphp.core.tokenizer.token.expr.ClassExprToken) OpenEchoTagToken(org.develnext.jphp.core.tokenizer.token.OpenEchoTagToken) CriticalException(php.runtime.exceptions.CriticalException) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)

Example 3 with OperatorExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken in project jphp by jphp-compiler.

the class ASMExpression method processToken.

protected void processToken(Token token, Stack<Token> stack, List<Token> result) {
    if (token instanceof CallExprToken) {
        CallExprToken call = (CallExprToken) token;
        if (call.getName() instanceof OperatorExprToken) {
            processOperator(stack, result, (OperatorExprToken) call.getName());
        }
        result.add(token);
    } else if (token instanceof ValueExprToken) {
        result.add(token);
    } else if (token instanceof BraceExprToken) {
        BraceExprToken brace = (BraceExprToken) token;
        if (brace.isSimpleOpened()) {
            stack.push(brace);
        } else if (brace.isSimpleClosed()) {
            if (stack.empty())
                unexpectedToken(brace);
            boolean done = false;
            do {
                Token el = stack.pop();
                if (el instanceof BraceExprToken && ((BraceExprToken) el).isSimpleOpened()) {
                    done = true;
                    break;
                }
                result.add(el);
            } while (!stack.isEmpty());
            if (!done)
                unexpectedToken(brace);
        } else
            unexpectedToken(brace);
    } else if (token instanceof OperatorExprToken) {
        OperatorExprToken operator = (OperatorExprToken) token;
        /*boolean done = !stack.empty();
            if (done){
                if (operator.isRightSide())
                    done = getPriority(stack.peek()) > prior;
                else
                    done = getPriority(stack.peek()) > prior;
            }

            if (done){
                if (prior == 1){
                    processOperator(stack, result, prior);
                    result.add(token);
                    return;
                }

                stack.push(token);
                return;
            }*/
        processOperator(stack, result, operator);
        stack.push(token);
    }
}
Also used : CallExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.CallExprToken) BraceExprToken(org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken) Token(org.develnext.jphp.core.tokenizer.token.Token) ExprStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken) ExprToken(org.develnext.jphp.core.tokenizer.token.expr.ExprToken) BraceExprToken(org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) CallExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.CallExprToken) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)

Example 4 with OperatorExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken in project jphp by jphp-compiler.

the class DynamicAccessCompiler method write.

@Override
public void write(DynamicAccessExprToken dynamic, boolean returnValue) {
    expr.writeDynamicAccessPrepare(dynamic, false);
    if (dynamic.getFieldExpr() == null && dynamic.getField() instanceof NameToken && !method.clazz.statement.isTrait()) {
        expr.writeGetStatic("$CALL_PROP_CACHE", PropertyCallCache.class);
        expr.writePushConstInt(method.clazz.getAndIncCallPropCount());
    } else {
        expr.writePushConstNull();
        expr.writePushConstInt(0);
    }
    if (dynamic instanceof DynamicAccessAssignExprToken) {
        OperatorExprToken operator = (OperatorExprToken) ((DynamicAccessAssignExprToken) dynamic).getAssignOperator();
        String code = operator.getCode();
        if (operator instanceof IncExprToken || operator instanceof DecExprToken) {
            if (operator.getAssociation() == Association.RIGHT)
                code = code + "AndGet";
            else
                code = "GetAnd" + code.substring(0, 1).toUpperCase() + code.substring(1);
            expr.writeSysStaticCall(ObjectInvokeHelper.class, code + "Property", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
        } else {
            expr.writeSysStaticCall(ObjectInvokeHelper.class, code + "Property", Memory.class, Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
        }
    } else if (dynamic instanceof DynamicAccessUnsetExprToken) {
        expr.writeSysStaticCall(ObjectInvokeHelper.class, "unsetProperty", void.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
        if (returnValue)
            expr.writePushNull();
    } else if (dynamic instanceof DynamicAccessEmptyExprToken) {
        expr.writeSysStaticCall(ObjectInvokeHelper.class, "emptyProperty", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
    } else if (dynamic instanceof DynamicAccessIssetExprToken) {
        expr.writeSysStaticCall(ObjectInvokeHelper.class, "issetProperty", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
    } else {
        expr.writeSysStaticCall(ObjectInvokeHelper.class, dynamic instanceof DynamicAccessGetRefExprToken ? "getRefProperty" : "getProperty", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
    }
}
Also used : Memory(php.runtime.Memory) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) TraceInfo(php.runtime.env.TraceInfo) NameToken(org.develnext.jphp.core.tokenizer.token.expr.value.NameToken) ObjectInvokeHelper(php.runtime.invoke.ObjectInvokeHelper) PropertyCallCache(php.runtime.invoke.cache.PropertyCallCache) Environment(php.runtime.env.Environment)

Example 5 with OperatorExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken in project jphp by jphp-compiler.

the class ASMExpression method processOperator.

protected void processOperator(Stack<Token> stack, List<Token> result, OperatorExprToken current) {
    List<Token> list = new ArrayList<Token>();
    boolean isRightOperator = current != null && current.isRightSide();
    int prior = current == null ? -1 : current.getPriority();
    while (!stack.empty()) {
        Token el = stack.peek();
        int elPrior = getPriority(el);
        if (el instanceof BraceExprToken)
            break;
        if (current != null && current.getAssociation() == Association.RIGHT && !current.isBinary() && prev instanceof OperatorExprToken)
            break;
        boolean flush = current == null || elPrior == 1 || (isRightOperator ? elPrior > prior : elPrior <= prior);
        if (flush) {
            stack.pop();
            list.add(el);
        } else {
            break;
        }
    }
    result.addAll(list);
}
Also used : BraceExprToken(org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken) ArrayList(java.util.ArrayList) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken) Token(org.develnext.jphp.core.tokenizer.token.Token) ExprStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken) ExprToken(org.develnext.jphp.core.tokenizer.token.expr.ExprToken) BraceExprToken(org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) CallExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.CallExprToken)

Aggregations

OperatorExprToken (org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken)5 Token (org.develnext.jphp.core.tokenizer.token.Token)4 ValueExprToken (org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)4 Memory (php.runtime.Memory)3 OpenEchoTagToken (org.develnext.jphp.core.tokenizer.token.OpenEchoTagToken)2 BraceExprToken (org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken)2 ClassExprToken (org.develnext.jphp.core.tokenizer.token.expr.ClassExprToken)2 ExprToken (org.develnext.jphp.core.tokenizer.token.expr.ExprToken)2 CallExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.CallExprToken)2 ExprStmtToken (org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken)2 Environment (php.runtime.env.Environment)2 TraceInfo (php.runtime.env.TraceInfo)2 ObjectInvokeHelper (php.runtime.invoke.ObjectInvokeHelper)2 UndefinedMemory (php.runtime.memory.helper.UndefinedMemory)2 ArrayList (java.util.ArrayList)1 StackItem (org.develnext.jphp.core.compiler.common.misc.StackItem)1 LocalVariable (org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)1 NameToken (org.develnext.jphp.core.tokenizer.token.expr.value.NameToken)1 Type (org.objectweb.asm.Type)1 CriticalException (php.runtime.exceptions.CriticalException)1