blob: 0802bf14a8482d591fd77e9c28ecc8363b06f04f [file] [log] [blame]
/* exp.h */
/*
Java Decompiler
Copyright (c) 1994-2003, Pete Ryland.
Distributed under the GNU GPL Version 2.
This package is available from http://pdr.cx/hbd/
*/
#ifndef EXP_H
#define EXP_H
#include "id.h"
#include "op.h"
/* The various types of expressions */
enum Exptype {
NOEXP, IDENT, PREUNARY, POSTUNARY,
BINARY, TERNARY, FUNCTIONCALL, ARRAYACCESS,
BRANCH, SWITCH
};
/*
This structure is a secondary structure to
the actual Exp struct. It is used to allow
us to have a set of "standard" Expressions
for things like an integer constant "1" which
is often used. This saves both time and memory.
*/
struct Exp_ {
int isstd; /* 1 if this is one of the standard Exp_'s */
Exptype et; /* The tpye of expression this is */
Type type; /* The Java type of the result of this Exp_ */
Op op; /* The operation performed in this Exp_ */
Id *id; /* A reference to an Id if this Exp_
is simply an identifier */
/* This constructor creates an expression for the
given identifier */
Exp_(Id *idptr) {
isstd = 1; et = IDENT; type = idptr->type;
op = ID; id = idptr;
}
/* These constructors will create more general Exp_'s */
Exp_(Exptype _et, Type _type, Op _op) {
isstd = 0; et = _et; type = _type; op = _op;
}
Exp_(Exptype _et, Type _type, Op _op, Id *_id) {
isstd = 0; et = _et; type = _type; op = _op; id = _id;
}
Exp_(int _isstd, Exptype _et, Type _type, Op _op, Id *_id) {
isstd = _isstd; et = _et; type = _type; op = _op; id = _id;
}
};
/* This is the table of commonly-used Exp_'s */
extern Exp_ std_exps[];
struct Case { long caseval; long branch_pc; };
/* The main Exp struct */
struct Exp {
/* The secondary Exp_ structure for this Exp */
Exp_ *e;
/* A reference count */
unsigned numrefs;
unsigned pc;
unsigned minpc;
Exp *exp1, *exp2;
union {
Exp *exp3;
unsigned default_pc;
};
union {
unsigned numexps;
unsigned branch_pc;
unsigned numcases;
};
union {
Exp **explist;
Case *cases;
};
/* Constructors for "standard" Exp_'s */
Exp(unsigned pcval, unsigned stdexpnum) {
numrefs = 1; pc = minpc = pcval; e = std_exps + stdexpnum;
}
Exp(unsigned pcval, unsigned minpcval,
unsigned stdexpnum, Exp *_exp1, unsigned branchpcval) {
numrefs = 1; pc = pcval; minpc = minpcval;
e = std_exps + stdexpnum;
exp1 = _exp1; branch_pc = branchpcval;
}
/* A constructor for Identifiers */
Exp(unsigned pcval, Exptype et, Type type, Op op, Id *id) {
numrefs = 1; pc = minpc = pcval;
e = new Exp_(et, type, op, id);
}
/* A fairly general constructor */
Exp(unsigned pcval, Exptype et,
Type type, Op op, Exp *_exp1 = 0, Exp *_exp2 = 0) {
numrefs = 1; pc = minpc = pcval;
e = new Exp_(et, type, op);
exp1 = _exp1; exp2 = _exp2;
}
/* A constructor for case "expressions" */
Exp(unsigned pcval, unsigned minpcval, Exptype et,
Type type, Op op, Exp *_exp1, unsigned defaultpcval,
unsigned _numcases, Case *_cases) {
numrefs = 1; pc = pcval; minpc = minpcval;
e = new Exp_(et, type, op);
exp1 = _exp1; default_pc = defaultpcval;
numcases = _numcases; cases = _cases;
}
/* A constructor for method calls */
Exp(unsigned pcval, unsigned minpcval, Exptype et,
Type type, Op op, Exp *_exp1,
unsigned _numexps, Exp** _explist) {
numrefs = 1; pc = pcval; minpc = minpcval;
e = new Exp_(et, type, op);
exp1 = _exp1; numexps = _numexps;
explist = _explist;
}
/* A constructor for conditionals */
Exp(unsigned pcval, Exptype et, Type type,
Op op, Exp *_exp1, unsigned branchpcval) {
numrefs = 1; pc = minpc = pcval;
e = new Exp_(et, type, op);
exp1 = _exp1; branch_pc = branchpcval;
}
/* Another general constructor */
Exp(unsigned pcval, int minpcval, Exptype et,
Type type, Op op, Exp *_exp1, Exp *_exp2 = 0) {
numrefs = 1; pc = pcval; minpc = minpcval;
e = new Exp_(et, type, op);
exp1 = _exp1; exp2 = _exp2;
}
/* Another constructor for identifiers */
Exp(unsigned pcval, char *idname,
Type idtype, Loc idloc, int idlocinfo = 0) {
Id *id = new Id; id->name = idname; id->type = idtype;
id->loc = idloc; id->locinfo = idlocinfo;
numrefs = 1; pc = minpc = pcval;
e = new Exp_(IDENT, idtype, ID, id);
}
/* Provides a string representation of this Expression */
char *toString(unsigned nextpc);
};
/* This enum provides an easier way to look up the table of
"standard" Exp_'s */
enum stdexp_vals {
NULLEXP, INEG1EXP, I0EXP, I1EXP, I2EXP, I3EXP, I4EXP, I5EXP,
L0EXP, L1EXP, F0EXP, F1EXP, F2EXP, D0EXP, D1EXP, FALSEEXP,
TRUEEXP, IFEXP
};
/* This recursively deletes an expression and it's children */
void killexp(Exp *e);
/* This will negate a boolean expression. It will cause an
error if called on a non-boolean expression */
int notexp(Exp **e);
/* These handle the indent level during the print phase */
struct intnode {
unsigned node;
intnode *next;
intnode(unsigned i) {
node = i;
next = 0;
}
intnode(unsigned i, intnode *n) {
node = i;
next = n;
}
};
struct intlist {
intnode *head;
intnode *tail;
intlist() {
head = 0;
tail = 0;
}
void push(unsigned i) {
intnode *n = new intnode(i, head);
head = n;
if (tail == 0)
tail = head;
}
void add(unsigned i) {
intnode *n = new intnode(i);
if (tail == 0) {
head = tail = n;
} else {
tail->next = n;
tail = n;
}
}
unsigned top() {
return head?head->node:0;
}
int isempty() {
return head==0;
}
unsigned pop() {
intnode *n = head;
unsigned i = n->node;
head = n->next;
delete n;
if (head == 0)
tail = 0;
return i;
}
int contains(unsigned i) {
intnode *n = head;
while (n) {
if (n->node == i)
return 1;
n = n->next;
}
return 0;
}
};
typedef enum { LOOP_WHILE, LOOP_DOWHILE, LOOP_FOR } LoopType;
struct Loop {
unsigned jumpfrom_pc, jumpto_pc, jumppast_pc;
Exp *condition;
LoopType type;
Loop(unsigned from, unsigned to, unsigned past, Exp *cond, LoopType lt) {
jumpfrom_pc = from; jumpto_pc = to; jumppast_pc = past;
condition = cond; type = lt;
}
};
struct loopnode {
Loop *node;
loopnode *next;
loopnode(Loop *e) {
node = e;
next = 0;
}
loopnode(Loop *e, loopnode *n) {
node = e;
next = n;
}
};
struct looplist {
loopnode *head;
loopnode *tail;
looplist() {
head = 0;
tail = 0;
}
void push(Loop *e) {
loopnode *n = new loopnode(e, head);
head = n;
if (tail == 0)
tail = head;
}
void add(Loop *e) {
loopnode *n = new loopnode(e);
if (tail == 0) {
head = tail = n;
} else {
tail->next = n;
tail = n;
}
}
Loop *top() {
return head?head->node:0;
}
int isempty() {
return head==0;
}
Loop *pop() {
loopnode *n = head;
Loop *e = n->node;
head = n->next;
delete n;
if (head == 0)
tail = 0;
return e;
}
int containsPast(unsigned i) {
loopnode *n = head;
while (n) {
if (n->node->jumppast_pc == i)
return 1;
n = n->next;
}
return 0;
}
};
extern int indentlevel;
#endif