Immediate If
Monkey Forums/Monkey Programming/Immediate If
| ||
Quick Q. Does Monkey have Immediate If? Something like a pseudofunction or ternary operator, like such: Basic-style: Iif(expression, truepart, falsepart) C-style: expression ? truepart : falsepart |
| ||
From the language reference... "In addtion, a simple one line version of If is also supported:" If Expression [ Then ] Statement [ Else statement ] I'm not sure that returns a value. |
| ||
Ok, I tested it out:Function Main:Int() Local retVal:Int = 0; Local cond:Bool = false; 'retVal = (If cond Then 1 Else 9); ' doesn't work If cond Then retVal = 1 Else retVal = 9; Print(retVal); Return 0; End |
| ||
Kinda sloppy but you can also try something like this : |
| ||
The problem with that is that both results are evaluated regardless of the condition boolean. A c-style ternary operator won't do that. It will only evaluate the result it needs to. |
| ||
@Samah: In Monkey it's the same, only the required operator is evaluated, and it is clearer as it is shown in the form of program flow.If True Then Print("Hello") Else Print("Bye") Bye is never printed. So second expression is not evaluated. In this example: If False Then Print("Hello") Else Print("Bye") Hello is never printed. In other languages the IIF function does in fact evaluate all its parameters, wich is a lot unuseful. |
| ||
@Ziggy: I'm not talking about the one line If, I'm talking about the call to IIf. I can do a simple If like that in just about any language, but it's not the same as a proper ternary operator that you can inline in an equation. |
| ||
Of course! I was misreading your post |
| ||
Of course! I was misreading your post <3 I do however agree that a proper ternary operator would be fantastic. A coalesce operator would be great too. |
| ||
I do however agree that a proper ternary operator would be fantastic. A coalesce operator would be great too. +1 on coalesce. Ternary operation may break the flow of a Basic dialect for readability unless proper care is taken. ":" is already used for us here to define type-related stuff, so I'm wondering if "|" might be an acceptable alternative. I'm completely fine with "??" as a null-coalescing operator, however. |
| ||
I believe pipe is used for a bitwise OR. It'd probably have to be an actual keyword like Coa. |
| ||
oh, well I meant for the second half of the iif ternary operator. I guess an overload for "," could work too, as was done in CPL. As for null coalescense, I'd still be for "??" or a keyword token like OrIfNull ... |
| ||
I'm reading through the parser and Monkey uses top-down LL parsing with no backtracking and no look-ahead. I suggest you open parser.monkey to follow along. Keep in mind some of the differences between assignment statements and If statements. The right-hand-side of an assignment statement has to be an expression (not a statement). That's why IF blocks can't be used to return a value (not that they do anyways). So you couldn't do this: Identifier = Iif expression, truepart, falsepart because as soon as the parser hits the '=' token, it becomes an assignment operation that expects an expression on the right. How To I can think of two ways to get a ternary operator. The more complicated way involves extending the language all the way down to the LANG specific translators. That's a lot of work. The easier way is to translate the ternary operation into the existing IFStmt by generating an AssignStmt for both the Then/Else blocks. To get a ternary assignment operation, you would need to: * define the operator, something like =? (?= is taken) * modify ParseStmt() and add a case for "=?" in the Default section * create a ParseTernStmt() that generates a IfStmt, so that: Identifier =? (bool expression) ? trueexpression : falseexpression turns into IF bool expression THEN Identifier = trueexpression ELSE Identifier = falseexpression The IfStmt takes blocks for THEN and ELSE. You can manually add Statements to the blocks, specifically AssignStmt: thenStmt = new AssignStmt("=", IdentifierExpr, trueExpression); thenBlock.AddStmt(thenStmt); ... elseStmt & elseBlock _block.AddStmt New IfStmt( boolExpr,thenBlock,elseBlock ) Recursive ?: http://en.wikipedia.org/wiki/%3F:#.3F:_in_style_guidelines Once you're parsing the Ternary statement, then you can recursively parse the trueExpression and falseExpression for more ternary statements. ParseIfStmt() is a good example as 'ElseIf' is really a recursive IF block being pushed on the stack. That lets you do something like vehicle =? arg = 'B' ? bus : arg = 'A' ? airplane : arg = 'T' ? train : arg = 'C' ? car : arg = 'H' ? horse : feet; Coalesce The coalesce could be faked with the ternary operator looking for a special case token '??' Identifier =? theObject ?? theDefault translates into: IF theObject<>NULL THEN Identifier = theObject ELSE Identifier = theDefault The special case is that the ternary operator doesn't look for the ':' token or subsequent falseExpression. Obviously, this only works for nullable types. |