1. Extending Euphoria with Fallbacks
- Posted by David Cuny <euphoria_coder at HOTMAIL.COM> Mar 26, 2001
- 423 views
Some time ago, I ran across the Lua language: http://www.tecgraf.puc-rio.br/lua/ There's a short paper at: http://www.tecgraf.puc-rio.br/lua/spe.html One of the more interesting features is the handling of errors. It uses 'fallbacks', which catch run-time abnormal conditions. The programmer has the option of catching illegal operations, and choosing what to do about it. Errors fall into classes, such as: "arith" - bad type, overflow "concat" - bad type "index" - out of range, bad type "range" - bad range, bad type "test" - bad type "assign" - bad type I've embellished the list a bit, adding some classes that seem to make sense in Euphoria. For example, trying to add two sequences: ... "two" + "strings" This is an error in Euphoria, because the sequences are of differing lengths. If would trigger a fallback in the "arith" class, with three arguments: op = "add" arg1 = "this" arg2 = "that" The neat thing about fallbacks is that they won't *break* any existing code. After all, they are only triggered when there's a runtime error. In addition, the won't alter the runtime speed of Euphoria, if they are never used. It's pretty obvious that you could try to use fallbacks to trigger a shutdown routine, or possibly attempt to recover from errors. But you can do more than that: you can use them to extend the language. As an example of what can be done with callbacks, I've put together a few examples (untested of course): 1. Convert strings to numbers, and numbers to strings automatically. Example: integer i sequence s s = 123 i = "456" Code: function convert_to_string( object var, object expr ) sequence result -- storing number in sequence? if sequence( var ) and atom( expr ) then -- convert to string return sprintf( "%g", val ) -- storing sequence in number? elsif atom( val ) and sequence( var ) then -- attempt to convert to number result = value( var ) if result[1] = GET_SUCCESS then return result[2] end if end if -- default return call_func( oldFallback, {var, val} ) end function oldFallback = set_fallback("assign", routine_id("convert_to_type")) 2. Allow the use of strings as indexes. This assumes that the first element in the sequence contains a list of all the keys, such as: cat = { {"name","color"}, "chester", "orange" } Example: puts( 1, cat["name"] ) Code: function string_index(object s, object index) integer at if sequence( index ) then -- association list? if length( s ) = 2 then -- indexes stored at s[1], -- data in elements 2..end at = find( index, s[1] ) if at then return at+1 end if end if end if return call_func( oldFallback, {s, index} ) end if end function oldFallback = setfallback("index", routine_id("string_index")) 3. Automatically clip ranges past end of strings to match size of string: Example: sequence s s = "123456789" ? s[1..20] Code: function string_index(object s, object index ) if is_string( s ) and integer( iStart ) then end if return call_func( oldFallback1, {s, index} ) end function oldFallback1 = set_fallback("index", routine_id("string_index")) function string_range(object s, object iStart, object iEnd) if is_string( s ) and integer( iStart ) and integer( iEnd ) then if iStart > length( s ) then iStart = length( s ) end if if iEnd > length( iEnd ) then iEnd = length( iEnd ) end if return s[iStart..iEnd] end if return call_func( oldFallback2, {s, iStart, iEnd} ) end function oldFallback2 = set_fallback("range", routine_id("string_range")) 4. Make '=' behave like 'equal'. This requires two traps: one for when '=' is passes sequences of different sizes, and one for when 'if' is passed the comparison of two equal sized strings. Example: if "cat" = "dog" then ... Code: function string_if(object op, object test) if equal( op, "if" ) and sequence( test ) then -- sequence passed to 'if' statement return find( 0, arg ) end if return call_func( ifFallback, {op, arg} ) end function ifFallback = set_fallback("test", routine_id("string_if")) function string_eq( object op, object arg1, object arg2 ) if equal( op, "=" ) then -- make it behave like 'equal' return equal( arg1, arg2 ) end if return call_func( oldFallback, {op, arg1, arg2} ) end function oldFallback = setfallback("arith", routine_id("string_eq")) -- David Cuny
2. Re: Extending Euphoria with Fallbacks
- Posted by Kat <gertie at PELL.NET> Mar 26, 2001
- 401 views
On 26 Mar 2001, at 16:39, David Cuny wrote: > > Some time ago, I ran across the Lua language: > > http://www.tecgraf.puc-rio.br/lua/ > > There's a short paper at: > > http://www.tecgraf.puc-rio.br/lua/spe.html > > One of the more interesting features is the handling of errors. It > uses > 'fallbacks', which catch run-time abnormal conditions. The > programmer has > the option of catching illegal operations, and choosing what to do > about it. It also has: dostring (string [, chunkname]) Executes a given string as a Lua chunk. If there is any error executing the string, then dostring returns nil. Otherwise, it returns the values returned by the chunk, or a non-nil value if the chunk returns no values. The optional parameter chunkname is the ``name of the chunk'', used in error messages and debug information. Kat