Re: RosettaCode
- Posted by jimcbrown (admin) Jan 26, 2011
- 1889 views
It's not possible to turn the resulting compose-id into a routine-id (as far as I know).
This is what is preventing me from accepting this composition solution. The compose function must take two routine-ids as input, and produce one routine-id as output.*
Why does it have to be routine-ids, and not some other token like a c-func-id ?
However, it is possible to create a c-func-id from a compose-id that can be used with c_func().
This I would very much like to see.
Ok, ok, it can't be done in Euphoria. At least not Euphoria alone. A bottle of machine code glue is required...
Change the call_func()s in composed_call_back() to call_composition() and pass in compose-ids from the other compose into this compose() and it all works.
To turn only a single routine-id (or compose-id) into a c-func-id, pass NOT_USED as the second id.
include std/dll.e include std/machine.e constant mach = { -- 0 #55, -- 1 #89, #e5, -- 3 #83, #ec, #18, -- 6 #c7, #45, #f4, -- 9 #78, #56, #34, #12, -- 13 #c7, #45, #f8, -- 16 #21, #43, #65, #87, -- 20 #c7, #45, #fc, -- 23 #01, #f0, #01, #f0, -- 27 #83, #ec, #04, -- 30 #ff, #75, #08, -- 33 #ff, #75, #f8, -- 36 #ff, #75, #f4, -- 39 #8b, #45, #fc, -- 42 #ff, #d0, -- 44 #83, #c4, #10, -- 47 #c9, -- 48 #c3 -- 49 } function composed_call_back(integer a, integer b, integer c) return call_func(a, {call_func(b, {c})}) end function constant composed_call_back_mach = call_back(routine_id("composed_call_back")) public function compose(integer rid_a, integer rid_b) atom a a = allocate(length(mach)) poke(a, mach) poke4(a + 9, rid_a) poke4(a + 16, rid_b) poke4(a + 23, composed_call_back_mach) return define_c_func("", a, {C_ULONG}, C_ULONG) end function public function identity(object x) return x end function public constant NOT_USED = routine_id("identity") -- example code function ax(integer i) return i + 2 end function function bx(integer i) return i * 2 end function atom zx = compose(routine_id("ax"), routine_id("bx")) atom xz = compose(routine_id("bx"), routine_id("ax")) -- should print 4 ? c_func(zx, {1}) -- should print 6 ? c_func(xz, {1})