Hi, As Ross pointed out, forward labels can easily be implemented using recursive monadic bindings. There're a number of alternatives as to which underlying monad you want to use. Continuations are problematic, but this problem can be solved by using a simple state monad: please see the attached file for one possible implementation. The variables test1-test4 (see the end of the file) are bound to the compiled and interpreted versions of your examples compute112 and compute12. Note: I had to add a "return ()" to the end of your compute12 example, since mdo-notation requires the last generator to be an expression, just like an ordinary do-expression. You need a fairly recent version of Hugs to run this example, November 2002 release would do (try with -98). For ghc, you need the CVS version, or wait till the next release. As far as I know, no other implementation supports mdo, nor there are any plans for it. -Levent.
-----Original Message----- From: Mike Gunter [mailto:m@ryangunter.com] Sent: Friday, November 15, 2002 1:38 AM To: haskell@haskell.org Subject: Implementing forward refs in monadic assembler and interpreter
I need to implement an assembler and interpreter for a simple instruction set. For example, this code
\begin{code} compute112 = do { zero r1 ; zero r2 ; addi r2 3 -- loop three times ;topLoop <- label ; addi r1 4 ; addi r2 (-1) -- decrement loop counter ; brPositive r2 topLoop ; add r1 100 } \end{code}
would result in register r1 having a value 112. Without forward branches, the implementation is reasonably straightforward. The assembler can use a Monad with state and writer capabilities. The interpreter can use a continuation monad to implement branches and a state monad for the machine state.
However, forward branches make things harder. I'd like to be able to write something along the lines of:
\begin{code} compute12 = mdo { zero r1 ; zero r2 ; addi r2 3 -- loop three times ;topLoop <- label ; addi r1 4 ; addi r2 (-1) -- decrement loop counter ; brPositive r2 topLoop ; mov r3 r1 ; addi r3 (-10) -- !!! Forward branch: ; brPositive r3 out -- if r1 > 10 don't add 100 ; add r1 100 ;out <- label } \end{code}
but it's not clear to me how to implement it. I'd be willing to accept a somewhat less clean version (for instance, with more cumbersome forward references.)
Any help would be greatly appreciated.
thanks, mike _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell