Increase a variable of type data Microprocessor

0

They ask me not to repeat this logic pC microprocesador + 1 I can not think of an idea of how to do it, I think they ask me to somehow autoincrement.

data Microprocesador = Microprocesador {
  nombre :: String,
  memory :: [Int],
  a :: Int,
  b :: Int,
  pC :: Int,
  mensajeDeError :: String
} deriving(Show)

type Intruccion = Microprocesador -> Microprocesador

nop :: Instruccion
nop microprocesador = microprocesador { pC = pC microprocesador + 1 }

lodv :: Int -> Instruccion
lodv valor microprocesador = microprocesador {
  a = a microprocesador + valor,
  pC = pC microprocesador + 1
}

swap :: Instruccion
swap microprocesador = microprocesador {
  b = a microprocesador,
  a = b microprocesador,
  pC = pC microprocesador + 1
}
    
asked by Rafael Olmos 18.04.2018 в 18:40
source

1 answer

1

You can create a function that is responsible for increasing the program counter, and another function that is responsible for executing the instructions.

Increase program counter

nextPC :: Instruccion
nextPC microprocesador = microprocesador { pC = pC microprocesador + 1 }

The nextPC function takes a microprocessor and returns the same microprocessor, but with the counter incremented.

Execute instruction

run :: Instruccion -> Instruccion
run = (.) nextPC

The run function takes one instruction and returns another instruction. What it does is to compose the instruction it receives with the function nextPC : this way it will first perform the logic of the instruction it receives, and then it will increase the program counter.

This function could also be written like this, if it's easier to see:

run :: Instruccion -> Microprocesador -> Microprocesador
run instruccion microprocesador = nextPC (instruccion microprocesador)

This makes it explicit that what the function receives is an instruction and a microprocessor, and that it executes the received instruction to the received microprocessor, and then increases the program counter with nextPC .

Define instructions

Since the program counter will be increased by the run function, you must modify your instructions. For example, the function nop will do nothing:

nop :: Instruccion
nop microprocesador = microprocesador

It returns what it receives, that is, it acts as the identity function id , so you can write it directly as:

nop :: Instruccion
nop = id

And the same with the rest of the functions:

lodv :: Int -> Instruccion
lodv valor microprocesador = microprocesador { a = a microprocesador + valor }

swap :: Instruccion
swap microprocesador = microprocesador { b = a microprocesador, a = b microprocesador }

Example

Now you can execute your instructions like:

ghci> let x = Microprocesador "a" [] 0 1 2 ""
ghci> run nop x
Microprocesador {nombre = "a", memory = [], a = 0, b = 1, pC = 3, mensajeDeError = ""}
    
answered by 21.04.2018 в 13:46