The following code now works: /////////////// proc mythrow[T] : T = "throw $1;"; const exn : int = "_exn";
try var x = 1; mythrow 20; x = 10; catch int :> x = 2; println$ "Exception " + str exn; endtry println$ x; ///////////////////// ~/felix>flx --test=build/release ex Exception 20 2 ///////////////// Note: this is experimental DO NOT USE in production code. For playing only. It generates the "obvious" C++: try { ....} catch (int &_exn) { .. } Note temporary hack: the exception caught is named _exn. This is mainly because I couldn't figure out how to allow the user to name it: it can be done, and the syntax will probably change to catch (x:int) => .... The catch thing is basically a procedure, but it isn't declared in the normal way, so I have to actually think about how the variable gets a name. The implementation is a hack: try just generates "try {" and endtry just generates "}" and catch generates "} catch (" + type + " &_exn) {": naming the variable should imply it has a scope from the start of the catch handler to its end, but the implementation doesn't make any scope. C++ does though! Ok, so: you can NOT use this construction if there is a supervisor call inside the try block. Supervisor calls work by returning control, which implies there must not be any machine stack. After the call we resume, and you can't jump into the middle of a block in C++. It's worse though: you cannot use this construction if you call a procedure closure in the try block either, because that also works by returning control. However this doesn't mean you can't call a procedure in there, it just means the procedure has to be inlined. Most directly called procedures will be inlined unless they're too big, the caller is too big, or the procedure is recursive. Procedures called via closures can't be inlined. Furthermore, "throws" from procedures cannot propagate to their callers, because procedure calls don't use the machine stack. You can throw from inside a function though, since they do. It's rather unfortunate, but in Felix you have to KNOW what the implementation of code will be. Inlined or not matters. Functions also get inlined, and what's more, many of them are actually converted to procedures (by passing a pointer to the result variable, and replacing return x with *result = x;) The spaghetti stack is a way to swap stacks quickly, without having to swap machine stacks (which cannot be done portably other than by using threads). The machine stack is used for functions, for speed and C compatibility. The resulting system is a hybrid with somewhat difficult characteristics, but there's no real alternative if we want to generate C++ which can also use existing C++ code. The right way to handle this is probably to use the type system to prevent incorrect guesses as to the final optimised implementation: optimisation shouldn't change the semantics of correct code, but it does allow technically "incorrect" code to work, which is bad because down the track it may fail for unknown reasons. I dislike exceptions. But it's reality that C++ code such as library functions might throw them in circumstances where we actually want to catch them rather than terminate. Also, they're useful for quick exits. For example searching an array or list for a value using an iter function should be able to stop as soon as it succeeds. Anyhow, the RULE for proper use of exceptions is to keep them localised, and make sure the try block contains simple algorithmic code. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language