How to resolve the algorithm Subleq step by step in the Haskell programming language

Published on 7 June 2024 03:52 AM

How to resolve the algorithm Subleq step by step in the Haskell programming language

Table of Contents

Problem Statement

Subleq is an example of a One-Instruction Set Computer (OISC). It is named after its only instruction, which is SUbtract and Branch if Less than or EQual to zero.
Your task is to create an interpreter which emulates a SUBLEQ machine. The machine's memory consists of an array of signed integers.   These integers may be interpreted in three ways: Any reasonable word size that accommodates all three of the above uses is fine. The program should load the initial contents of the emulated machine's memory, set the instruction pointer to the first address (which is defined to be address 0), and begin emulating the machine, which works as follows: Your solution may initialize the emulated machine's memory in any convenient manner, but if you accept it as input, it should be a separate input stream from the one fed to the emulated machine once it is running. And if fed as text input, it should be in the form of raw subleq "machine code" - whitespace-separated decimal numbers, with no symbolic names or other assembly-level extensions, to be loaded into memory starting at address   0   (zero). For purposes of this task, show the output of your solution when fed the below   "Hello, world!"   program. As written, this example assumes ASCII or a superset of it, such as any of the Latin-N character sets or Unicode;   you may translate the numbers representing characters (starting with 72=ASCII 'H') into another character set if your implementation runs in a non-ASCII-compatible environment. If 0 is not an appropriate terminator in your character set, the program logic will need some adjustment as well. The above "machine code" corresponds to something like this in a hypothetical assembler language for a signed 8-bit version of the machine:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Subleq step by step in the Haskell programming language

This Haskell program implements a subroutine that reads a sequence of opcodes and executes them. The opcodes specify operations such as reading a character from the standard input, writing a character to the standard output, or performing an arithmetic operation on two values.

The program uses the State monad to track the state of the program, which includes the current instruction pointer and a map from values to characters. The subleq function is the main loop of the program, which repeatedly executes the next opcode.

The loop function is the main loop of the program. It first checks if the current instruction pointer is valid, and if not, it exits. It then gets the values of the current and next opcodes from the state. If the current opcode is negative, it means that it is a read opcode, so the program reads a character from the standard input and stores it in the state. If the current opcode is positive, it means that it is a write opcode, so the program writes the character stored at the value of the next opcode to the standard output. If the current opcode is zero, it means that it is a jump opcode, so the program jumps to the address stored at the value of the next opcode.

The main function initializes the state of the program and then runs the subleq function on the state. The helloWorld variable contains the opcodes for the program, which simply prints the string "Hello world!" to the standard output.

Source code in the haskell programming language

{-# LANGUAGE FlexibleContexts #-}
import Control.Monad.State
import Data.Char (chr, ord)
import Data.IntMap

subleq = loop 0
    where
      loop ip =
          when (ip >= 0) $
          do m0 <- gets (! ip)
             m1 <- gets (! (ip + 1))
             if m0 < 0
                then do modify . insert m1 ch . ord =<< liftIO getChar
                        loop (ip + 3)
                else if m1 < 0
                        then do liftIO . putChar . chr =<< gets (! m0)
                                loop (ip + 3)
                        else do v <- (-) <$> gets (! m1) <*> gets (! m0)
                                modify $ insert m1 v
                                if v <= 0
                                   then loop =<< gets (! (ip + 2))
                                   else loop (ip + 3)

main = evalStateT subleq helloWorld
    where
      helloWorld =
          fromList $
          zip [0..]
              [15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 10, 0]


  

You may also check:How to resolve the algorithm Memory allocation step by step in the FreeBASIC programming language
You may also check:How to resolve the algorithm Minesweeper game step by step in the Icon and Unicon programming language
You may also check:How to resolve the algorithm I before E except after C step by step in the BASIC programming language
You may also check:How to resolve the algorithm Constrained genericity step by step in the TXR programming language
You may also check:How to resolve the algorithm Odd word problem step by step in the Nim programming language