Nasal Conditionals: Difference between revisions

Jump to navigation Jump to search
m
Use Nasal highlighter
m (make condition less abstract)
m (Use Nasal highlighter)
Line 4: Line 4:
Sometimes you may only want to execute certain portions of your code, depending on conditions. This can be accomplished in several ways. One of the most straightforward ways  being an '''if''' expression, which  has the form:
Sometimes you may only want to execute certain portions of your code, depending on conditions. This can be accomplished in several ways. One of the most straightforward ways  being an '''if''' expression, which  has the form:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var condition=1; # this evaluates to boolean true
var condition=1; # this evaluates to boolean true
if (condition) {
if (condition) {
Line 15: Line 15:
To negate the whole thing, use the '''!''' operator:
To negate the whole thing, use the '''!''' operator:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var condition=1; # boolean true
var condition=1; # boolean true
if (!condition) {
if (!condition) {
Line 26: Line 26:
In both examples, the '''condition''' variable is just a placeholder, it could be a variable named '''condition''', but it could also be a more complex expression, such as a '''getprop''' call for example:
In both examples, the '''condition''' variable is just a placeholder, it could be a variable named '''condition''', but it could also be a more complex expression, such as a '''getprop''' call for example:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var condition = getprop("/sim/signals/freeze");
var condition = getprop("/sim/signals/freeze");


Line 39: Line 39:




<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
if (var condition = getprop("/sim/signals/freeze")) {
if (var condition = getprop("/sim/signals/freeze")) {
     # true block, will  be executed if condition is true
     # true block, will  be executed if condition is true
Line 50: Line 50:




<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
if (getprop("/sim/signals/freeze")) {
if (getprop("/sim/signals/freeze")) {
     # true block, will  be executed if condition is true
     # true block, will  be executed if condition is true
Line 63: Line 63:
* '''or'''
* '''or'''


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var condition = (1==1 and 2==2 and 3==3) or (4!=5 and !0);
var condition = (1==1 and 2==2 and 3==3) or (4!=5 and !0);
if (condition) {
if (condition) {
Line 78: Line 78:
The last semicolon in a code block is optional, to make this prettier:
The last semicolon in a code block is optional, to make this prettier:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var abs = func(n) {  
var abs = func(n) {  
     if(n<0)  
     if(n<0)  
Line 89: Line 89:
And for those who don't like typing, the ternary operator works like you expect:
And for those who don't like typing, the ternary operator works like you expect:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var abs = func(n) { n < 0 ? -n : n }
var abs = func(n) { n < 0 ? -n : n }
</syntaxhighlight>
</syntaxhighlight>
Line 95: Line 95:
In addition, Nasal supports braceless blocks, like they're known from C/C++ and other languages. Basically, the block ends with a semicolon, instead of being encapsulated inside a <tt>{</tt>/<tt>}</tt> pair. This means basically that the first statement (expression) after a conditional is evaluated if the condition is true, otherwise it will be ignored:
In addition, Nasal supports braceless blocks, like they're known from C/C++ and other languages. Basically, the block ends with a semicolon, instead of being encapsulated inside a <tt>{</tt>/<tt>}</tt> pair. This means basically that the first statement (expression) after a conditional is evaluated if the condition is true, otherwise it will be ignored:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var foo=1;
var foo=1;
if (foo)
if (foo)
Line 107: Line 107:
Instead of a switch statement one can use
Instead of a switch statement one can use


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
if (1==2) {
if (1==2) {
     print("wrong");
     print("wrong");
Line 120: Line 120:
Instead of "else if", you can also use the shorter equivalent form "elsif":
Instead of "else if", you can also use the shorter equivalent form "elsif":


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
if (1==2) {
if (1==2) {
     print("wrong");
     print("wrong");
Line 133: Line 133:
The <tt>nil</tt> logic is actually quite logical, let's just restate the obvious:
The <tt>nil</tt> logic is actually quite logical, let's just restate the obvious:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
if (nil) {
if (nil) {
     print("This should never be printed");
     print("This should never be printed");
Line 145: Line 145:
Nasal's binary boolean operators are "and" and "or", unlike C. Unary not is still "!" however. They short-circuit like you expect:
Nasal's binary boolean operators are "and" and "or", unlike C. Unary not is still "!" however. They short-circuit like you expect:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var toggle = 0;
var toggle = 0;
var a = nil;
var a = nil;
Line 155: Line 155:
Note that you should always surround multiple conditions within outer parentheses:
Note that you should always surround multiple conditions within outer parentheses:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
if (1) do_something();
if (1) do_something();
if (1 and 1) do_something();
if (1 and 1) do_something();
Line 164: Line 164:
Nasal's binary boolean operators can also be used to default expressions to certain values:
Nasal's binary boolean operators can also be used to default expressions to certain values:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var altitude = getprop("/position/altitude-ft") or 0.00;
var altitude = getprop("/position/altitude-ft") or 0.00;
</syntaxhighlight>
</syntaxhighlight>
Line 176: Line 176:
At first, this may seem pretty complex and counter-intuitive - but it's important to keep this technique in mind, especially for variables that are later on used in calcuations:
At first, this may seem pretty complex and counter-intuitive - but it's important to keep this technique in mind, especially for variables that are later on used in calcuations:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var x = getprop("/velocities/airspeed-kts") or 0.00; # to ensure that x is always valid number
var x = getprop("/velocities/airspeed-kts") or 0.00; # to ensure that x is always valid number
var foo = 10*3.1*x; # ... for this computation
var foo = 10*3.1*x; # ... for this computation
Line 185: Line 185:
Bottom line being, using "or" to default a variable to a given value is a short and succinct way to avoid otherwise elaborate checks, e.g. compare:
Bottom line being, using "or" to default a variable to a given value is a short and succinct way to avoid otherwise elaborate checks, e.g. compare:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var altitude_ft = getprop("/position/altitude-ft");
var altitude_ft = getprop("/position/altitude-ft");
if (altitude_ft == nil) {
if (altitude_ft == nil) {
Line 194: Line 194:
versus:
versus:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var altitude_ft = getprop("/position/altitude-ft") or 0.00;
var altitude_ft = getprop("/position/altitude-ft") or 0.00;
</syntaxhighlight>
</syntaxhighlight>
Line 204: Line 204:
Nasal is a language that has no statements, it's all about EXPRESSIONS. So you can put things in pretty much arbitrary places.
Nasal is a language that has no statements, it's all about EXPRESSIONS. So you can put things in pretty much arbitrary places.


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var do_something = func return 0;
var do_something = func return 0;
if (a==1) {
if (a==1) {
Line 216: Line 216:
In a boolean comparison, 1 always means "true" while 0 always means "false". For instance, ANY comparison with if x ==1 can be abbreviated to if (x), because the ==1 check is implictly done:
In a boolean comparison, 1 always means "true" while 0 always means "false". For instance, ANY comparison with if x ==1 can be abbreviated to if (x), because the ==1 check is implictly done:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var do_something = func return 0;
var do_something = func return 0;
( a and do_something() ) or print("failed");
( a and do_something() ) or print("failed");
Line 225: Line 225:
You can easily reduce the complexity of huge conditional (IF) statements, such as this one:
You can easily reduce the complexity of huge conditional (IF) statements, such as this one:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
if (a==1) function_a();
if (a==1) function_a();
else
else
Line 239: Line 239:
.. just by using the variable as a key (index) into a hash, so that you can directly call the corresponding function:
.. just by using the variable as a key (index) into a hash, so that you can directly call the corresponding function:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var mapping = {1:function_a, 2:function_b, 3:function_c, 4:function_d,5:function_e};
var mapping = {1:function_a, 2:function_b, 3:function_c, 4:function_d,5:function_e};
mapping[a] ();
mapping[a] ();
Line 250: Line 250:
Using this technique, you can reduce the complexity of huge conditional blocks. For example, consider this extract from weather_tile_management.nas:
Using this technique, you can reduce the complexity of huge conditional blocks. For example, consider this extract from weather_tile_management.nas:


<syntaxhighlight lang="php" line start="460">
<syntaxhighlight lang="nasal" line start="460">
if (code == "altocumulus_sky"){weather_tiles.set_altocumulus_tile();}
if (code == "altocumulus_sky"){weather_tiles.set_altocumulus_tile();}
else if (code == "broken_layers") {weather_tiles.set_broken_layers_tile();}
else if (code == "broken_layers") {weather_tiles.set_broken_layers_tile();}
Line 273: Line 273:
While this is not a very complex or huge block of code, it is an excellent example for very good naming conventions used already, because the consistency of naming variables and functions can pay off easily here, with just some very small changes, you can already reduce the whole thing to a hash lookup like this:
While this is not a very complex or huge block of code, it is an excellent example for very good naming conventions used already, because the consistency of naming variables and functions can pay off easily here, with just some very small changes, you can already reduce the whole thing to a hash lookup like this:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
weather_tiles["set_"~code~"_tile"]();  # naming convention
weather_tiles["set_"~code~"_tile"]();  # naming convention
</syntaxhighlight>
</syntaxhighlight>
Line 285: Line 285:
But these are very simple changes to do (just renaming these functions to match the existing conventions). When you do that, you can easily replace such huge IF statements and replace them with a single hash lookup and function call:
But these are very simple changes to do (just renaming these functions to match the existing conventions). When you do that, you can easily replace such huge IF statements and replace them with a single hash lookup and function call:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
hash[key] (arguments...);
hash[key] (arguments...);
</syntaxhighlight>
</syntaxhighlight>
Line 291: Line 291:
For example, consider:
For example, consider:


<syntaxhighlight lang="php">
<syntaxhighlight lang="nasal">
var makeFuncString = func(c) return tolower("set_"~c~"_tile");
var makeFuncString = func(c) return tolower("set_"~c~"_tile");
var isFunc = func(f) typeof(f)=='func';
var isFunc = func(f) typeof(f)=='func';

Navigation menu