Problems getting into an "if" statement, JAVA
I've got a program that goes through and reads "tokens" that can either be a String (Symbol) or a number. It uses postfix and a stack to evaluate simple commands.
For example:
/x 100 def
/y 200 def
x y add
should return 300. The first line defines a variable called "x" and sets it to 100. To do this a reader adds "/x" and "100" on the stack and stops when it gets to the "def" operator, which tells it to go make a token with a Symbol called "x" and its value being 100. The stack is then empty, and next time "x" would be pushed, the interpreter should automatically replace it with its value. This is where my problem lies.
This is my interpreter:
while ( r.hasMoreTokens() ) {
Token t = r.nextToken();
if ( !t.isSymbol() ) {
开发者_如何学Go operands.push( t );
} else if (env.contains(t.getSymbol())) {
Token tmp = env.get(t.getSymbol());
operands.push(tmp);
} else if (t.getSymbol().startsWith("/")) {
operands.push(t);
} else if ( t.getSymbol().equals( "def" ) ){
execute_def();
} else if ( t.getSymbol().equals( "add" ) ) {
execute_add();
} else if ( t.getSymbol().equals( "sub" ) ) {
execute_sub();
} else if ( t.getSymbol().equals( "mul" ) ) {
execute_mul();
} else if ( t.getSymbol().equals( "exch" ) ) {
execute_exch();
} else if ( t.getSymbol().equals( "dup" ) ) {
execute_dup();
} else if ( t.getSymbol().equals( "pop" ) ) {
execute_pop();
} else if ( t.getSymbol().equals( "pstack" ) ) {
execute_pstack();
} else if ( t.getSymbol().equals( "moveto" ) ) {
execute_moveto();
} else if ( t.getSymbol().equals( "lineto" ) ) {
execute_lineto( g );
} else if ( t.getSymbol().equals( "arc" ) ) {
execute_arc( g );
} else if ( t.getSymbol().equals( "quit" ) ) {
execute_quit();
} else {
System.out.println( "ILLEGAL SYMBOL: " + t );
}
}
Once the variables get defined correctly, I cant get into that first else if
and change the value. Because I can't do this, I never push anything on the stack and end up with an empty stack error. Here are the methods contains()
and get()
from env (environment):
public boolean contains(String key) {
Elem tmp = top;
for (int i = 0; i < size; i++) {
if (tmp.key == key) {
return true;
} else {
tmp = tmp.next;
}
}
return false;
}
public Token get(String key) {
Elem tmp = top;
int counter = 0;
boolean found = false;
for (int i = 0; i < size; i++) {
if (tmp.key == key) {
found = true;
break;
} else {
tmp = tmp.next;
}
counter++;
}
if (found == true) {
tmp = top;
for (int i = 0; i <= counter; i++) {
tmp = tmp.next;
}
return tmp.value;
} else {
throw new BadKeyQueryException();
}
}
I'm using linked elements in the environment to keep track of symbols. Elem is a nested class in Environment:
private static class Elem {
private String key;
private Token value;
private Elem next;
private Elem(String key, Token value, Elem next) {
this.key = key;
this.value = value;
this.next = next;
}
}
Thanks for any help from you guys!
Strings in java are Objects, rather than primitives.
When you say:
int i = 5;
i stores the value "5".
When you say:
String s = "string";
s stores the value of a reference to "string".
Comparing s to "string" would return false, even though they contain the same value when you print there. This is because the computer compares a reference to memory containing "string" to another reference to memory containing "string". Same values, but different references.
Also, you're setting "t" to multiple different values in your code. Try setting t once, before everything, and a precomputed t value against your if-else-if block.
You can only call getSymbol() once, so you just need to store the value from it. Here is the start of your statements, you should be able to change the others the same way
if ( !t.isSymbol() ) {
operands.push( t );
continue;
}
String symbol = t.getSymbol();
if (env.contains(symbol)) {
Token tmp = env.get(symbol);
operands.push(tmp);
} else if (symbol.startsWith("/")) {
operands.push(t);
...
精彩评论