How to resolve the algorithm Execute Computer/Zero step by step in the Julia programming language
How to resolve the algorithm Execute Computer/Zero step by step in the Julia programming language
Table of Contents
Problem Statement
Create a Computer/zero Assembly emulator. You may consider this webpage as a reference implementation. Output the results of the sample programs "2+2" and "7*8" found there.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Execute Computer/Zero step by step in the Julia programming language
The code is a program written in the Julia programming language that simulates a simple 8-bit computer called the "ComputerZero". It includes several functions and macros that define the behavior of the computer and its instructions. Here's a breakdown of the code:
-
ComputerZero
Struct:- Defines a custom struct called
ComputerZero
that represents the computer itself. - It contains fields such as
ip
for the instruction pointer,ram
for the memory,accum
for the accumulator, andisready
to indicate if the computer is still running.
- Defines a custom struct called
-
ComputerZero
Constructor:- This function initializes a
ComputerZero
struct with the specified program as a vector of unsigned 8-bit integers. - It populates the first 32 bytes of memory with the program instructions and sets the other fields to their initial values.
- This function initializes a
-
Instruction Definitions:
- A series of macros (
NOP
,LDA
,STA
,ADD
,SUB
,BRZ
,JMP
, andSTP
) define the behavior of each instruction. - These macros update the computer's state based on the instruction being executed. For example,
LDA
loads a value from memory into the accumulator, whileADD
adds a value from memory to the accumulator.
- A series of macros (
-
step
andinstructions
Arrays:step
is an array that maps each instruction opcode to its corresponding macro.instructions
is an array that contains the string names of the instructions.
-
run
Function:- This function runs the specified
ComputerZero
instance by executing instructions one by one until it completes or encounters an error. - It uses the
step
array to execute the appropriate instruction for each opcode.
- This function runs the specified
-
compile
Function:- This function takes an assembly language program as a string and compiles it into a vector of unsigned 8-bit integers that can be loaded into the computer's memory.
- It parses the assembly instructions and translates them into the corresponding opcodes and operands.
-
testprograms
Array:- Defines several test programs in assembly language that are used for testing the computer.
-
interpret
Function:- This function is similar to the
run
function but interprets the assembly language instructions directly without compiling them. - It uses a custom interpreter that parses the assembly instructions and executes them one by one.
- This function is similar to the
-
Additional Test Programs:
- Several more test programs are defined in assembly language to demonstrate the capabilities of the computer and the interpreter.
Overall, this code provides a framework for simulating a simple 8-bit computer and executing assembly language programs on it. The modular design and use of macros make it easy to add new instructions and modify the behavior of the computer.
Source code in the julia programming language
mutable struct ComputerZero
ip::Int
ram::Vector{UInt8}
accum::UInt8
isready::Bool
end
function ComputerZero(program)
memory = zeros(UInt8, 32)
for i in 1:min(32, length(program))
memory[i] = program[i]
end
return ComputerZero(1, memory, 0, true)
end
NOP(c) = (c.ip = mod1(c.ip + 1, 32))
LDA(c) = (c.accum = c.ram[c.ram[c.ip] & 0b00011111 + 1]; c.ip = mod1(c.ip + 1, 32))
STA(c) = (c.ram[c.ram[c.ip] & 0b00011111 + 1] = c.accum; c.ip = mod1(c.ip + 1, 32))
ADD(c) = (c.accum += c.ram[c.ram[c.ip] & 0b00011111 + 1]; c.ip = mod1(c.ip + 1, 32))
SUB(c) = (c.accum -= c.ram[c.ram[c.ip] & 0b00011111 + 1]; c.ip = mod1(c.ip + 1, 32))
BRZ(c) = (c.ip = (c.accum == 0) ? c.ram[c.ip] & 0b00011111 + 1 : mod1(c.ip + 1, 32))
JMP(c) = (c.ip = c.ram[c.ip] & 0b00011111 + 1)
STP(c) = (println("Program completed with accumulator value $(c.accum).\n"); c.isready = false)
const step = [NOP, LDA, STA, ADD, SUB, BRZ, JMP, STP]
const instructions = ["NOP", "LDA", "STA", "ADD", "SUB", "BRZ", "JMP", "STP"]
const assemblywords = Dict(s => i - 1 for (i, s) in pairs(instructions))
function run(compzero::ComputerZero, debug = false)
while compzero.isready
instruction = compzero.ram[compzero.ip]
opcode, operand = instruction >> 5 + 1, instruction & 0b00011111
debug && println("op $(instructions[opcode]), operand $operand")
step[opcode](compzero)
end
return compzero.accum
end
run(program::Vector, debug = false) = run(ComputerZero(program), debug)
function compile(text::String)
bin, lines = UInt8[], 0
for line in strip.(split(text, "\n"))
lines += 1
if isempty(line)
push!(bin, 0)
elseif (m = match(r"(\w\w\w)\s+(\d\d?)", line)) != nothing
push!(bin, UInt8((assemblywords[m.captures[1]] << 5) | parse(UInt8, m.captures[2])))
elseif (m = match(r"(\w\w\w)", line)) != nothing
push!(bin, UInt8(assemblywords[m.match] << 5))
elseif (m = match(r"\d\d?", line)) != nothing
push!(bin, parse(UInt8, m.match))
else
error("Compilation error at line $lines: error parsing <$line>")
end
end
println("Compiled $lines lines.")
return bin
end
const testprograms = [
"""
LDA 3
ADD 4
STP
2
2
""",
"""
LDA 12
ADD 10
STA 12
LDA 11
SUB 13
STA 11
BRZ 8
JMP 0
LDA 12
STP
8
7
0
1
""",
"""
LDA 14
STA 15
ADD 13
STA 14
LDA 15
STA 13
LDA 16
SUB 17
BRZ 11
STA 16
JMP 0
LDA 14
STP
1
1
0
8
1
""",
"""
LDA 13
ADD 15
STA 5
ADD 16
STA 7
NOP
STA 14
NOP
BRZ 11
STA 15
JMP 0
LDA 14
STP
LDA 0
0
28
1
6
0
2
26
5
20
3
30
1
22
4
24
""",
"""
0
0
STP
NOP
LDA 3
SUB 29
BRZ 18
LDA 3
STA 29
BRZ 14
LDA 1
ADD 31
STA 1
JMP 2
LDA 0
ADD 31
STA 0
JMP 2
LDA 3
STA 29
LDA 0
ADD 30
ADD 3
STA 0
LDA 1
ADD 30
ADD 3
STA 1
JMP 2
0
1
3
"""
]
for t in testprograms
run(compile(t))
end
function interpret(text::String)
ip, accum, isready, ram = 0x1, 0x0, true, zeros(UInt8, 32)
NOP() = (ip = mod1(ip + 1, 32))
LDA() = (accum = ram[ram[ip] & 0b00011111 + 1]; ip = mod1(ip + 1, 32))
STA() = (ram[ram[ip] & 0b00011111 + 1] = accum; ip = mod1(ip + 1, 32))
ADD() = (accum += ram[ram[ip] & 0b00011111 + 1]; ip = mod1(ip + 1, 32))
SUB() = (accum -= ram[ram[ip] & 0b00011111 + 1]; ip = mod1(ip + 1, 32))
BRZ() = (ip = (accum == 0) ? ram[ip] & 0b00011111 + 1 : mod1(ip + 1, 32))
JMP() = (ip = ram[ip] & 0b00011111 + 1)
STP() = (println("Program completed with accumulator value $(accum).\n"); isready = false)
step = [NOP, LDA, STA, ADD, SUB, BRZ, JMP, STP]
assemblywords = Dict(s => i - 1 for (i, s) in pairs(string.(step)))
labels = Dict{String, Int}()
arglabels = Dict{Int, Tuple{Int, String}}()
for (i, line) in pairs(strip.(split(text, "\n")))
i > 32 && break
line = replace(line, r";.*$" => "") # remove comment
if occursin(":", line)
label, line = split(line, ":", limit = 2)
haskey(labels, label) && error("Duplicate label at line $i")
labels[strip(label)] = i - 1
end
if isempty(line)
ram[i] = 0
elseif (m = match(r"(\w\w\w)\s+([a-zA-Z]\w*)", line)) != nothing
arglabels[i] = (UInt8((assemblywords[m.captures[1]] << 5)), m.captures[2])
elseif (m = match(r"(\w\w\w)\s+(\d\d*)", line)) != nothing
ram[i] = UInt8((assemblywords[m.captures[1]] << 5) | parse(UInt8, m.captures[2]))
elseif (m = match(r"([a-zA-Z]\w*)", line)) != nothing
ram[i] = UInt8(assemblywords[m.match] << 5)
elseif (m = match(r"\d\d*", line)) != nothing
ram[i] = parse(UInt8, m.match)
else
error("Compilation error at line $i: error parsing <$line>")
end
end
for (i, t) in arglabels
ram[i] = t[1] | labels[t[2]]
end
while isready
step[ram[ip] >> 5 + 1]()
end
return accum
end
const testprograms = [
"""
LDA 3
ADD 4
STP
2
2
""",
"""
LDA 12
ADD 10
STA 12
LDA 11
SUB 13
STA 11
BRZ 8
JMP 0
LDA 12
STP
8
7
0
1
""",
"""
LDA 14
STA 15
ADD 13
STA 14
LDA 15
STA 13
LDA 16
SUB 17
BRZ 11
STA 16
JMP 0
LDA 14
STP
1
1
0
8
1
""",
"""
LDA 13
ADD 15
STA 5
ADD 16
STA 7
NOP
STA 14
NOP
BRZ 11
STA 15
JMP 0
LDA 14
STP
LDA 0
0
28
1
6
0
2
26
5
20
3
30
1
22
4
24
""",
"""
0
0
STP
NOP
LDA 3
SUB 29
BRZ 18
LDA 3
STA 29
BRZ 14
LDA 1
ADD 31
STA 1
JMP 2
LDA 0
ADD 31
STA 0
JMP 2
LDA 3
STA 29
LDA 0
ADD 30
ADD 3
STA 0
LDA 1
ADD 30
ADD 3
STA 1
JMP 2
0
1
3
""",
"""\
LDA x
ADD y ; accumulator = x + y
STP
x: 2
y: 2
""",
"""\
loop: LDA prodt
ADD x
STA prodt
LDA y
SUB one
STA y
BRZ done
JMP loop
done: LDA prodt ; to display it
STP
x: 8
y: 7
prodt: 0
one: 1
""",
"""\
loop: LDA n
STA temp
ADD m
STA n
LDA temp
STA m
LDA count
SUB one
BRZ done
STA count
JMP loop
done: LDA n ; to display it
STP
m: 1
n: 1
temp: 0
count: 8 ; valid range: 1-11
one: 1
""",
"""\
start: LDA load
ADD car ; head of list
STA ldcar
ADD one
STA ldcdr ; next CONS cell
ldcar: NOP
STA value
ldcdr: NOP
BRZ done ; 0 stands for NIL
STA car
JMP start
done: LDA value ; CAR of last CONS
STP
load: LDA 0
value: 0
car: 28
one: 1
; order of CONS cells
; in memory
; does not matter
6
0 ; 0 stands for NIL
2 ; (CADR ls)
26 ; (CDDR ls) -- etc.
5
20
3
30
1 ; value of (CAR ls)
22 ; points to (CDR ls)
4
24
""",
"""\
p: 0 ; NOP in first round
c: 0
start: STP ; wait for p's move
pmove: NOP
LDA pmove
SUB cmove
BRZ same
LDA pmove
STA cmove ; tit for tat
BRZ cdeft
LDA c ; p defected, c did not
ADD three
STA c
JMP start
cdeft: LDA p
ADD three
STA p
JMP start
same: LDA pmove
STA cmove ; tit for tat
LDA p
ADD one
ADD pmove
STA p
LDA c
ADD one
ADD pmove
STA c
JMP start
cmove: 0 ; co-operate initially
one: 1
three: 3
""",
"""\
LDA 3
SUB 4
STP 0
0
255
""",
"""\
LDA 3
SUB 4
STP 0
0
1
""",
"""\
LDA 3
ADD 4
STP 0
1
255
""",
]
for t in testprograms
interpret(t)
end
You may also check:How to resolve the algorithm Factors of a Mersenne number step by step in the Crystal programming language
You may also check:How to resolve the algorithm Greatest element of a list step by step in the PureBasic programming language
You may also check:How to resolve the algorithm Sieve of Eratosthenes step by step in the PowerShell programming language
You may also check:How to resolve the algorithm User input/Text step by step in the Oz programming language
You may also check:How to resolve the algorithm Mandelbrot set step by step in the Forth programming language