struct Statement {
enum Type {
Alloc, Assign, Store, Load
} type;
struct Operand {
enum Type {
Variable, Object, Field
} type;
char str[3];
int p0, p1;
void determine() {
if(str[1] == '.') type = Field, p0 = str[0] - 'A', p1 = str[2] - 'a';
else if(islower(str[0])) type = Object, p0 = str[0] - 'a';
else type = Variable, p0 = str[0] - 'A';
}
} left, right;
void determine() {
if(left.type == Operand::Variable && right.type == Operand::Object) type = Alloc;
else if(left.type == Operand::Variable && right.type == Operand::Variable) type = Assign;
else if(left.type == Operand::Field && right.type == Operand::Variable) type = Store;
else if(left.type == Operand::Variable && right.type == Operand::Field) type = Load;
}
int execute() {
int ret = 0, pop;
switch(type) {
case Alloc:
if(A[left.p0] & (1 << right.p0)) ret = 0;
else A[left.p0] |= (1 << right.p0), ret = 1;
break;
case Assign:
ret = __builtin_popcount(A[left.p0]);
A[left.p0] |= A[right.p0];
ret = __builtin_popcount(A[left.p0]) - ret;
break;
case Store:
for(int i = 0; i < 26; ++i) {
if(A[left.p0] & (1 << i)) {
pop = __builtin_popcount(G[i][left.p1]);
G[i][left.p1] |= A[right.p0];
ret += __builtin_popcount(G[i][left.p1]) - pop;
}
}
break;
case Load:
pop = __builtin_popcount(A[left.p0]);
for(int i = 0; i < 26; ++i) {
if(A[right.p0] & (1 << i)) {
A[left.p0] |= G[i][right.p1];
}
}
ret = __builtin_popcount(A[left.p0]) - pop;
break;
}
return ret;
}
} prog[233];