Cheaterman / basic

A small BASIC interpreter written in Python using SLY.
MIT License
6 stars 3 forks source link

Combining comparison with expressions and print gives incorrect value to print. #3

Open Poikilos opened 3 weeks ago

Poikilos commented 3 weeks ago

Hello,

I'm working on this to get old games working (There is already QB64-PE, but chaining multiple files doesn't seem to work, and some old games tried to use DOS libraries that cannot be called from a 64-bit binary; I can do HLE instead, as in, call a modern MIDI library to play MIDI; I'm still implementing operations though, not graphics nor any kind of block statements yet). In my fork: https://github.com/hierosoft/bahle I added:

but I'm having trouble with combining comparison with expressions and print. Instead of "-1 " or " 0 " I am getting some value from some subset of the operands. I keep trying to learn precedence but there must be something I'm missing. I looked up how to make "x = a = b" work and set b to the result of the comparison, and learned I must change the precedence type of "=" to "nonassoc" so it isn't associated with itself and the context can determine whether it is being used as the assignment operator or the comparison operator. That test ((('a = 11', 'b = 10', 'x = a = b', 'Print x'), ' 0 '),) passes, but the ones regarding this issue do not, such as (The value after FIXME is the actual value printed, which is wrong):

        (('a = 10', 'b = 11', 'x = 21 > a + b', 'Print x'), ' 0 '), # FIXME: 1
        (('a = 10', 'b = 11', 'Print 21 > a + b'), ' 0 '), # FIXME: 1
        (('a = 10', 'b = 11', 'x = 21 > a + b - 1', 'Print x'), '-1 '),  # FIXME: 9
        (('a = 10', 'b = 11', 'Print 21 > a + b - 1'), '-1 '),  # FIXME: 9
        (('a = 10', 'b = 11', 'IF 21 > a + b THEN PRINT -1 ELSE PRINT 0'), ' 0 '), # FIXME: 1
        (('a = 10', 'b = 11', 'IF 21 > a + b - 1 THEN PRINT -1 ELSE PRINT 0', ), '-1 '),  # FIXME: 9

I've been trying different things for three days so far, but can't get this specific precedence working.

Is there any possibility you could help out?

I really appreciate the precision and code coverage in your project, and I tried to replicate your methodology. However, note one significant difference in my code: I use my new method "to_value" (which calls "evaluate" then changes each Variable to a Python type) for the inequality methods (any_gt_any, any_ge_any, etc) in the interpreter instead of calling only "evaluate" so I get real values so I can do the comparison and try to return Python values to the caller. I hope that's ok. If not, I'll need another solution.

Warnings:

WARNING: 6 shift/reduce conflicts
WARNING: 252 reduce/reduce conflicts
Cman's simple BASIC v0.1
2019 Cheaterman
bahle/bahle/basicinterpreter.py:134: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
Poikilos commented 3 weeks ago

SLY documentation at https://sly.readthedocs.io/en/latest/sly.html says to do precedence for inequalities like:

     precedence = (
          ('nonassoc', LESSTHAN, GREATERTHAN),  # Nonassociative operators
          ('left', PLUS, MINUS),
          ('left', TIMES, DIVIDE),
          ('right', UMINUS),            # Unary minus operator
     )