Open dideler opened 9 years ago
According to http://designpepper.com/blog/drips/truthy-and-falsy-values-in-javascript.html, there are only six falsy values in JS:
// Outputs: "Falsy."
logTruthiness(false);
// Outputs: "Falsy."
logTruthiness(null);
// Outputs: "Falsy."
logTruthiness(undefined);
// Outputs: "Falsy."
logTruthiness(NaN);
// Outputs: "Falsy."
logTruthiness(0);
// Outputs: "Falsy."
logTruthiness("");
The empty string is one of them, which explains why if "":
works in filbert. But the Python notation for empty list []
, tuple ()
, and dict {}
are all truthy in JS (whereas they're falsy in Python), so that's causing some issues.
I'm not entirely sure what the best approach to fix this is, especially since I'm new to lexical analysis. Should there be a special class for a Python list that holds an attribute of its truthiness?
Currently there is this
var pythonRuntime = exports.pythonRuntime = {
objects: {
list: function () {
var arr = [];
arr.push.apply(arr, arguments);
pythonRuntime.utils.convertToList(arr);
return arr;
}
}
}
It seems like parseExpression()
is called for any sequence in a conditional expression, so maybe the logic for handling the sequences should go in there? Or in parseMaybeAssign()
since parseExpression()
just calls that?
Good questions. I'm not sure offhand, but should have some time later this week to look into this.
@dideler Wrapping non-operator expressions in a bool()
call should fix this.
I don't think we need a specific truthiness value to the Python list object, since bool()
already evaluates correctly. The truthiness value would be read by bool()
if we had one.
For an if
test clause, you'd need to identify all the expressions that should be wrapped, and then generate the correct AST for a __pythonRuntime.functions.bool()
call. Unfortunately, you can't just wrap the whole test clause in a bool()
call.
If test clause:
https://github.com/differentmatt/filbert/blob/master/filbert.js#L1842
Generating AST for bool()
runtime call:
https://github.com/differentmatt/filbert/blob/master/filbert.js#L2189
Given this Python code:
if not []:
print('correct')
else:
print('incorrect')
if []:
print('incorrect')
else:
print('correct')
We'd generate this JavaScript code:
if (!__pythonRuntime.functions.bool(new __pythonRuntime.objects.list())) {
__pythonRuntime.functions.print('correct');
} else {
__pythonRuntime.functions.print('incorrect');
}
if (__pythonRuntime.functions.bool(new __pythonRuntime.objects.list())) {
__pythonRuntime.functions.print('incorrect');
} else {
__pythonRuntime.functions.print('correct');
}
The "Pythonic" way to check for an empty list is
if not my_list
and for a non-empty list isif my_list
.A temporary workaround for checking for empty lists is to check the length of the list:
Note that
bool()
evaluates lists correctly in filbert; the issue seems to just be with conditionals.