AS2: p-code deobfuscation

This commit is contained in:
Jindra Pet��k
2013-02-10 14:00:49 +01:00
parent 83758ae746
commit 92b02e3b56
52 changed files with 614 additions and 26 deletions
@@ -0,0 +1,63 @@
package com.jpexs.asdec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
*
* @author JPEXS
*/
public class ReReadableInputStream extends InputStream {
InputStream is;
ByteArrayOutputStream baos=new ByteArrayOutputStream();
byte []converted;
int pos=0;
int count=0;
public byte[] getAllRead(){
return baos.toByteArray();
}
public int getPos() {
return pos;
}
public ReReadableInputStream(InputStream is) {
this.is=is;
}
public void setPos(int pos) throws IOException{
if(pos>count){
skip(pos-count);
}
this.pos=pos;
}
@Override
public int read() throws IOException {
if(pos<count){
if(converted==null){
converted=baos.toByteArray();
}
int ret=converted[pos]&0xff;
pos++;
return ret;
}
int i= is.read();
baos.write(i);
count++;
pos++;
converted=null;
return i;
}
@Override
public int available() throws IOException {
return (pos<count?count-pos:0)+is.available();
}
}
+139 -3
View File
@@ -16,13 +16,18 @@
*/
package com.jpexs.asdec;
import com.jpexs.asdec.abc.avm2.instructions.other.NopIns;
import com.jpexs.asdec.action.Action;
import com.jpexs.asdec.action.special.ActionNop;
import com.jpexs.asdec.action.swf3.*;
import com.jpexs.asdec.action.swf4.*;
import com.jpexs.asdec.action.swf5.*;
import com.jpexs.asdec.action.swf6.*;
import com.jpexs.asdec.action.swf7.*;
import com.jpexs.asdec.action.treemodel.ConstantPool;
import com.jpexs.asdec.action.treemodel.TreeItem;
import com.jpexs.asdec.helpers.Helper;
import com.jpexs.asdec.helpers.Highlighting;
import com.jpexs.asdec.tags.*;
import com.jpexs.asdec.types.*;
import com.jpexs.asdec.types.filters.*;
@@ -31,11 +36,13 @@ import com.jpexs.asdec.types.shaperecords.EndShapeRecord;
import com.jpexs.asdec.types.shaperecords.SHAPERECORD;
import com.jpexs.asdec.types.shaperecords.StraightEdgeRecord;
import com.jpexs.asdec.types.shaperecords.StyleChangeRecord;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
import java.util.logging.Logger;
@@ -54,6 +61,31 @@ public class SWFInputStream extends InputStream {
private static final Logger log = Logger.getLogger(SWFInputStream.class.getName());
private List<PercentListener> listeners = new ArrayList<PercentListener>();
private long percentMax;
private List<byte[]> buffered = new ArrayList<byte[]>();
private ByteArrayOutputStream buffer;
public int getBufferLength() {
return buffer.size();
}
public void startBuffer() {
stopBuffer();
buffer = new ByteArrayOutputStream();
}
public byte[] getBuffer() {
return buffer.toByteArray();
}
public byte[] stopBuffer() {
if (buffer != null) {
byte[] ret = buffer.toByteArray();
buffered.add(ret);
buffer = null;
return ret;
}
return null;
}
public void addPercentListener(PercentListener listener) {
listeners.add(listener);
@@ -448,14 +480,118 @@ public class SWFInputStream extends InputStream {
* @throws IOException
*/
public List<Action> readActionList() throws IOException {
List<Action> retdups = new ArrayList<Action>();
ConstantPool cpool = null;
Stack<TreeItem> stack = new Stack<TreeItem>();
ReReadableInputStream rri = new ReReadableInputStream(this);
SWFInputStream sis = new SWFInputStream(rri, version);
readActionListAtPos(stack, cpool, sis, rri, 0, retdups);
List<Action> ret = new ArrayList<Action>();
Action a;
while ((a = readAction()) != null) {
ret.add(a);
Action last = null;
for (Action a : retdups) {
if (a != last) {
ret.add(a);
}
last = a;
}
return ret;
}
private void readActionListAtPos(Stack<TreeItem> stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List<Action> ret) throws IOException {
rri.setPos(ip);
Action a;
List<TreeItem> output = new ArrayList<TreeItem>();
long filePos = rri.getPos();
while ((a = sis.readAction()) != null) {
if (a instanceof ActionPush) {
if (cpool != null) {
((ActionPush) a).constantPool = cpool.constants;
}
}
if (a instanceof ActionDefineFunction) {
if (cpool != null) {
((ActionDefineFunction) a).setConstantPool(cpool.constants);
}
}
if (a instanceof ActionDefineFunction2) {
if (cpool != null) {
((ActionDefineFunction2) a).setConstantPool(cpool.constants);
}
}
long newFilePos = rri.getPos();
long actionLen = newFilePos - filePos;
ensureCapacity(ret, ip);
int newip = -1;
if (!(ret.get(ip) instanceof ActionNop)) {
break;
}
if (a instanceof ActionConstantPool) {
if (cpool == null) {
cpool = new ConstantPool();
}
cpool.constants = ((ActionConstantPool) a).constantPool;
}
Action beforeInsert = null;
ActionIf aif = null;
boolean goaif = false;
if (a instanceof ActionIf) {
aif = (ActionIf) a;
TreeItem top = stack.pop();
if (top.isCompileTime()) {
if (top.toBoolean()) {
newip = rri.getPos() + aif.offset;
rri.setPos(newip);
a = new ActionJump(aif.offset);
} else {
a = new ActionNop();
}
beforeInsert = new ActionPop();
} else {
goaif = true;
}
} else if (a instanceof ActionJump) {
newip = rri.getPos() + ((ActionJump) a).offset;
rri.setPos(newip);
} else {
a.translate(stack, cpool, output, new HashMap<Integer, String>());
}
for (int i = 0; i < actionLen; i++) {
ensureCapacity(ret, ip + i);
if (a instanceof ActionNop) {
a = new ActionNop();
if (i == 0) {
a.beforeInsert = beforeInsert;
}
} else {
a.beforeInsert = beforeInsert;
}
ret.set(ip + i, a);
}
if (newip > -1) {
ip = newip;
} else {
ip = ip + (int) actionLen;
}
filePos = rri.getPos();
if (goaif) {
int oldPos = rri.getPos();
readActionListAtPos(stack, cpool, sis, rri, rri.getPos() + aif.offset, ret);
rri.setPos(oldPos);
}
}
}
private void ensureCapacity(List<Action> ret, int index) {
while (ret.size() <= index) {
ret.add(new ActionNop());
}
}
private static void dumpTag(PrintStream out, int version, Tag tag, int level) {
StringBuilder sb = new StringBuilder();
sb.append(Helper.formatHex((int) tag.getPos(), 8));
@@ -21,6 +21,7 @@ import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.asdec.helpers.Highlighting;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
public abstract class TreeItem {
+9 -19
View File
@@ -21,6 +21,7 @@ import com.jpexs.asdec.SWFOutputStream;
import com.jpexs.asdec.action.parser.FlasmLexer;
import com.jpexs.asdec.action.parser.ParseException;
import com.jpexs.asdec.action.parser.ParsedSymbol;
import com.jpexs.asdec.action.special.ActionNop;
import com.jpexs.asdec.action.swf4.*;
import com.jpexs.asdec.action.swf5.*;
import com.jpexs.asdec.action.swf6.ActionEnumerate2;
@@ -46,6 +47,7 @@ import java.util.logging.Logger;
*/
public class Action {
public Action beforeInsert;
/**
* Action type identifier
*/
@@ -361,29 +363,17 @@ public class Action {
}
offset = 0;
if (Main.LATEST_CONSTANTPOOL_HACK) {
for (Action a : list) {
if (a instanceof ActionConstantPool) {
constantPool.clear();
constantPool.addAll(((ActionConstantPool) a).constantPool);
}
}
}
for (Action a : list) {
if (!Main.LATEST_CONSTANTPOOL_HACK) {
if (a instanceof ActionConstantPool) {
constantPool.clear();
constantPool.addAll(((ActionConstantPool) a).constantPool);
}
}
if (a instanceof ActionPush) {
((ActionPush) a).constantPool = constantPool;
}
for (Action a : list) {
offset = a.getAddress();
if (importantOffsets.contains(offset)) {
ret += "loc" + Helper.formatAddress(offset) + ":";
}
ret += Highlighting.hilighOffset("", offset) + a.getASMSource(importantOffsets, constantPool, version) + "\r\n";
if(a.beforeInsert!=null){
ret+=a.beforeInsert.getASMSource(importantOffsets, constantPool, version) + "\r\n";
}
if(!(a instanceof ActionNop)){
ret += Highlighting.hilighOffset("", offset) + a.getASMSource(importantOffsets, constantPool, version) + "\r\n";
}
offset += a.getBytes(version).length;
}
if (importantOffsets.contains(offset)) {
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2010-2013 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.asdec.action.special;
import com.jpexs.asdec.action.Action;
import com.jpexs.asdec.action.treemodel.ConstantPool;
import com.jpexs.asdec.action.treemodel.SimpleActionTreeItem;
import com.jpexs.asdec.action.treemodel.TreeItem;
import java.util.List;
import java.util.Stack;
public class ActionNop extends Action {
public ActionNop() {
super(-1, 0);
}
@Override
public String toString() {
return "Nop";
}
@Override
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
output.add(new SimpleActionTreeItem(this, "nop();"));
}
}
@@ -71,5 +71,5 @@ public class ActionGetURL extends Action {
@Override
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
output.add(new GetURLTreeItem(this, urlString, targetString));
}
}
}
@@ -32,6 +32,12 @@ public class ActionJump extends Action {
public int offset;
public String identifier;
public ActionJump(int offset){
super(0x99,2);
this.offset=offset;
}
public ActionJump(SWFInputStream sis) throws IOException {
super(0x99, 2);
offset = sis.readSI16();
@@ -76,4 +82,11 @@ public class ActionJump extends Action {
ret.add(this);
return ret;
}
@Override
public String toString() {
return "Jump";
}
}
@@ -201,7 +201,11 @@ public class ActionPush extends Action {
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, java.util.HashMap<Integer, String> regNames) {
for (Object o : values) {
if (o instanceof ConstantIndex) {
o = constants.constants.get(((ConstantIndex) o).index);
if((constants==null)||(((ConstantIndex) o).index>=constants.constants.size())){
o="CONSTNOTFOUND";
}else{
o = constants.constants.get(((ConstantIndex) o).index);
}
}
if (o instanceof RegisterNumber) {
if (regNames.containsKey(((RegisterNumber) o).number)) {
@@ -28,7 +28,7 @@ public class ConstantIndex {
public ConstantIndex(int index) {
this.index = index;
this.constantPool = new ArrayList<String>();
this.constantPool = new ArrayList<String>();
}
public ConstantIndex(int index, List<String> constantPool) {
@@ -23,12 +23,19 @@ import com.jpexs.asdec.action.parser.ASMParser;
import com.jpexs.asdec.action.parser.FlasmLexer;
import com.jpexs.asdec.action.parser.Label;
import com.jpexs.asdec.action.parser.ParseException;
import com.jpexs.asdec.action.swf4.ActionPush;
import com.jpexs.asdec.action.swf7.ActionDefineFunction2;
import com.jpexs.asdec.action.treemodel.ConstantPool;
import com.jpexs.asdec.action.treemodel.FunctionTreeItem;
import com.jpexs.asdec.action.treemodel.TreeItem;
import com.jpexs.asdec.helpers.Helper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
public class ActionDefineFunction extends Action {
@@ -36,9 +43,24 @@ public class ActionDefineFunction extends Action {
public List<String> paramNames = new ArrayList<String>();
public List<Action> code;
public int codeSize;
private int version;
public void setConstantPool(List<String> constantPool){
for(Action a:code){
if(a instanceof ActionPush){
((ActionPush)a).constantPool=constantPool;
}
if(a instanceof ActionDefineFunction2){
((ActionDefineFunction2)a).setConstantPool(constantPool);
}
if(a instanceof ActionDefineFunction){
((ActionDefineFunction)a).setConstantPool(constantPool);
}
}
}
public ActionDefineFunction(int actionLength, SWFInputStream sis, int version) throws IOException {
super(0x9B, actionLength);
this.version=version;
//byte data[]=sis.readBytes(actionLength);
//sis=new SWFInputStream(new ByteArrayInputStream(data),version);
functionName = sis.readString();
@@ -127,4 +149,10 @@ public class ActionDefineFunction extends Action {
public List<Action> getAllIfsOrJumps() {
return Action.getActionsAllIfsOrJumps(code);
}
@Override
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, HashMap<Integer, String> regNames) {
stack.push(new FunctionTreeItem(this, functionName, paramNames, Action.actionsToTree(regNames, code,version ), constants));
}
}
@@ -23,12 +23,19 @@ import com.jpexs.asdec.action.parser.ASMParser;
import com.jpexs.asdec.action.parser.FlasmLexer;
import com.jpexs.asdec.action.parser.Label;
import com.jpexs.asdec.action.parser.ParseException;
import com.jpexs.asdec.action.swf4.ActionPush;
import com.jpexs.asdec.action.swf5.ActionDefineFunction;
import com.jpexs.asdec.action.treemodel.ConstantPool;
import com.jpexs.asdec.action.treemodel.FunctionTreeItem;
import com.jpexs.asdec.action.treemodel.TreeItem;
import com.jpexs.asdec.helpers.Helper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
public class ActionDefineFunction2 extends Action {
@@ -47,9 +54,25 @@ public class ActionDefineFunction2 extends Action {
public int registerCount;
public int codeSize;
public List<Action> code;
private int version;
public void setConstantPool(List<String> constantPool){
for(Action a:code){
if(a instanceof ActionPush){
((ActionPush)a).constantPool=constantPool;
}
if(a instanceof ActionDefineFunction2){
((ActionDefineFunction2)a).setConstantPool(constantPool);
}
if(a instanceof ActionDefineFunction){
((ActionDefineFunction)a).setConstantPool(constantPool);
}
}
}
public ActionDefineFunction2(int actionLength, SWFInputStream sis, int version) throws IOException {
super(0x8E, actionLength);
this.version=version;
functionName = sis.readString();
int numParams = sis.readUI16();
registerCount = sis.readUI8();
@@ -185,6 +208,18 @@ public class ActionDefineFunction2 extends Action {
+ " " + preloadGlobalFlag).trim() + " " + paramStr + " {\r\n" + Action.actionsToString(code, knownAddreses, constantPool, version) + "}";
}
@Override
public String toString() {
return "DefineFunction2";
}
@Override
public void translate(Stack<TreeItem> stack, ConstantPool constants, List<TreeItem> output, HashMap<Integer, String> regNames) {
stack.push(new FunctionTreeItem(this, functionName, paramNames, Action.actionsToTree(regNames, code,version ), constants));
}
@Override
public List<Long> getAllRefs(int version) {
return Action.getActionsAllRefs(code, version);
@@ -31,4 +31,16 @@ public class DecrementTreeItem extends TreeItem {
public String toString(ConstantPool constants) {
return object.toString(constants) + hilight("-1");
}
@Override
public boolean isCompileTime(){
return object.isCompileTime();
}
@Override
public double toNumber() {
return object.toNumber()-1;
}
}
@@ -34,6 +34,29 @@ public class DirectValueTreeItem extends TreeItem {
this.value = value;
}
@Override
public double toNumber() {
if(value instanceof Double){
return (Double)value;
}
if(value instanceof Float){
return (Float)value;
}
if(value instanceof Long){
return (Long)value;
}
return super.toNumber();
}
@Override
public boolean toBoolean() {
boolean ret=(value instanceof Boolean)?(Boolean)value:false;
return ret;
}
@Override
public String toStringNoQuotes(ConstantPool constants) {
if (value instanceof Double) {
@@ -75,4 +98,9 @@ public class DirectValueTreeItem extends TreeItem {
}
return hilight(value.toString());
}
@Override
public boolean isCompileTime(){
return (value instanceof Double)||(value instanceof Float)||(value instanceof Boolean)||(value instanceof Long);
}
}
@@ -30,7 +30,7 @@ public class FunctionTreeItem extends TreeItem {
public FunctionTreeItem(Action instruction, String functionName, List<String> paramNames, List<TreeItem> actions, ConstantPool constants) {
super(instruction, PRECEDENCE_PRIMARY);
this.actions = actions;
this.constants = constants.constants;
this.constants = constants==null?null:constants.constants;
this.functionName = functionName;
this.paramNames = paramNames;
}
@@ -31,4 +31,16 @@ public class IncrementTreeItem extends TreeItem {
public String toString(ConstantPool constants) {
return object.toString(constants) + hilight("+1");
}
@Override
public boolean isCompileTime(){
return object.isCompileTime();
}
@Override
public double toNumber() {
return object.toNumber()+1;
}
}
@@ -96,4 +96,17 @@ public abstract class TreeItem {
return target.toString();
}
}
public boolean isCompileTime(){
return false;
}
public double toNumber(){
return 0;
}
public boolean toBoolean(){
return Double.compare(toNumber(),0.0)!=0;
}
}
@@ -24,4 +24,11 @@ public class AddTreeItem extends BinaryOpTreeItem {
public AddTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+");
}
@Override
public double toNumber() {
return leftSide.toNumber()+rightSide.toNumber();
}
}
@@ -24,4 +24,11 @@ public class AndTreeItem extends BinaryOpTreeItem {
public AndTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_LOGICALAND, leftSide, rightSide, "&&");
}
@Override
public boolean toBoolean() {
return leftSide.toBoolean()&&rightSide.toBoolean();
}
}
@@ -24,4 +24,11 @@ public class AsTypeTreeItem extends BinaryOpTreeItem {
public AsTypeTreeItem(Action instruction, TreeItem value, TreeItem type) {
super(instruction, PRECEDENCE_RELATIONAL, value, type, " as ");
}
@Override
public boolean isCompileTime() {
return false;
}
}
@@ -49,4 +49,8 @@ public abstract class BinaryOpTreeItem extends TreeItem {
}
return ret;
}
@Override
public boolean isCompileTime(){
return leftSide.isCompileTime()&&rightSide.isCompileTime();
}
}
@@ -24,4 +24,9 @@ public class BitAndTreeItem extends BinaryOpTreeItem {
public BitAndTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_BITWISEAND, leftSide, rightSide, "&");
}
@Override
public double toNumber() {
return ((int)leftSide.toNumber())&((int)rightSide.toNumber());
}
}
@@ -24,4 +24,11 @@ public class BitNotTreeItem extends UnaryOpTreeItem {
public BitNotTreeItem(Action instruction, TreeItem value) {
super(instruction, PRECEDENCE_UNARY, value, "~");
}
@Override
public double toNumber() {
return ~((int)value.toNumber());
}
}
@@ -24,4 +24,9 @@ public class BitOrTreeItem extends BinaryOpTreeItem {
public BitOrTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_BITWISEOR, leftSide, rightSide, "|");
}
@Override
public double toNumber() {
return ((int)leftSide.toNumber())|((int)rightSide.toNumber());
}
}
@@ -24,4 +24,9 @@ public class BitXorTreeItem extends BinaryOpTreeItem {
public BitXorTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_BITWISEXOR, leftSide, rightSide, "^");
}
@Override
public double toNumber() {
return ((int)leftSide.toNumber())^((int)rightSide.toNumber());
}
}
@@ -24,4 +24,9 @@ public class DivideTreeItem extends BinaryOpTreeItem {
public DivideTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "/");
}
@Override
public double toNumber() {
return leftSide.toNumber()/rightSide.toNumber();
}
}
@@ -24,4 +24,11 @@ public class EqTreeItem extends BinaryOpTreeItem {
public EqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "==");
}
@Override
public boolean toBoolean() {
return (leftSide.toBoolean()==rightSide.toBoolean())&&(leftSide.toNumber()==rightSide.toNumber());
}
}
@@ -24,4 +24,11 @@ public class GeTreeItem extends BinaryOpTreeItem {
public GeTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">=");
}
@Override
public boolean toBoolean() {
return leftSide.toNumber()>=rightSide.toNumber();
}
}
@@ -24,4 +24,9 @@ public class GtTreeItem extends BinaryOpTreeItem {
public GtTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">");
}
@Override
public boolean toBoolean() {
return leftSide.toNumber()>rightSide.toNumber();
}
}
@@ -24,4 +24,11 @@ public class InTreeItem extends BinaryOpTreeItem {
public InTreeItem(Action instruction, TreeItem name, TreeItem object) {
super(instruction, PRECEDENCE_RELATIONAL, name, object, " in ");
}
@Override
public boolean isCompileTime() {
return false;
}
}
@@ -24,4 +24,11 @@ public class InstanceOfTreeItem extends BinaryOpTreeItem {
public InstanceOfTreeItem(Action instruction, TreeItem value, TreeItem type) {
super(instruction, PRECEDENCE_RELATIONAL, value, type, " instanceof ");
}
@Override
public boolean isCompileTime() {
return false;
}
}
@@ -24,4 +24,11 @@ public class IsTypeTreeItem extends BinaryOpTreeItem {
public IsTypeTreeItem(Action instruction, TreeItem value, TreeItem type) {
super(instruction, PRECEDENCE_RELATIONAL, value, type, " is ");
}
@Override
public boolean isCompileTime() {
return false;
}
}
@@ -24,4 +24,9 @@ public class LShiftTreeItem extends BinaryOpTreeItem {
public LShiftTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, "<<");
}
@Override
public double toNumber() {
return ((int)leftSide.toNumber())<<((int)rightSide.toNumber());
}
}
@@ -24,4 +24,9 @@ public class LeTreeItem extends BinaryOpTreeItem {
public LeTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<=");
}
@Override
public boolean toBoolean() {
return leftSide.toNumber()<=rightSide.toNumber();
}
}
@@ -24,4 +24,9 @@ public class LtTreeItem extends BinaryOpTreeItem {
public LtTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<");
}
@Override
public boolean toBoolean() {
return leftSide.toNumber()<rightSide.toNumber();
}
}
@@ -24,4 +24,9 @@ public class ModuloTreeItem extends BinaryOpTreeItem {
public ModuloTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "%");
}
@Override
public double toNumber() {
return ((int)leftSide.toNumber())%((int)rightSide.toNumber());
}
}
@@ -24,4 +24,9 @@ public class MultiplyTreeItem extends BinaryOpTreeItem {
public MultiplyTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "*");
}
@Override
public double toNumber() {
return leftSide.toNumber()*rightSide.toNumber();
}
}
@@ -24,4 +24,11 @@ public class NegTreeItem extends UnaryOpTreeItem {
public NegTreeItem(Action instruction, TreeItem value) {
super(instruction, PRECEDENCE_UNARY, value, "-");
}
@Override
public double toNumber() {
return -value.toNumber();
}
}
@@ -24,4 +24,9 @@ public class NeqTreeItem extends BinaryOpTreeItem {
public NeqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "!=");
}
@Override
public boolean toBoolean() {
return (leftSide.toNumber()!=rightSide.toNumber())||(leftSide.toBoolean()!=rightSide.toBoolean());
}
}
@@ -34,4 +34,12 @@ public class NotTreeItem extends UnaryOpTreeItem {
public boolean isFalse() {
return !value.isFalse();
}
@Override
public boolean toBoolean() {
boolean ret= !value.toBoolean();
return ret;
}
}
@@ -24,4 +24,11 @@ public class OrTreeItem extends BinaryOpTreeItem {
public OrTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_LOGICALOR, leftSide, rightSide, "||");
}
@Override
public boolean toBoolean() {
return leftSide.toBoolean()||rightSide.toBoolean();
}
}
@@ -24,4 +24,11 @@ public class PreDecrementTreeItem extends UnaryOpTreeItem {
public PreDecrementTreeItem(Action instruction, TreeItem object) {
super(instruction, PRECEDENCE_UNARY, object, "--");
}
@Override
public double toNumber() {
return value.toNumber()-1;
}
}
@@ -24,4 +24,11 @@ public class PreIncrementTreeItem extends UnaryOpTreeItem {
public PreIncrementTreeItem(Action instruction, TreeItem object) {
super(instruction, PRECEDENCE_UNARY, object, "++");
}
@Override
public double toNumber() {
return value.toNumber()+1;
}
}
@@ -24,4 +24,9 @@ public class RShiftTreeItem extends BinaryOpTreeItem {
public RShiftTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>");
}
@Override
public double toNumber() {
return ((int)leftSide.toNumber())>>((int)rightSide.toNumber());
}
}
@@ -24,4 +24,9 @@ public class StrictEqTreeItem extends BinaryOpTreeItem {
public StrictEqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "===");
}
@Override
public boolean toBoolean() {
return (leftSide.toBoolean()==rightSide.toBoolean())&&(leftSide.toNumber()==rightSide.toNumber());
}
}
@@ -24,4 +24,9 @@ public class StrictNeqTreeItem extends BinaryOpTreeItem {
public StrictNeqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "!==");
}
@Override
public boolean toBoolean() {
return (leftSide.toBoolean()!=rightSide.toBoolean())&&(leftSide.toNumber()!=rightSide.toNumber());
}
}
@@ -24,4 +24,9 @@ public class StringAddTreeItem extends BinaryOpTreeItem {
public StringAddTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+");
}
@Override
public boolean isCompileTime() {
return false;
}
}
@@ -24,4 +24,11 @@ public class StringEqTreeItem extends BinaryOpTreeItem {
public StringEqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "==");
}
@Override
public boolean isCompileTime() {
return false;
}
}
@@ -37,4 +37,9 @@ public class StringLengthTreeItem extends TreeItem {
}
return s + hilight(".length");
}
@Override
public boolean isCompileTime() {
return false;
}
}
@@ -24,4 +24,9 @@ public class StringLtTreeItem extends BinaryOpTreeItem {
public StringLtTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<");
}
@Override
public boolean isCompileTime() {
return false;
}
}
@@ -24,4 +24,11 @@ public class SubtractTreeItem extends BinaryOpTreeItem {
public SubtractTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "-");
}
@Override
public double toNumber() {
return leftSide.toNumber()-rightSide.toNumber();
}
}
@@ -24,4 +24,9 @@ public class URShiftTreeItem extends BinaryOpTreeItem {
public URShiftTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) {
super(instruction, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>>");
}
@Override
public double toNumber() {
return ((int)leftSide.toNumber())>>>((int)rightSide.toNumber());
}
}
@@ -39,4 +39,9 @@ public abstract class UnaryOpTreeItem extends TreeItem {
}
return hilight(operator) + s;
}
@Override
public boolean isCompileTime(){
return value.isCompileTime();
}
}