package org.develnext.jphp.core.compiler.common.util; import org.objectweb.asm.Opcodes; import org.develnext.jphp.core.compiler.common.misc.StackItem; import php.runtime.env.Environment; import php.runtime.env.TraceInfo; import php.runtime.memory.DoubleMemory; import php.runtime.memory.LongMemory; import php.runtime.memory.StringMemory; import php.runtime.Memory; import org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken; import org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken; import org.develnext.jphp.core.tokenizer.token.expr.operator.*; import org.develnext.jphp.core.tokenizer.token.expr.value.*; final public class CompilerUtils { private CompilerUtils(){ } protected static Memory toCallMemory(CallExprToken call, Memory... arguments){ return null; // TODO } public static Memory toMemory(ValueExprToken value, Memory... arguments){ if (value instanceof IntegerExprToken){ return LongMemory.valueOf(((IntegerExprToken) value).getValue()); } else if (value instanceof DoubleExprToken){ return DoubleMemory.valueOf(((DoubleExprToken) value).getValue()); } else if (value instanceof StringExprToken && !((StringExprToken) value).isBinary()){ return StringMemory.valueOf(((StringExprToken) value).getValue()); } else if (value instanceof BooleanExprToken){ return ((BooleanExprToken) value).getValue() ? Memory.TRUE : Memory.FALSE; } else if (value instanceof NullExprToken){ return Memory.NULL; } else if (value instanceof CallExprToken){ return toCallMemory((CallExprToken)value, arguments); } return null; } public static Memory calcUnary(Environment env, TraceInfo trace, Memory o1, OperatorExprToken operator){ if (operator.isBinary()) throw new IllegalArgumentException("Operator is not unary"); return operator.calc(env, trace, o1, null); } public static Memory calcBinary(Environment env, TraceInfo trace, Memory o1, Memory o2, OperatorExprToken operator, boolean right){ if (!operator.isBinary()) throw new IllegalArgumentException("Operator is not binary"); if (right) { Memory o = o1; o1 = o2; o2 = o; } return operator.calc(env, trace, o1, o2); } public static int getOperatorOpcode(OperatorExprToken operator, StackItem.Type type){ if (operator instanceof PlusExprToken){ switch (type){ case DOUBLE: return Opcodes.DADD; case FLOAT: return Opcodes.FADD; case LONG: return Opcodes.LADD; case BYTE: case SHORT: case INT: return Opcodes.IADD; } } if (operator instanceof MinusExprToken){ switch (type){ case DOUBLE: return Opcodes.DSUB; case FLOAT: return Opcodes.FSUB; case LONG: return Opcodes.LSUB; case BYTE: case SHORT: case INT: return Opcodes.ISUB; } } if (operator instanceof MulExprToken){ switch (type){ case DOUBLE: return Opcodes.DMUL; case FLOAT: return Opcodes.FMUL; case LONG: return Opcodes.LMUL; case BYTE: case SHORT: case INT: return Opcodes.IMUL; } } throw new IllegalArgumentException("Unknown operator " + operator.getWord() + " for type " + type.name()); } public static boolean isOperatorAlwaysReturn(OperatorExprToken operator) { return operator instanceof KeyValueExprToken; } }