Home > Mobile >  How to write functions for data type class
How to write functions for data type class

Time:11-06

I have a data type:

data Instr =
        LOADI Val|
        LOAD Val|
        ADD Val|
        STORE Val | 
        JMP Val|
        JMPLESS Val|
        JMPGE Val
        deriving (Eq, Read, Show)

and a function iexec that takes an instruction and a configuration to perform a process and returns the new configuration.

iexec :: Instr -> Config -> Config

where Config is defined as: type Config = (Int, [*], [*]) An example is LOADI which takes value Val (an Integer) and loads it onto a stack, with the config argument giving the information on the stack. It would look something like this in GHCI:

>iexec (LOADI 5) (0, empty, [])
> (1, fromList[], [5])

where the program counter increases to 1, and 5 is added to the stack (I'm not sure what the fromList[] means, any explanation for that would be appreciated). I'm also not sure if my config type declaration is correct.

How would I finish the iexec function to allow this to work? Anything to point me in the right direction would be appreciated. Thank you.

CodePudding user response:

This looks like an exercise based on the book Concrete Semantics. This language appears on page 96. From this description there, it looks like the configuration is a combination of a program counter, a "memory" (i.e., list of integer-indexed variables), and a stack.

The Haskell type:

type Config = (Int, [*], [*])

is "interesting", and it's certainly not the type you want. Since all values in this language are Vals, you instead want:

type Config = (Int, [Val], [Val])

which says that the configuration is a an integer program counter, a memory that's a list of Vals and a stack that's another list of Vals.

The instruction LOADI loads an "immediate" value into the stack, so its implementation is:

iexec (LOADI n) (pc, mem, stk) = (pc 1, mem, n:stk)

That is, it bumps the program counter, doesn't change the memory, and pushes the value n onto the stack.

The instruction LOAD fetches the value of a variable from memory and pushes it onto the stack. Assuming that type Val = Int, its implementation is:

iexec (LOAD i) (pc, mem, stk) = (pc 1, mem, n:stk)
    where n = mem !! i

It's the same as LOADI except the pushed value is looked up in memory with mem !! i.

Hopefully you can figure out the rest. If you need hints, an ML implementation of iexec is given on page 97 of the above book.

Note that your definition of ADD looks wrong, as that instruction isn't supposed to take an argument. It just adds the top two values of the stack together, presumably putting the answer in place of the original two values.

  • Related