richpl / PyBasic

Simple interactive BASIC interpreter written in Python
GNU General Public License v3.0
165 stars 45 forks source link

ongoto/gosub update #29

Closed RetiredWizard closed 3 years ago

RetiredWizard commented 3 years ago

The on gosub statement behaved in non standard way, this update adds the goto option as well as making the statement operate in a more typical fashion

richpl commented 3 years ago

Sorry, I've got some conflicts in basicparser.py, perhaps because of changes made by brickbots. Grateful if you could take a quick look, thanks

RetiredWizard commented 3 years ago

I've run my test program and this seems to be resolved and working.

RetiredWizard commented 3 years ago

Ugh, github doesn't like basicparser, I'll update and upload a new copy so the comparison is useful...

RetiredWizard commented 3 years ago

okay the diffs look clean now and no conflicts :)

RetiredWizard commented 3 years ago

I was a bit terse in my original description, I should have described exactly how the current on statement works and how this will change it, so....

The current on statement syntax is "on logical-expr gosub lineno". This statement will branch to the indicated lineno if the logical-expr evaluates to a True value.

This PR will modify the syntax to "on expr goto|gosub lineno1,lineno2,... and the operation will be modified such that program flow will be transferred to the line number in the list of line numbers corresponding to the ordinal value of the evaluated expr. The first line number corresponds with an expr value of 1. "expr" must evaluate to an integer value.

richpl commented 3 years ago

@RetiredWizard, any chance you could move some of your explanatory material from the informal grammar section into the main body of the documentation? Many thanks

RetiredWizard commented 3 years ago

@richpl I did add the description of the PR behavior of the ON statement to the README.MD file of this PR. Was there more information you'd like me to add?

richpl commented 3 years ago

@RetiredWizard, perhaps I'm going mad but it seems like ON - GOSUB/GOTO works by eveluating an ordinal now rather than a boolean expression, but this doesn't seem to be reflected in the README section on conditional branching (which I have just slightly updated by the way).

RetiredWizard commented 3 years ago

Okay, I've looked a little more carefully and I see there are multiple references to the on gosub behavior. I had updated the syntax description:

ON expression GOSUB|GOTO line-number1,line-number2,... - Conditional subroutine call|branch - Program flow will be transferred either through a GOSUB subroutine call or a GOTO branch to the line number in the list of line numbers corresponding to the ordinal value of the evaluated expr. The first line number corresponds with an expr value of 1. expr must evaluate to an integer value.

But I missed:

It is also possible to call a subroutine depending upon the result of a conditional expression using the ON-GOSUB statement. If the expression evaluates to true, then the subroutine is called, otherwise execution continues to the next statement without making the call:

I'll go ahead and post a PR with that text updated along with the updates for the new File I/O and RESTORE commands :)

richpl commented 3 years ago

Thanks @RetiredWizard! Looking at the code, the evaluation of conditional expressions appears to be missing. Only ordinal values are processed (I confirmed this by trying a simple proram, using a conditional now results in an error)

RetiredWizard commented 3 years ago

That's correct, I was unfamiliar with the conditional syntax and wasn't sure it was intentional. Most basic dialects I've encountered allow a GOSUB off of an IF statement so the conditional ON GOSUB didn't make sense to me. Now that I understand where PyBasic came from I can see how the syntax may have been appropriate.

If you feel that functionality is important I can look at generalizing the ON statement or I think a better option might be to generalize the IF statement to support statements other than GOTO including GOSUB.

richpl commented 3 years ago

At the moment only a GOTO is called from IF-THEN, so the only way to obtain the equivalent of a conditional call within ON-GOSUB is to use a GOTO to jump from an IF-THEN to a subroutine call on another line. Even by the standards of BASIC that's a bit nasty.

I will generalise the IF-THEN statement if you're happy to update the documentation to describe the behaviour of the revised ON-GOSUB|GOTO. Many thanks

RetiredWizard commented 3 years ago

The IF-THEN generalization is clearly more desirable but I did come up with another option using a Ternary and the ON-GOSUB. I threw an example in the documentation Pull Request. Feel free to axe that from the README it if you just want to go with an IF-THEN update :)