World: r4wp
[#Red] Red language group
older newer | first last |
DocKimbel 13-Apr-2013 [6991x10] | THROW requires an integer! value. Such value represent the exception ID and is user-defined. After the resume from a caught exception, you can use SYSTEM/THROWN to read the passed exception ID and act accordingly (usually using a SWITCH dispatcher). |
Important thing to note: system/thrown needs to be manually reset, as the last thrown value will stay there if no exception occured. Such reset could be done before each call to a function that could generate an exception or after processing the thrown value. | |
I could have added a much more sophisticated system with a true CATCH function, but this would have made the implementation way more complex and would have taken a lot more time. As I need it only for Red's interpreter, I think this way should be enough and will be usable by other Red/System programmers to enhance their own code. | |
Thinking about it, it might be possible to allow an extended catch attribut with a integer value to specify the barrier value for catching exceptions (and avoid manual re-throwning), something like: foo: func [[catch 100]][...] would catch all thrown exceptions with a value <= 100 and let others pass up to caller. | |
What do you think about all this? | |
BTW, this exception system relies on stack frames unwinding, so it won't work for callbacks (CATCH attribut won't be accepted in callback functions anyway). | |
I've considered using a continuation approach for constant-time exception throwing (would also work from callbacks), but I didn't find a simple enough syntax for defining/using it without having to rely on CPS (Continuation-Passing Style) for every functions... See http://en.wikipedia.org/wiki/Continuation-passing_style | |
Another note: messing up with the stack (using push/pop) in a user-function is fine as long as you returned the stack clean before calling a function that could generate an exception. Failure to do so will result in a crash. It might be possible to make stack-unwinding for exception resistant to such cases, I will investigate that. | |
Exception handling code pushed. Have fun! ;) | |
(only IA-32 for now, will add ARM support in the next days) | |
Gregg 13-Apr-2013 [7001x2] | That sounds great Doc. I collected your comments into a file in %Red/. |
Hmm, shouldn't bar print KO in the second example, from your description? | |
DocKimbel 13-Apr-2013 [7003] | Nope, see first example. This might be a bit non/counter-intuitive, I will see if I can improve that. |
Gregg 13-Apr-2013 [7004] | Ah, I get it now. Yes, that wasn't obvious at first. |
DocKimbel 13-Apr-2013 [7005] | I won't be online tomorrow most of the day, will look into that and will upgrade the documentation tomorrow night. |
Gregg 13-Apr-2013 [7006x2] | So you don't check system/thrown in the func with [catch], correct? |
But in the func that *called* the func with [catch]. | |
DocKimbel 13-Apr-2013 [7008x2] | Right. |
I might adjust that tomorrow if possible to make it more intuitive. | |
PeterWood 13-Apr-2013 [7010] | Absolutely fabulous Nenad!!! |
Arnold 14-Apr-2013 [7011] | Good progress. Nice of you to sum it up Gregg, makes the comments a whole lot more readable. Filename is a bit awkward though: "esceptions" |
Gregg 14-Apr-2013 [7012x2] | Fixed. Thanks Arnold. |
I had a Spanish accent last night. | |
DocKimbel 15-Apr-2013 [7014] | Gregg, I've reconsidered the behavior of the [catch] function attribut, if I change it, some use cases become even less intuitive. For example, the single function use case (my first example above) performs quite intuitively. I think the vague non-intuitive feeling at the beginning comes from our habits with CATCH native in Rebol, after using Red/System's way a bit, that feeling just faded away. Anyway, if you have suggestions for improvements, it's the right time. |
Kaj 15-Apr-2013 [7015] | Doc, any idea how I can convert a string! passed into a routine! to UTF-8, or access a cached UTF-8 value? |
PeterWood 15-Apr-2013 [7016] | Kaj, can you use string/mold inside the routine to create a c-string! ? |
PeterWood 16-Apr-2013 [7017] | The answer is not you can't as mold doesnt output a UTF-8 string. |
DocKimbel 16-Apr-2013 [7018x8] | Kaj: cached UTF-8 string is available using str/cache if str is a red-string! value. |
Only small strings (< 64 bytes) are cached. | |
We haven't yet implemented UTF-8 encoding functions in the standard library. It will be done during the I/O implementation (unless you have a strong need for it, then I'll have a look at it). | |
After trying to use the new exception handling in the interpreter to implement EXIT/RETURN, I realized that the current behavior of the [catch] attribut is not suitable in a intensively recursive environment. So I had to change the moment the exceptions are caught to an earlier time. Now, it works like this: foo: does [ print "3" throw 100 print "KO" ] bar: func [[catch]][ print "2" foo print "4" ] print "1" bar will output: 1234 So, now the [catch] attribut resumes the execution at the current level, instead of the parent caller level like before. | |
The catch flags position on stack has been changed to a safer place, so it's now resistant to a "dirty" stack left by user code (unbalanced PUSH/POP actions at the exception raising point). | |
A [catch] flag will have no effect on exceptions launched from the same level (enables re-throwing exceptions). | |
EXIT and RETURN have been implemented for the interpreter too now. All related tests are now passing. An important fact to note, which differs from the Rebol way: EXIT and RETURN are dialect keywords in Red, not native functions. Both the compiler and the interpreter are processing them as part of function's body dialect. | |
@Ladislav, I know you don't care much about Red, but you might be pleased to see that some of your old propositions for Rebol found their way into Red. ;-) | |
Pekr 16-Apr-2013 [7026x2] | Can't speak for Ladislav, but maybe he is mostly busy with other stuff, so he'll wait, how Red turns out in the end :-) |
So, now as exceptions are working, my typical - what's next? :-) Dyn-lib emmiter? Contexts? IO? :-) | |
DocKimbel 16-Apr-2013 [7028] | Shared lib generation for Mac OS X and Linux. |
PeterWood 16-Apr-2013 [7029] | Does that include ARM? |
DocKimbel 16-Apr-2013 [7030] | Not sure if you mean for exceptions or shared libs, so: - Exceptions: I will push the upgraded ARM version in a few hours - Shared lib: yes, we will support it on ARM too |
PeterWood 16-Apr-2013 [7031] | I meant shared libs |
Ladislav 16-Apr-2013 [7032] | ...you might be pleased to see that some of your old propositions for Rebol found their way into Red - yes, that is great! |
Gregg 16-Apr-2013 [7033] | EXIT from a func exits the console. Is that intended? |
DocKimbel 16-Apr-2013 [7034x2] | N ope. |
The console needs a [catch] somewhere to avoid such exceptions reach global code and exit from console. | |
Gregg 16-Apr-2013 [7036x2] | Ahhh, makes sense. |
Should I log it as ain issue? | |
DocKimbel 16-Apr-2013 [7038] | No need, I will process tonight as I need to do a bit more work on exceptions (like documenting them). |
Gregg 16-Apr-2013 [7039] | OK. |
DocKimbel 16-Apr-2013 [7040] | Gregg, can't reproduce your console issue, here's the test code I'm using: red>> foo: func [][print "1" exit print "2"] == func [][print "1" exit print "2"] red>> foo 1 red>> |
older newer | first last |