3
\$\begingroup\$

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's

  • add ADDRESS1: int, ADDRESS2: int ADDRESS3: int, which sets ADDRESS3's value to ADDRESS1's + ADDRESS2's

  • sub ADDRESS1: int, ADDRESS2: int ADDRESS3: int, which sets ADDRESS3's value to ADDRESS1's - ADDRESS2's

  • div ADDRESS1: int, ADDRESS2: int ADDRESS3: int, which sets ADDRESS3's value to ADDRESS1's // ADDRESS2's

  • if+ 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 ADDRESS

  • swap 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 
vnp
58.6k4 gold badges55 silver badges144 bronze badges
asked Jun 13, 2021 at 5:04
\$\endgroup\$
2
  • \$\begingroup\$ I rolled back your last edit. In this exchange, editing the question after it's been answered, invalidates the answer. \$\endgroup\$ Commented 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\$ Commented Jun 13, 2021 at 21:19

1 Answer 1

2
\$\begingroup\$

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:

  1. Pay attention to newSeq proc.

  2. "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.

answered Jun 13, 2021 at 13:11
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.