Menu

#55 TRY/CATCH, ONERROR and some other stuff[r889]

Unstable_(example)
open
None
5
2017-08-06
2017-08-06
No

Hi Jim,

This update fix some issues and add some features:


OnError - can be used inside a Try / Catch / End Try statement

Remove the limitation: You may not execute an OnError statement inside a Try / Catch / End Try statement.
OffError statement can be used safely anywhere, even in a Try / Catch / End Try statement.


Calling a subroutine without arguments

From now on, it is no longer possible to call subroutines without parentheses (to avoid confusions with variables and to keep the same behaviour with functions).

draw =1
call draw

Before: call sub
Now works only: call sub()


OnError: (re)add the ability to use a subroutine for error trapping

It is safe (in fact it is safer than ONERROR label)

ONERROR mysub()

To do this, the subroutine must have no arguments. Otherwise the user will receive the appropriate error.

ONERROR mysub(1)
SUBROUTINE mysub(a)
END SUBROUTINE

COMPILE ERROR on line 1: Cannot pass arguments to a SUBROUTINE used by ONERROR statement.

ONERROR mysub()
SUBROUTINE mysub(a)
END SUBROUTINE

ERROR on line 1: SUBROUTINE 'mysub' expects arguments and therefore can not be used by ONERROR statement.

Documentation should be like this:

OnError (Statement)

Format

onerror label
onerror subroutine()

Description

Execute a GOSUB at the specified label or call the specified subroutine when a runtime error occurs.
In order to use a subroutine it must have no argument.
The difference between the two ways of using the ONERROR statement is that if a label is used, all variables are shared with the called code and the program control may be resumed at the next statement with a Return statement in the called code.
When it is used with a subroutine all variables used within the subroutine, that have not been previously declared as Global, will be local to the subroutine and will not change the values in the calling code. In this case the program control will be returned when a Return statement is executed in subroutine or when the End Subroutine statement ise reached. (See more: [[Subroutine|Subroutine]])

Error traps are kept in a stack so that the last defined trap, that has not been removed with an OffError will be the active one.


drop OP_ARGUMENTCOUNTTEST

For each SUBROUTINE/FUNCTION the required number of arguments is stored at compiling time.
So it's simpler and faster to check if the number of arguments match with SUBROUTINE/FUNCTION definition.
This is actually happening even before the SUBROUTINE/FUNCTION call.
This is needed also by ONERROR sub() to check the number of required arguments BEFORE using it in this syntax.


Fix crash when number of symbols used by program is greater than 2000

If you use a large program that use a number of symbols greater than 2000 it will not crash anymore.


TRY/CATCH: Correct/clean jump to CATCH code

r=1
try
call sub()
catch
print r #r 1-current recurse level, 2-we are still in subroutine
endtry
end


subroutine sub()
r=2
g=0/0
end subroutine

Before: program prints "2" because the program is still in subroutine level (never return).
After: program prints "1" - the program control is returned to TRY/CATCH level


TRY/CATCH: no more messing ONERROR with TRY/CATCH

onerror err
goto jump
try
jump:
    print "we are in the middle of try part"
catch
    print "catch it!"
endtry
print 0/0
end

err:
print "error!"
return

Before:

we are in the middle of try part
ERROR on line 9: Division by zero.

After: correct result because TRY/CATCH and ONERROR do not share the same stack anymore

we are in the middle of try part
error!
0

TRY/CATCH: correctly delete nested TRY/CATCH when CATCH is encounted

try
    try
        print "we are in second try"
        goto jump
    catch
        print "catch it (second)!"
    end try
jump:
catch
    print "catch it (first)!"
end try

print 0/0
end

print "error!"
return

Before:

we are in second try
catch it (first)!
ERROR on line 13: Division by zero.

After: correct result because each CATCH know which is the matching TRY

we are in second try
ERROR on line 13: Division by zero.

TRY/CATCH: fix outdated TRY/CATCH traps

call sub()
a=0/0
end

subroutine sub()
    try
        print "TRY in subroutine"
        return
    catch
        print "never here!"
    end try
    print "never here too!"
end subroutine

Before:

TRY in subroutine
never here!
never here too!

After: correct behaviour because the TRY/CATCH trap from subroutine is removed when subroutine returns

TRY in subroutine
ERROR on line 2: Division by zero.

How the code looks

try
print 1
catch
print 2
endtry

Before:

00000000 OP_CURRLINE          1
00000002 OP_ONERRORCATCH      0000000e ___0_0
00000004 OP_CURRLINE          2
00000006 OP_PUSHINT           1
00000008 OP_PRINTN           
00000009 OP_CURRLINE          3
0000000b OP_OFFERROR         
0000000c OP_GOTO              00000016 ___1_0
0000000e OP_OFFERROR         
0000000f OP_CURRLINE          4
00000011 OP_PUSHINT           2
00000013 OP_PRINTN           
00000014 OP_CURRLINE          5
00000016 OP_CURRLINE          6

After:

00000000 OP_CURRLINE          1
00000002 OP_ONERRORCATCH      0000000d ___0_0
00000004 OP_CURRLINE          2
00000006 OP_PUSHINT           1
00000008 OP_PRINTN           
00000009 OP_CURRLINE          3
0000000b OP_OFFERRORCATCH     00000014 ___1_0
0000000d OP_CURRLINE          4
0000000f OP_PUSHINT           2
00000011 OP_PRINTN           
00000012 OP_CURRLINE          5

What is new is OP_OFFERRORCATCH label - which close try/catch trap and jump over the CATCH part.


Add compiler error message: "Out of memory"

Discussion


Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.