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;
}
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;
}
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);
}
}
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);
}
}
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);
}
Aggregations