Strange behavior of ternary operator - grails

I observed strange behavior, in clean "test" application I have this simple controller:
(Grails 2.5.0, Java Oracle 8u45, GNU/Linux Debian 7)
package test
class DiController {
def ok() {
double d = 0d
int i = (int)d
def r = []
r << i
if (true) {
r << i
}
else {
r << d
}
if (false) {
r << i
}
else {
r << d
}
render r.toString()
}
def bug() {
double d = 0d
int i = (int)d
def r = []
r << i
r << (true ? i : d) // why Integer will be serialized like Double ?
r << (false ? i : d)
render r.toString()
}
}
/test/di/ok renders [0, 0, 0.0], but /test/di/bug renders [0, 0.0, 0.0].
It seems that ternary operator converts the result value, but I haven't observed such conversion in Groovy console. Is this Grails specific?
(Graeme Rocher marked this as "not a bug" here: https://github.com/grails/grails-core/issues/8994, so it should be known behavior)
EDIT: I used older Groovy (1.8.6) for tests "out of Grails", Groovy 2.4.3 has described behavior (gives [0, 0.0, 0.0]), so it has really nothing to do with Grails.

I believe that's because Groovy tries to find a common ground for incompatible types. This is an example of various ternary operators uses:
println ((true ? (0 as Integer) : (0.0 as Float)).class)
println ((true ? (0 as Float) : (0.0 as Double)).class)
println ((true ? (0 as Integer) : (0 as Long)).class)
println ((true ? (0 as Integer) : (0 as Byte)).class)
and that's how Groovy compiles this into Java
var1[1].callCurrent(this, var1[2].callGetProperty(true?(Float)ScriptBytecodeAdapter.castToType((Integer)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Integer.class), Float.class):(Float)ScriptBytecodeAdapter.asType($const$0, Float.class)));
var1[3].callCurrent(this, var1[4].callGetProperty(true?(Double)ScriptBytecodeAdapter.castToType((Float)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Float.class), Double.class):(Double)ScriptBytecodeAdapter.asType($const$0, Double.class)));
var1[5].callCurrent(this, var1[6].callGetProperty(true?(Long)ScriptBytecodeAdapter.castToType((Integer)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Integer.class), Long.class):(Long)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Long.class)));
var1[7].callCurrent(this, var1[8].callGetProperty(true?(Integer)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Integer.class):(Integer)ScriptBytecodeAdapter.castToType((Byte)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Byte.class), Integer.class)));
In all cases it does a lot of type conversions just to agree both true/false result branch and make them return the same type. Surprisingly this is the case only for numerical values. Other values are treated differently.
println ((true ? ("s") : (0 as Byte)).class)
println ((false ? ("s") : (0 as Byte)).class)
println ((true ? (new Date()) : (0 as Byte)).class)
gets translated into Java like
var1[9].callCurrent(this, var1[10].callGetProperty(true?"s":(Byte)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Byte.class)));
var1[11].callCurrent(this, var1[12].callGetProperty(false?"s":(Byte)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Byte.class)));
var1[13].callCurrent(this, var1[14].callGetProperty(true?var1[15].callConstructor(Date.class):(Byte)ScriptBytecodeAdapter.asType(Integer.valueOf(0), Byte.class)));
It doesn't answer why that happens but answers how that happened. At least I hope so.

Related

How to create inline if without else case

Does Dart support a syntax to have an inline if without an else case? I sometimes find myself in a situation to create a flutter layout where this might be really helpful
new Row(children: <Widget>[
new Text(item.name),
item.name2 != null ? new Text(item.name2) : new Container(),
]
In this example the empty container is unnecessary so I was hoping for something like this:
new Row(children: <Widget>[
new Text(item.name),
item.name2 != null ? new Text(item.name2),
]
there is no inline if without else
but in your case you're using if only to check only if it's null or not
dart have :
x = someVar ?? 0
here dart checks if someVar == null ? if true sets x value to 0, if false sets it to someVar value
but flutter will never let you add null to it's widget tree, so your can't use it in row/col
You can do this:
myVar == null ? 0 : myVar
If myVar is null then is 0, else then myVar
If you need to call a function you can use like this:
String s; //null
s == null ? print("if shorthand working") : {};
For variable assignment:
String c = "not null value";
String b; //null
var a = b ?? c;
Now a = c.
Visual Studio Code tip: add this to ignore linting for a line
// ignore: unnecessary_statements
In general, the "inline if" can be written in darts as follows:
<condition> ? <expression 1> : <expression 2>
So that if <condition> evaluates to True, then <expression 1> is returned and otherwise <expression 2>.
For example:
result = myVar == null ? 0 : myVar ;
// if myVar is null -> result = 0
// if myVar is not null -> result = myVar
There is actually plans to include a similar feature into the Dart language itself.
For a preview of how it would look like, take a look at this article by Remi
https://medium.com/flutter-community/quick-tip-sync-a-taste-of-the-future-9be4cd6993f4
And some accompanying Github issues
https://github.com/flutter/flutter/issues/17862
https://github.com/dart-lang/language/issues/47
https://github.com/dart-lang/language/issues/78

Parsing an integer and HEX value in Ragel

I am trying to design a parser using Ragel and C++ as host langauge.
There is a particular case where a parameter can be defined in two formats :
a. Integer : eg. SignalValue = 24
b. Hexadecimal : eg. SignalValue = 0x18
I have the below code to parse such a parameter :
INT = ((digit+)$incr_Count) %get_int >!(int_error); #[0-9]
HEX = (([0].'x'.[0-9A-F]+)$incr_Count) %get_hex >!(hex_error); #[hexadecimal]
SIGNAL_VAL = ( INT | HEX ) %/getSignalValue;
However in the above defined parser command, only the integer values(as defined in section a) gets recognized and parsed correctly.
If an hexadecimal number(eg. 0x24) is provided, then the number gets stored as ´0´ . There is no error called in case of hexadecimal number. The parser recognizes the hexadecimal, but the value stored is '0'.
I seem to be missing out some minor details with Ragel. Has anyone faced a similar situation?
The remaning part of the code :
//Global
int lInt = -1;
action incr_Count {
iGenrlCount++;
}
action get_int {
int channel = 0xFF;
std::stringstream str;
while(iGenrlCount > 0)
{
str << *(p - iGenrlCount);
iGenrlCount--;
}
str >> lInt; //push the values
str.clear();
}
action get_hex {
std::stringstream str;
while(iGenrlCount > 0)
{
str << std::hex << *(p - iGenrlCount);
iGenrlCount--;
}
str >> lInt; //push the values
}
action getSignalValue {
cout << "lInt = " << lInt << endl;
}
It's not a problem with your FSM (which looks fine for the task you have), it's more of a C++ coding issue. Try this implementation of get_hex():
action get_hex {
std::stringstream str;
cout << "get_hex()" << endl;
while(iGenrlCount > 0)
{
str << *(p - iGenrlCount);
iGenrlCount--;
}
str >> std::hex >> lInt; //push the values
}
Notice that it uses str just as a string buffer and applies std::hex to >> from std::stringstream to int. So in the end you get:
$ ./a.out 245
lInt = 245
$ ./a.out 0x245
lInt = 581
Which probably is what you want.

Dart - NumberFormat

Is there a way with NumberFormat to display :
'15' if double value is 15.00
'15.50' if double value is 15.50
Thanks for your help.
Actually, I think it's easier to go with truncateToDouble() and toStringAsFixed() and not use NumberFormat at all:
n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
So for example:
main() {
double n1 = 15.00;
double n2 = 15.50;
print(format(n1));
print(format(n2));
}
String format(double n) {
return n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
}
Prints to console:
15
15.50
Edit: The solution posted by Martin seens to be a better one
I don't think this can be done directly. You'll most likely need something like this:
final f = new NumberFormat("###.00");
String format(num n) {
final s = f.format(n);
return s.endsWith('00') ? s.substring(0, s.length - 3) : s;
}
Not very easily. Interpreting what you want as printing zero decimal places if it's an integer value and precisely two if it's a float, you could do
var forInts = new NumberFormat();
var forFractions = new NumberFormat();
forFractions.minimumFractionDigits = 2;
forFractions.maximumFractionDigits = 2;
format(num n) =>
n == n.truncate() ? forInts.format(n) : forFractions.format(n);
print(format(15.50));
print(format(15.0));
But there's little advantage in using NumberFormat for this unless you want the result to print differently for different locales.
Maybe you don't want use NumberFormat:
class DoubleToString {
String format(double toFormat) {
return (toFormat * 10) % 10 != 0 ?
'$toFormat' :
'${toFormat.toInt()}';
}
}
A variant of double value formatting:
void main (){
final n1 = 15.00;
final n2 = 15.50;
print(format(n1));
print(format(n2));
}
String format(double n) {
final fraction = n - n.toInt();
if (fraction == 0.0) {
return n.toString();
}
var twoDigitFraction = (fraction * 100).truncateToDouble().toInt();
return '${n.toInt()}.$twoDigitFraction';
}
This will work.
main() {
double n1 = 15.00;
double n2 = 15.50;
print(_formatDecimal(n1));
print(_formatDecimal(n2));
}
_formatDecimal(double value) {
if (value % 1 == 0) return value.toStringAsFixed(0).toString();
return value.toString();
}
Output:
15
15.5
An alternate solution, working on the string output of NumberFormat:
final f = NumberFormat("###.00");
print(f.format(15.01).replaceAll('.00', ''));
print(f.format(15.00).replaceAll('.00', ''));
Here is a flexible function that nicely rounds and removes trailing zeros after the decimal point to resolve double's imperfections. This doesn't handle the strictly 0 or 2 decimal points scenario from the question, but rather is a more general formatting for double numbers that may be useful for others to consider.
The verbose value can be changed to fit precision needs.
void main() {
for (double i = 0; i < 10; i += 0.3) {
print(i);
print(_formatDouble(i));
}
}
//Creates nicely formatted number string without trailing decimal zeros.
String _formatDouble(double value) {
//this also rounds (so 0.8999999999999999 becomes '0.9000')
var verbose = value.toStringAsFixed(4);
var trimmed = verbose;
//trim all trailing 0's after the decimal point (and the decimal point if applicable)
for (var i = verbose.length - 1; i > 0; i--) {
if (trimmed[i] != '0' && trimmed[i] != '.' || !trimmed.contains('.')) {
break;
}
trimmed = trimmed.substring(0, i);
}
return trimmed;
}
prints output:
0
0
0.3
0.3
0.6
0.6
0.8999999999999999
0.9
1.2
1.2
1.5
1.5
1.8
1.8
2.1
2.1
2.4
2.4
2.6999999999999997
2.7
2.9999999999999996
3
3.2999999999999994
3.3
3.599999999999999
3.6
3.899999999999999
3.9
4.199999999999999
4.2
4.499999999999999
4.5
4.799999999999999
4.8
5.099999999999999
5.1
5.399999999999999
5.4
5.699999999999998
5.7
5.999999999999998
6
6.299999999999998
6.3
6.599999999999998
6.6
6.899999999999998
6.9
7.1999999999999975
7.2
7.499999999999997
7.5
7.799999999999997
7.8
8.099999999999998
8.1
8.399999999999999
8.4
8.7
8.7
9
9
9.3
9.3
9.600000000000001
9.6
9.900000000000002
9.9

Z3 - How to extract variables from a given formula?

I'm using Z3 C++ API (Version 4.3.1) and I want to extract variables of a formula (An object of type expr). I've found a similar question but it is in Z3py. I am wonder if there is a method in Z3 C/C++ API to extract variables from expr object. Thanks!
For example (some details omitted):
expr fs = implies(x + y == 0, z * x < 15);
std::vector<expr> varlist = get_vars(fs);
Then varlist should contain x,y,z.
The C++ example in the distribution (examples/c++/example.cpp) shows a sample visitor pattern.
It is very simplistic, but will give the idea.
I repeat it here below:
void visit(expr const & e) {
if (e.is_app()) {
unsigned num = e.num_args();
for (unsigned i = 0; i < num; i++) {
visit(e.arg(i));
}
// do something
// Example: print the visited expression
func_decl f = e.decl();
std::cout << "application of " << f.name() << ": " << e << "\n";
}
else if (e.is_quantifier()) {
visit(e.body());
// do something
}
else {
assert(e.is_var());
// do something
}
}
The visitor function can be improved by using
a cache of previously visited expressions because in general Z3 uses shared sub-expressions.
This is similar to the Python example.
Hope this helps

PEG for Python style indentation

How would you write a Parsing Expression Grammar in any of the following Parser Generators (PEG.js, Citrus, Treetop) which can handle Python/Haskell/CoffeScript style indentation:
Examples of a not-yet-existing programming language:
square x =
x * x
cube x =
x * square x
fib n =
if n <= 1
0
else
fib(n - 2) + fib(n - 1) # some cheating allowed here with brackets
Update:
Don't try to write an interpreter for the examples above. I'm only interested in the indentation problem. Another example might be parsing the following:
foo
bar = 1
baz = 2
tap
zap = 3
# should yield (ruby style hashmap):
# {:foo => { :bar => 1, :baz => 2}, :tap => { :zap => 3 } }
Pure PEG cannot parse indentation.
But peg.js can.
I did a quick-and-dirty experiment (being inspired by Ira Baxter's comment about cheating) and wrote a simple tokenizer.
For a more complete solution (a complete parser) please see this question: Parse indentation level with PEG.js
/* Initializations */
{
function start(first, tail) {
var done = [first[1]];
for (var i = 0; i < tail.length; i++) {
done = done.concat(tail[i][1][0])
done.push(tail[i][1][1]);
}
return done;
}
var depths = [0];
function indent(s) {
var depth = s.length;
if (depth == depths[0]) return [];
if (depth > depths[0]) {
depths.unshift(depth);
return ["INDENT"];
}
var dents = [];
while (depth < depths[0]) {
depths.shift();
dents.push("DEDENT");
}
if (depth != depths[0]) dents.push("BADDENT");
return dents;
}
}
/* The real grammar */
start = first:line tail:(newline line)* newline? { return start(first, tail) }
line = depth:indent s:text { return [depth, s] }
indent = s:" "* { return indent(s) }
text = c:[^\n]* { return c.join("") }
newline = "\n" {}
depths is a stack of indentations. indent() gives back an array of indentation tokens and start() unwraps the array to make the parser behave somewhat like a stream.
peg.js produces for the text:
alpha
beta
gamma
delta
epsilon
zeta
eta
theta
iota
these results:
[
"alpha",
"INDENT",
"beta",
"gamma",
"INDENT",
"delta",
"DEDENT",
"DEDENT",
"epsilon",
"INDENT",
"zeta",
"DEDENT",
"BADDENT",
"eta",
"theta",
"INDENT",
"iota",
"DEDENT",
"",
""
]
This tokenizer even catches bad indents.
I think an indentation-sensitive language like that is context-sensitive. I believe PEG can only do context-free langauges.
Note that, while nalply's answer is certainly correct that PEG.js can do it via external state (ie the dreaded global variables), it can be a dangerous path to walk down (worse than the usual problems with global variables). Some rules can initially match (and then run their actions) but parent rules can fail thus causing the action run to be invalid. If external state is changed in such an action, you can end up with invalid state. This is super awful, and could lead to tremors, vomiting, and death. Some issues and solutions to this are in the comments here: https://github.com/dmajda/pegjs/issues/45
So what we are really doing here with indentation is creating something like a C-style blocks which often have their own lexical scope. If I were writing a compiler for a language like that I think I would try and have the lexer keep track of the indentation. Every time the indentation increases it could insert a '{' token. Likewise every time it decreases it could inset an '}' token. Then writing an expression grammar with explicit curly braces to represent lexical scope becomes more straight forward.
You can do this in Treetop by using semantic predicates. In this case you need a semantic predicate that detects closing a white-space indented block due to the occurrence of another line that has the same or lesser indentation. The predicate must count the indentation from the opening line, and return true (block closed) if the current line's indentation has finished at the same or shorter length. Because the closing condition is context-dependent, it must not be memoized.
Here's the example code I'm about to add to Treetop's documentation. Note that I've overridden Treetop's SyntaxNode inspect method to make it easier to visualise the result.
grammar IndentedBlocks
rule top
# Initialise the indent stack with a sentinel:
&{|s| #indents = [-1] }
nested_blocks
{
def inspect
nested_blocks.inspect
end
}
end
rule nested_blocks
(
# Do not try to extract this semantic predicate into a new rule.
# It will be memo-ized incorrectly because #indents.last will change.
!{|s|
# Peek at the following indentation:
save = index; i = _nt_indentation; index = save
# We're closing if the indentation is less or the same as our enclosing block's:
closing = i.text_value.length <= #indents.last
}
block
)*
{
def inspect
elements.map{|e| e.block.inspect}*"\n"
end
}
end
rule block
indented_line # The block's opening line
&{|s| # Push the indent level to the stack
level = s[0].indentation.text_value.length
#indents << level
true
}
nested_blocks # Parse any nested blocks
&{|s| # Pop the indent stack
# Note that under no circumstances should "nested_blocks" fail, or the stack will be mis-aligned
#indents.pop
true
}
{
def inspect
indented_line.inspect +
(nested_blocks.elements.size > 0 ? (
"\n{\n" +
nested_blocks.elements.map { |content|
content.block.inspect+"\n"
}*'' +
"}"
)
: "")
end
}
end
rule indented_line
indentation text:((!"\n" .)*) "\n"
{
def inspect
text.text_value
end
}
end
rule indentation
' '*
end
end
Here's a little test driver program so you can try it easily:
require 'polyglot'
require 'treetop'
require 'indented_blocks'
parser = IndentedBlocksParser.new
input = <<END
def foo
here is some indented text
here it's further indented
and here the same
but here it's further again
and some more like that
before going back to here
down again
back twice
and start from the beginning again
with only a small block this time
END
parse_tree = parser.parse input
p parse_tree
I know this is an old thread, but I just wanted to add some PEGjs code to the answers. This code will parse a piece of text and "nest" it into a sort of "AST-ish" structure. It only goes one deep and it looks ugly, furthermore it does not really use the return values to create the right structure but keeps an in-memory tree of your syntax and it will return that at the end. This might well become unwieldy and cause some performance issues, but at least it does what it's supposed to.
Note: Make sure you have tabs instead of spaces!
{
var indentStack = [],
rootScope = {
value: "PROGRAM",
values: [],
scopes: []
};
function addToRootScope(text) {
// Here we wiggle with the form and append the new
// scope to the rootScope.
if (!text) return;
if (indentStack.length === 0) {
rootScope.scopes.unshift({
text: text,
statements: []
});
}
else {
rootScope.scopes[0].statements.push(text);
}
}
}
/* Add some grammar */
start
= lines: (line EOL+)*
{
return rootScope;
}
line
= line: (samedent t:text { addToRootScope(t); }) &EOL
/ line: (indent t:text { addToRootScope(t); }) &EOL
/ line: (dedent t:text { addToRootScope(t); }) &EOL
/ line: [ \t]* &EOL
/ EOF
samedent
= i:[\t]* &{ return i.length === indentStack.length; }
{
console.log("s:", i.length, " level:", indentStack.length);
}
indent
= i:[\t]+ &{ return i.length > indentStack.length; }
{
indentStack.push("");
console.log("i:", i.length, " level:", indentStack.length);
}
dedent
= i:[\t]* &{ return i.length < indentStack.length; }
{
for (var j = 0; j < i.length + 1; j++) {
indentStack.pop();
}
console.log("d:", i.length + 1, " level:", indentStack.length);
}
text
= numbers: number+ { return numbers.join(""); }
/ txt: character+ { return txt.join(""); }
number
= $[0-9]
character
= $[ a-zA-Z->+]
__
= [ ]+
_
= [ ]*
EOF
= !.
EOL
= "\r\n"
/ "\n"
/ "\r"

Resources