rzel / tinypy

Automatically exported from code.google.com/p/tinypy
Other
0 stars 0 forks source link

'not' operator only works for numbers, not strings or lists #42

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
(I'm using SVN trunk.)

The 'not' operator only works for numbers.  The following code works as
expected and prints "OK":

  n = 0
  if not n:
    print('OK')

However, it doesn't work for empty dicts, lists, or strings.  The following
code fails to print "OK" for any of the tests:

  d = {}
  if not d:
    print('OK')
  l = []
  if not l:
    print('OK')
  s = ''
  if not s:
    print('OK')

Internally, the bytecode that gets generated is:
  NUMBER 0
  STRING "s"
  GGET
  EQ
(The responsible code is encode.py, line 248.)

---

I've only just started looking at tinypy and the internals.  If the
internal tp_bool() function (in ops.c) were to be exposed (say, as a
builtin named 'bool'), then 'not' could be implemented as:
  NUMBER 0
  STRING "s"
  GGET
  call bool() here
  EQ
...which would behave as expected.

I'm planning on submitting a patch to do this in the next few days.  I was
surprised to see that there isn't actually a bool type in tinypy.  What are
your views on adding it?  I am rather tempted to submit a patch for this as
well...

Original issue reported on code.google.com by kiwid...@gmail.com on 8 Apr 2009 at 12:15

GoogleCodeExporter commented 9 years ago
Attached is a patch to tinypy r143 which fixes the issues with the logical 
operators
and/or/not.  Changes:

 * renamed the arithmetic AND/OR/NOT opcodes and the tp_and/tp_or/tp_xor functions to
BITAND/BITOR/BITNOT and tp_bitwise_and/or/xor, to make it clear that they are 
not
logical operators.  
 * added a new IFN opcode, which is the inverse of the existing IF opcode.
 * added a new NOT opcode, which uses tp_bool() to determine the truthiness of the
operand and inverts it.
 * changed the bytecode generated for logical and/or to evaluate the left-hand
expression, check it for truthiness (using IF for and, IFN for or) and skip
evaluating the right-hand expression if needed [short-circuited].  The return 
value
of 'expr_a AND expr_b' is either expr_a or expr_b (not a logical 0 or 1), just 
like
in bigpy.
 * changed the bytecode generated for logical not to use the new NOT opcode.
 * exposed the internal tp_bool() function as the builtin 'bool'.

The behaviour of logical and/or/not is now consistent with both what is 
expected and
with bigpy.

Original comment by kiwid...@gmail.com on 9 Apr 2009 at 10:27

Attachments:

GoogleCodeExporter commented 9 years ago
I have verified this Issue and have merged kiwidrew's patch. plus, in
tinypy/tests.py, following line:

system(TINYPY+fname+' > tmp.txt')

is not right, since when running tests.py, the working directory is
$(TOPDIR)/tinypy/, while TINYPY is defined as './tinypy'. It should be changed 
to
right path of executable tinypy. Thus, I changed this statement as:

system("../build/tinypy "+fname+' > tmp.txt')

Maybe there's better way around this problem.

Some test cases is added in tests.py.

Original comment by ybc2084@gmail.com on 12 May 2009 at 4:28