This repository has been archived by the owner on Jan 2, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
elfcode.nim
49 lines (37 loc) · 2.1 KB
/
elfcode.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import strutils, tables
type
instr* = tuple[op: string, a,b,c: int]
instructionSet* = tuple[ipr: int, instructions: seq[instr]]
let ops* = {
"addi": proc(regs: seq[int], a,b: int): int = regs[a] + b,
"addr": proc(regs: seq[int], a,b: int): int = regs[a] + regs[b],
"muli": proc(regs: seq[int], a,b: int): int = regs[a] * b,
"mulr": proc(regs: seq[int], a,b: int): int = regs[a] * regs[b],
"bani": proc(regs: seq[int], a,b: int): int = regs[a] and b,
"banr": proc(regs: seq[int], a,b: int): int = regs[a] and regs[b],
"bori": proc(regs: seq[int], a,b: int): int = regs[a] or b,
"borr": proc(regs: seq[int], a,b: int): int = regs[a] or regs[b],
"seti": proc(regs: seq[int], a,b: int): int = a,
"setr": proc(regs: seq[int], a,b: int): int = regs[a],
"gtir": proc(regs: seq[int], a,b: int): int = cast[int](a > regs[b]),
"gtri": proc(regs: seq[int], a,b: int): int = cast[int](regs[a] > b),
"gtrr": proc(regs: seq[int], a,b: int): int = cast[int](regs[a] > regs[b]),
"eqir": proc(regs: seq[int], a,b: int): int = cast[int](a == regs[b]),
"eqri": proc(regs: seq[int], a,b: int): int = cast[int](regs[a] == b),
"eqrr": proc(regs: seq[int], a,b: int): int = cast[int](regs[a] == regs[b]),
}.toTable
proc readInstructions*(input: seq[string]): instructionSet =
for line in input:
var parts = line.split(' ')
if parts[0] == "#ip":
result.ipr = parts[1].parseInt
else:
result.instructions.add((parts[0], parts[1].parseInt, parts[2].parseInt, parts[3].parseInt))
proc ip*(instructionSet: instructionSet, registers: seq[int]): int {.inline.} =
registers[instructionSet.ipr]
proc currentInstr*(instructionSet: instructionSet, registers: seq[int]): instr {.inline.} =
instructionSet.instructions[instructionSet.ip(registers)]
proc step*(instructionSet: instructionSet, registers: var seq[int]) {.inline.} =
let instr = instructionSet.currentInstr(registers)
registers[instr.c] = ops[instr.op](registers, instr.a, instr.b)
registers[instructionSet.ipr].inc