I am attempting to learn the Nim language by making a small and simplistic register machine. It is intended to interpret some basic instructions.
The entire parsing lexing process consists of splitting the inputted code by spaces (not whitespace in general), which newlines are counted as. Is this reasonable code style in Nim?
The code reads a file name containing the instructions from stdin and then executes those instructions on the seq.
I am a beginner at programming in general, not just Nim. Also, my very basic knowledge of Turing completeness suggests that it might be Turing complete. Is that so?
The instructions are as follows:
set+ ADDRESS: int, VALUE: int
, which sets the value of ADDRESS to the previous value of ADDRESS plus the value.set- ADDRESS: int, VALUE: int
, which sets the value of ADDRESS to the previous value of ADDRESS minus the value.mul ADDRESS1: int, ADDRESS2: int ADDRESS3: int
, which sets ADDRESS3's value to ADDRESS1's * ADDRESS2'sadd ADDRESS1: int, ADDRESS2: int ADDRESS3: int
, which sets ADDRESS3's value to ADDRESS1's + ADDRESS2'ssub ADDRESS1: int, ADDRESS2: int ADDRESS3: int
, which sets ADDRESS3's value to ADDRESS1's - ADDRESS2'sdiv ADDRESS1: int, ADDRESS2: int ADDRESS3: int
, which sets ADDRESS3's value to ADDRESS1's // ADDRESS2'sif+ ADDRESS1: int, ADDRESS2: int, JUMPLEN: int ,EQUALORUNEQUAL: ! or =
, which adds jumplen to code pointer if ADDRESS1 and ADDRESS2 are equal or unequal.if- ADDRESS1: int, ADDRESS2: int JUMPLEN: int, EQUALORUNEQUAL: ! or =
, which subtracts jumplen from code pointer if ADDRESS1 and ADDRESS2 are equal or unequal.inp ADDRESS: int
which takes one integer input and sets ADDRESS to it.echo ADDRESS: int
which echoes the value of ADDRESSswap ADDRESS1: int ADDRESS2: int
which swaps the values of ADDRESS1 and ADDRESS2
import strutils
var mem: seq[int]
for i in 0..30000:
mem.add(0)
var code = readFile(readLine(stdin))
var codeptr = 0
for i in 0..len(code) - 1:
if code[i] == '\n':
code[i] = ' '
var codes = code.split(" ")
var done: bool
var pyqt = false
while codeptr < len(codes):
done = false
pyqt = false
if codes[codeptr] == "set+" and done == false:
var IP = codes[codeptr + 1].parseInt()
mem[IP] = mem[IP] + codes[codeptr + 2].parseInt()
inc(codeptr, 2)
done = true
if codes[codeptr] == "set-" and done == false:
var IP1 = codes[codeptr + 1].parseInt()
mem[IP1] = mem[IP1] - codes[codeptr + 2].parseInt()
inc(codeptr, 2)
done = true
if codes[codeptr] == "add" and done == false:
var IP2 = codes[codeptr + 1].parseInt()
var IP3 = codes[codeptr + 2].parseInt()
var IP4 = codes[codeptr + 3].parseInt()
mem[IP4] = mem[IP2] + mem[IP3]
inc(codeptr, 2)
done = true
if codes[codeptr] == "sub" and done == false:
var IP5 = codes[codeptr + 1].parseInt()
var IP6 = codes[codeptr + 2].parseInt()
var IP7 = codes[codeptr + 3].parseInt()
mem[IP7] = mem[IP5] - mem[IP6]
inc(codeptr, 2)
done = true
if codes[codeptr] == "mul" and done == false:
var IP8 = codes[codeptr + 1].parseInt()
var IP9 = codes[codeptr + 2].parseInt()
var IP10 = codes[codeptr + 3].parseInt()
mem[IP10] = mem[IP8] * mem[IP9]
inc(codeptr, 2)
done = true
if codes[codeptr] == "div" and done == false:
var IP11 = codes[codeptr + 1].parseInt()
var IP12 = codes[codeptr + 2].parseInt()
var IP13 = codes[codeptr + 3].parseInt()
mem[IP13] = int(mem[IP11] / mem[IP12])
inc(codeptr, 2)
done = true
if codes[codeptr] == "if-" and done == false:
var IP14 = codes[codeptr + 1].parseInt()
var IP15 = codes[codeptr + 2].parseInt()
var IP16 = codes[codeptr + 3].parseInt()
var IP17 = codes[codeptr + 4]
if IP17 == "=":
if mem[IP14] == mem[IP15]:
codeptr = codeptr - IP16
pyqt = true
if IP17 == "!":
if mem[IP14] != mem[IP15]:
codeptr = codeptr - IP16
pyqt = true
done = true
if codes[codeptr] == "if+" and done == false:
var IP14 = codes[codeptr + 1].parseInt()
var IP15 = codes[codeptr + 2].parseInt()
var IP16 = codes[codeptr + 3].parseInt()
var IP17 = codes[codeptr + 4]
if IP17 == "=":
if mem[IP14] == mem[IP15]:
codeptr = codeptr + IP16
pyqt = true
if IP17 == "!":
if mem[IP14] != mem[IP15]:
codeptr = codeptr + IP16
pyqt = true
done = true
if codes[codeptr] == "inp" and done == false:
var IP18 = codes[codeptr + 1].parseInt()
mem[IP18] = readLine(stdin).parseInt()
inc(codeptr, 1)
done = true
if codes[codeptr] == "echo" and done == false:
var IP19 = codes[codeptr + 1].parseInt()
echo mem[IP19]
inc(codeptr, 1)
done = true
if codes[codeptr] == "swap" and done == false:
var IP20 = codes[codeptr + 1].parseInt()
var IP21 = codes[codeptr + 2].parseInt()
var temp = mem[IP21]
mem[IP21] = mem[IP20]
mem[IP20] = temp
inc(codeptr, 2)
done = true
if codes[codeptr] == "cp" and done == false:
var IP22 = codes[codeptr + 1].parseInt()
var IP23 = codes[codeptr + 2].parseInt()
mem[IP23] = mem[IP22]
inc(codeptr, 2)
done = true
if pyqt == false:
codeptr = codeptr + 1
-
\$\begingroup\$ I rolled back your last edit. In this exchange, editing the question after it's been answered, invalidates the answer. \$\endgroup\$vnp– vnp2021年06月13日 17:30:25 +00:00Commented Jun 13, 2021 at 17:30
-
\$\begingroup\$ Sorry, should have realized. It was just not my intention to convey what the answerer thought I was trying to. I was trying to ask if the code was using reasonable Nim style, not the minimal language implemented. It pays to proofread twice, and I should have. \$\endgroup\$LearningPython– LearningPython2021年06月13日 21:19:22 +00:00Commented Jun 13, 2021 at 21:19
1 Answer 1
The entire parsing lexing process consists of splitting the inputted code by spaces (not whitespace in general), which newlines are counted as. Is this reasonable code style in Nim?
Those are completely different things: you're writing an interpreter for some other language in Nim, so it doesn't matter if this style is reasonable in Nim - it should be reasonable in your language. I'm not pretty sure if it will be ok, but this is your language, so you're the one who decides if it's reasonable.
Yes, your language looks pretty much Turing complete.
Review:
Pay attention to newSeq proc.
"done == false" looks better as "not done":
if not done and codes[codeptr] == "if+":
but with this whole done thing you're reinventing elif statement in Nim.
Everything else is ok since you're a beginner. You should learn all keywords and System module.
Explore related questions
See similar questions with these tags.