Writing BASIC interpreter in java - loops and ifs - java

This paper: http://www.codeproject.com/Articles/345888/How-to-write-a-simple-interpreter-in-JavaScript helped me greatly in terms of engineering parsing and write instructions, however it does not explain how to write loops and ifs. Can you point me to some papers about that? While adding predefined functions, etc. is easy, especially since my BASIC dialect will be very oldschool one with mandatory line numbers, requirement for using LET to set variables, etc. and very fixed syntax (i.e. no ':' to separate instructions, only one instruction per line, no whitespaces allowed for parameter separation so 10 LET variable,value is valid, but 10 LET variable, value is not)?
On second thought maybe ifs will be easy, but there's still problem on how to do for..next loop (my interpreter won't use whiles/do..whiles, only oldschool gotos/gosubs).

To implement GOTO, you need a way to modify the i variable (usually called the program counter) in evaluate(). One way would be modifying parseNode to return an object instead of simple value:
// ...evaluate()...
var result = parseNode(parseTree[i]);
if (typeof result.newI !== undefined) {
i = result.newI;
}
if (typeof result.value !== "undefined") {
output += value + "\n";
}
// ...parseNode....
else if (node.type === "goto") {
return {newI : node.value};
}
Implementing IF would be simpler, something like this (if the condition is in node.args):
else if (node.type === "if") {
if (parseNode(node.args).value != 0) {
return parseNode(node.value);
}
}
I'm not sure if this implements multiple statements per IF well, but your dialect doesn't either.

Related

How does Java work with variables when evaluating a statement?

Basically what I am asking is if It's possible to use the same variable in an if statement. Assigning it a new value halfway through the statement so that I don't have to initialize a new variable. I know this is probably horrible practice but I'm just curious if it can be done.
Here is the closest I feel that I have gotten so far:
if(curID + 1 != (curID = myScanner.nextInt())) {
System.out.print(j++);
break;
} else {
j++;
}
Sorry if this is a duplicate but I couldn't seem to find anything on it. More than likely because I forgot the technical terms.
Edit: Forgot to say that when I ran it I think it just used the new variable for both instances because the loop just broke. I could be wrong though.
There is no benefit to writing
if(curID++ != (curID = myScanner.nextInt())) {
versus
if(curID != (curID = myScanner.nextInt())) {
because the value stored back by ++ will be lost by the subsequent assignment. That you're thinking of doing this suggests you're fuzzy on what these things mean.
EDITED: per discussion in comments, you're also confused about the difference between prefix and postfix forms of ++. The postfix form evaluates to the value before the increment occurs.
But in any case, the whole thing is better written without the embedded assignment.
int prevId = curId;
curId = myScanner.nextInt();
if (prevId + 1 != curId) {
...
}
EDITED: added the + 1 to make the code work as discussed in the comments, as distinct from as originally written.
Your concern that you "don't have to initialize a new variable" is misplaced. Adding prevId costs almost nothing.
Writing it per my suggestion means you don't have to wonder about what Java may or may not do (though you can readily determine it from the online Java Language Specification), since it is now obvious. And that's the most important thing in programming.

Nested ifs or ands?

I'm a beginner level programmer who's just starting to work on actual projects, and I'm starting to think about things such as efficiency and if my code looks professional. I was wondering if, when trying to check multiple booleans, is it better to use nested if statements, or multiple && and || operators.
Action action = event.getAction();
Material holding = event.getItem().getType();
if((action.equals(Action.RIGHT_CLICK_AIR)||(action.equals(Action.RIGHT_CLICK_BLOCK))))
{
if((event.hasItem())&&(holding.equals(Material.COMPASS)))
{
//if the player right clicked while holding a compass
}
}
Does this look right? I tried to group the like if-statements together. Also, if there's anything else I can do to improve my formatting, please tell me! Thanks.
Welcome to the Stack Overflow community!
There is no problem with the code shared in the question. In some cases, it is better to opt for legibility so that your co-workers will be able to understand the proposed code better. But in the end, this is very subjective.
IMHO, it is easier to understand if we write all the conditions at once. So,
Action action = event.getAction();
Material holding = event.getItem().getType();
Boolean isRequiredAction = action.equals(Action.RIGHT_CLICK_AIR) || action.equals(Action.RIGHT_CLICK_BLOCK)
if (
isRequiredAction
&& event.hasItem()
&& holding.equals(Material.COMPASS)
)
{
// logic...
}
However, if you really want advice and tips on how to refactor it and best practices in a particular language, try Code Review community.
imo for a personal taste, i would put those nested conditions in a boolean variable that can explain the behavior as much as the comment you let in the block, like:
boolean isActionRightClick = action.equals(Action.RIGHT_CLICK_AIR ||action.equals(Action.RIGHT_CLICK_BLOCK);
boolean isHoldingACompass = event.hasItem() && holding.equals(Material.COMPASS);
and then
if ( isActionRightClick && isHoldingACompass ) {...}
Yes your code looks very good to me. I used to work on big projects and uses nested if statements, or multiple && and || operators which saves time. In your code efficiency can be traced at :
if((action.equals(Action.RIGHT_CLICK_AIR)||(action.equals(Action.RIGHT_CLICK_BLOCK))))
As now check only one condition in the or statement will satisfy the if condition which will save time and also shorten the code length.
You can make this code more shorter by removing unwanted parenthesis from your code. Which you must take care in future.
For more details related to efficient coding you can visit this link:
https://docs.oracle.com/cd/E80738_01/pt854pbh2/eng/pt/tpcd/task_WritingMoreEfficientCode-0749ba.html#topofpage
This is good to think about the quality/readability of your code.
Nested "if" are a good question in most of the case i think this depends of people. Some people prefer to nest it, to evaluate condition one after another. Some other prefer to not nest for not lose the track in the block.
But in most of the case be careful to not do to much if statement and try to replace it with pattern design (Easier said than done.). You can find a lot of it in java-design-patterns
I think you could make it even more shorter by using ternary operator (?:) right.
if (expression1) {
result = 1;
} else if (expression2) {
result = 2;
} else if (expression3) {
result = 3;
} else {
result = 0;
}
result = (expression1) ? 1 : (expression2) ? 2 : (expression3) ? 3 : 0;

How do I evaluate boolean expression with many arguments?

I am trying to set up a condition check for my code. However, the code has become long and complex. I need a simpler version of the code that can easily do the job.
I have tried to compare three boolean values separated by brackets such that I only compare two values.
if (
(((userState[0][0]&&userState[0][1])&&(userState[0][2]))) ||
(((userState[1][0]&&userState[1][1])&&(userState[1][2]))) ||
(((userState[2][0]&&userState[2][1])&&(userState[2][2]))) ||
(((userState[0][0]&&userState[1][0])&&(userState[2][0]))) ||
(((userState[0][1]&&userState[2][1])&&(userState[1][1]))) ||
(((userState[0][2]&&userState[2][2])&&(userState[1][2]))) ||
(((userState[0][0]&&userState[2][2])&&(userState[1][1]))) ||
(((userState[1][2]&&userState[1][1])&&(userState[2][0])))
)
You can use nested loop:
boolean result;
for (int i = 0; i < userState.length; i++) {
for (int j = 0; j < userState[i].length; j++) {
result |= userStage[i][j];
}
}
Clean code suggests to never write such code in the first place.
If at all, you could for example create small helper methods for each line, like:
private hasStateConditionXyz(boolean[][] userState) {
return userState[0][0]&&userState[0][1])&&(userState[0][2];
}
where "Xyz" would be a nice handsome name that tells the reader what the intention of that check is.
Of course, that breaks your ability to somehow loop over your array.
In other words:
if possible, see if it is possible to compute your result by looping over that array, instead of writing down such manual "patterns"
if not, consider using such named helper methods
Where, in the end, the real answer might be to step back and look at the overall problem to solve. Meaning: when you have such a complex "state machine", then it might be better to really create a state machine. Or to use some sort of "work flow" engine. Such tools allow you to express such complex (business?) rules in much more concise and readable ways.

What are the cases in which it is better to use unconditional AND (& instead of &&)

I'd like to know some cases in Java (or more generally:
in programming) when it is preferred in boolean expressions to use the unconditional AND (&) instead of the conditional version (&&).
I know how they work, but I cannot think about a case when use the single & is worth it.
I have found cases in real life where both sides of the expression were really cheap, so it shaved off a nanosecond or two to avoid the branch and to use the unconditional & instead of &&. (These were extremely high-performance math utilities, though; I would almost never use this in other code, and I wouldn't have done it anyway without exhaustive benchmarking to prove it was better.)
(To give specific examples, x > 0 is going to be super cheap and side-effect-free. Why bother risking a branch misprediction to avoid a test that's going to be so cheap anyway? Sure, since it's a boolean the end result is going to be used in a branch anyway, but if (x >= 0 && x <= 10) involves two branches, and if (x >= 0 & x <= 10) involves only one.)
The only difference is that && and || stop the evaluation as soon as it is known. So for example:
if (a != null && a.get() != null)
works well with &&, but with & you could get a NullPointerException if a is null.
The only case I can think about where you want to use & is if the second operand has a side effect, for example (probably not the best example but you get the point):
public static void main(String[] args) {
int i = 1;
if (i == 0 & ++i != 2) {
}
System.out.println(i); //2
i = 1;
if (i == 0 && ++i != 2) {
}
System.out.println(i); //1
}
However, this looks like smelly code to me (in both cases).
The && allows the jvm to do short circuit evaluation. That is, if the first argument is false, then it doesn't need to bother checking the second argument.
A single & will run both sides regardless.
So, as a contrived example, you might have:
if (account.isAllowed() & logAccountAndCheckFlag(account))
// Do something
In that example, you might always want to log the fact that the owner of the account attempted to do something.
I don't think I have ever used a single & in commercial programming though.
Wikipedia has nicely described the Short Circuit Evaluation
Where do you prefer non short-circuit operators ?
From the same link:
Untested second condition leads to unperformed side effect
Code efficiency
Short-circuiting can lead to errors in branch prediction on modern
processors, and dramatically reduce performance (a notable example is
highly optimized ray with axis aligned box intersection code in ray
tracing)[clarification needed]. Some compilers can detect such cases
and emit faster code, but it is not always possible due to possible
violations of the C standard. Highly optimized code should use other
ways for doing this (like manual usage of assembly code)
If there are side effects that must happen, but that's a little ugly.
The bitwise AND (&) is mostly useful for just that - bitwise math.
Input validation is one possible case. You typically want to report all the errors in a form to the user in a single pass instead of stopping after the first one and forcing them to click submit repeatedly and only get a single error each time:
public boolean validateField(string userInput, string paramName) {
bool valid;
//do validation
if (valid) {
//updates UI to remove error indicator (if present)
reportValid(paramName);
} else {
//updates UI to indicate a problem (color change, error icon, etc)
reportInvalid(paramName);
}
}
public boolean validateAllInput(...) {
boolean valid = true;
valid = valid & validateField(userInput1, paramName1);
valid = valid & validateField(userInput2, paramName2);
valid = valid & validateField(userInput3, paramName3);
valid = valid & validateField(userInput4, paramName4);
valid = valid & validateField(userInput5, paramName5);
return valid;
}
public void onSubmit() {
if (validateAllInput(...)) {
//go to next page of wizard, update database, etc
processUserInput(userInput1, userInput2, ... );
}
}
public void onInput1Changed() {
validateField(input1.Text, paramName1);
}
public void onInput2Changed() {
validateField(input2.Text, paramName2);
}
...
Granted, you could trivially avoid the need for short circuit evaluation in validateAllInput() by refactoring the if (valid) { reportValid() ... logic outside of validateField(); but then you'd need to call the extracted code every time validateField() was called; at a minimum adding 10 extra lines for method calls. As always it's a case of which tradeoff's work best for you.
If the expression are trivial, you may get a micro-optimisation by using & or | in that you are preventing a branch. ie.
if(a && b) { }
if(!(a || b)) { }
is the same as
if (a) if (b) { }
if (!a) if (!b) { }
which has two places a branch can occur.
However using an unconditional & or |, there can be only one branch.
Whetehr this helps or not is highly dependant on what the code is doing.
If you use this, I sugegst commenting it to make it very clear why it has been done.
There isn't any specific use of single & but you can consider the following situation.
if (x > 0 & someMethod(...))
{
// code...
}
Consider that someMethod() is doing some operation which will modify instance variables or do something which will impact behavior later in processing.
So in this case if you use && operator and the first condition fails it will never go in someMethod(). In this case single & operator will suffice.
Because & is a bit-wise operator, you can do up to 32-checks in a single operation concurrently. This can become a significant speed gain for this very specific use cases. If you need to check a large number of conditions, and do it often and the cost of boxing/unboxing the conditions are amortized by the number of checks, or if you store your data on-disk and on-RAM in that format (it is more space efficient to store 32 conditions in a single bitmask), the & operator can give a huge speed benefit over a series of 32 individual &&. For example if you want to select all units that can move, is an infantry, has weapon upgrade, and is controlled by player 3, you can do:
int MASK = CAN_MOVE | INFANTRY | CAN_ATTACK | HAS_WEAPON_UPGRADE | PLAYER_3;
for (Unit u in allunits) {
if (u.mask & MASK == MASK) {
...;
}
}
See my other answers on a related question for more on the topic.
The only benefit I can think of is when you need to invoke a method or execute a code, no matter the first expression is evaluated to true or false:
public boolean update()
{
// do whatever you want here
return true;
}
// ...
if(x == y & update()){ /* ... */}
Although you can do this without &:
if(x == y){/* ... */}
update();
Short-circuiting can lead to errors in branch prediction on modern processors, and dramatically reduce performance (a notable example is highly optimized ray with axis aligned box intersection code in ray tracing)[clarification needed].

Condition that is true and false at the same time in C or Java [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What's the “condition” in C interview question?
Can something like this be done?
Code:
if(condition) {
printf("Hello")
} else {
printf("World");
}
Result: Hello World
What should be the condition to be used to make that possible ?
Please help. Thanks in advance.
No.
The else statement will only execute if the if didn't.
You can cheat to get this result in C:
#include <stdio.h>
#define else printf(" ");
int main()
{
int condition = 1;
if(condition) {
printf("Hello");
}
else {
printf("World");
}
}
Output:
Hello World
The only idea that comes into my mind is something like
if (printf("Hello") > 0)
printf("");
else
printf(" world");
but it's not the same thing, you can't execute both branches of an if/else: one of two is chosen.
The instructor is expecting you to fill in fork() as the condition. This is not general C code but Unix/POSIX code, and works by splitting the process into a parent process and child process. fork returns the child process id (a nonzero number, thus true) in the parent and 0 (false) in the child.
Another potential way to solve the problem, if you can add code elsewhere, is to write setjmp(jmp_buf) as the condition, and add a longjmp(jmp_buf, 1); after the conditional. However this seems to break the rules of the problem.
if/elses are either/ors. Either the if portion is executed or the else, but never both.
No, the statement is if ... else, not if ... and then also maybe. The condition is evaluated once, and the branch is chosen.
Its insane, but:
int test = 0;
String s = "";
switch (test) {
case 0: s += "Hello";
default: s += "World";
}
System.out.println(s);
Boolean type variables in both languages do not allow what you want to do. The whole point is that they must be one or the other.
To accomplish what you want, you probably need a custom type.
//This type allows for quantum weirdness
public class NotABool{
public boolean isTrue = false;
public boolean isFalse = false;
//Funky setMethod
void set(boolean value){
//...
}
}
NotABool nab = new NotABool();
if (NotABool.isTrue){
//Print "Hello"
}
if (NotABool.isFalse){
//Print "World"
}
Can you clarify what you're trying to accomplish?
The functionality you are describing looks more like the switch structures.
In Java, you can only switch on int and enum types, but in C, you can switch on string as well as int types.
It would look like so:
int i = 0;
switch (i) {
case 0:
System.out.print("Hello ");
case 1:
System.out.print("World!");
break;
}
The resulting output would be "Hello World!"
When i is 0, it matches the first case and executes the code until the next break; statement is found. If i was 1, it would only print out "World!".
In general, no, it's not possible. The way the if/else is translated to Java bytecode (and in either case, to machine code), one process will run exactly one of the two branches of the statement. If we didn't have if/else, we'd end up using goto to synthesize it, and that would look a lot like this:
if (condition) goto if_block;
else_block:
printf("World");
goto after_ifelse;
if_block:
printf("Hello");
after_ifelse:
As you can see, if the condition's true (even if it could somehow also be false!), the process will follow the 'if' branch and skip past the other. There's no way to get around this in a single process; any way would require changing the code of the program, or broken hardware (particularly RAM or CPU), or enough radiation to kill you. And every compiler and environment i know of treats if/else that way, though it's common to have the else case after the if (and invert the condition), which makes the (quite valid) assumption that any boolean condition that's not true is false.
Now with all that said...in C, it's semi possible, but not in the way you're thinking -- and not on every OS. On *nix systems, there's a system call usually called fork(), which allows one process to become two (thereby sidestepping the "one process will run exactly one branch" limitation).
if (fork())
printf("Hello");
else
printf("World");
But (1) this code has an inherent race condition -- both branches are now set to run, but either one could run before the other. You'd need to wait on the child process. And (2) this isn't a "condition", it's a function call. If you're not allowed to add code, then this should not be available as an answer.
Or you could do some evil macro stuff to translate the else into something else entirely. But anyone reading your code later would want to hunt you down and confiscate your keyboard, and that's if they're nice.

Categories

Resources