1부가 계속되고 2부가 시작됩니다.
4. ChatGPT에서 제공하는 코드를 디버깅하고 실행합니다.
class StackMachine:
def __init__(self):
self.stack = ()
self.program = ()
self.labels = {}
self.ip = 0
self.ax = 0
self.bx = 0
self.cx = 0
self.dx = 0
def load_program(self, program):
self.program = program
for i, line in enumerate(program):
if line.endswith(':'):
self.labels(line(:-1)) = i
def run(self):
count = 20000
while self.ip < len(self.program) and count > 0:
count -= 1
cmd = self.program(self.ip).split()
op = cmd(0).upper()
if op == 'PUSH':
self.stack.append(int(cmd(1)))
elif op == 'POP':
self.stack.pop()
elif op == 'ADD':
self.stack.append(self.stack.pop() + self.stack.pop())
elif op == 'SUB':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append(a - b)
elif op == 'MUL':
self.stack.append(self.stack.pop() * self.stack.pop())
elif op == 'DIV':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append(a // b)
elif op == 'MOD':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append(a % b)
elif op == 'DUP':
self.stack.append(self.stack(-1))
elif op == 'SWAP':
self.stack(-1), self.stack(-2) = self.stack(-2), self.stack(-1)
elif op == 'JMP':
self.ip = self.labels(cmd(1))
continue
elif op == 'JG':
if self.stack.pop() == 1:
self.ip = self.labels(cmd(1))
continue
elif op == 'JZ':
if self.stack.pop() == 0:
self.ip = self.labels(cmd(1))
continue
elif op == 'JNZ':
if self.stack.pop() != 0:
self.ip = self.labels(cmd(1))
continue
elif op == 'CMP':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append((a > b) - (a < b))
elif op == 'NOP':
pass
elif op == 'HALT':
break
self.ip += 1
아래와 같이 올바른 결과가 표시되는지 확인합니다.
C:\Users\chobo\AppData\Local\Programs\Python\Python38\python.exe C:\github\simple_vm\simple_vm\main.py
결과: 3628800
5. 코드를 약간 리팩토링하십시오.
6. ChatGPT에 수정된 코드를 주고 댓글을 영어로 변경하도록 요청합니다.
주석은 1단계에서 명령을 정리하여 작성한 그대로 첨부합니다.
class StackMachine:
"""
PUSH <value>: Push a value onto the stack. e.g., PUSH 10
POP: Remove and return the top value from the stack.
ADD: Remove the top two values from the stack, calculate their sum, and push the result onto the stack.
SUB: Remove the top two values from the stack, calculate their difference, and push the result onto the stack.
MUL: Remove the top two values from the stack, calculate their product, and push the result onto the stack.
DIV: Remove the top two values from the stack, calculate their division, and push the result onto the stack.
MOD: Remove the top two values from the stack, calculate their remainder, and push the result onto the stack.
DUP: Copy the top value from the stack and push it onto the stack.
SWAP: Swap the top two values on the stack.
JMP <label>: Move program execution to the given label. e.g., JMP LOOP
JZ <label>: If the top value on the stack is 0, move program execution to the given label.
JNZ <label>: If the top value on the stack is not 0, move program execution to the given label.
CMP: Compare the top two values on the stack and push the result onto the stack.
(-1: First value is smaller, 0: Both values are equal, 1: First value is larger)
CALL <label>: Save the current position and move program execution to the given label.
RET: Return to the previously saved position and continue program execution.
NOP: Perform no operation. This command is ignored in the program.
HALT: Stop program execution.
"""
def __init__(self):
self.stack = ()
self.program = ()
self.labels = {}
self.register = {'AX': 0, 'BX': 0, 'CX': 0, 'DX': 0}
self.ip = 0
def load_program(self, program):
self.program = program
for i, line in enumerate(program):
if line.endswith(':'):
self.labels(line(:-1)) = i
def run(self):
count = 20000
while self.ip < len(self.program) and count > 0:
count -= 1
cmd = self.program(self.ip).split()
op = cmd(0).upper()
if op == 'PUSH':
if type(cmd(1)) == int:
self.stack.append(int(cmd(1)))
else:
self.stack.append(int(self.register(cmd(1))))
elif op == 'POP':
self.stack.pop()
elif op == 'MOV':
if cmd(1) == 'AX':
self.ax = self.stack(-1)
elif cmd(1) == 'BX':
self.bx = self.stack(-1)
elif cmd(1) == 'CX':
self.cx = self.stack(-1)
elif cmd(1) == 'DX':
self.dx = self.stack(-1)
elif op == 'ADD':
self.stack.append(self.stack.pop() + self.stack.pop())
elif op == 'SUB':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append(a - b)
elif op == 'MUL':
self.stack.append(self.stack.pop() * self.stack.pop())
elif op == 'DIV':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append(a // b)
elif op == 'MOD':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append(a % b)
elif op == 'DUP':
self.stack.append(self.stack(-1))
elif op == 'SWAP':
self.stack(-1), self.stack(-2) = self.stack(-2), self.stack(-1)
elif op == 'JMP':
self.ip = self.labels(cmd(1))
continue
elif op == 'JG':
if self.stack.pop() == 1:
self.ip = self.labels(cmd(1))
continue
elif op == 'JL':
if self.stack.pop() == -1:
self.ip = self.labels(cmd(1))
continue
elif op == 'JZ':
if self.stack.pop() == 0:
self.ip = self.labels(cmd(1))
continue
elif op == 'JNZ':
if self.stack.pop() != 0:
self.ip = self.labels(cmd(1))
continue
elif op == 'CMP':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append((a > b) - (a < b))
elif op == 'NOP':
pass
elif op == 'HALT':
break
self.ip += 1
# print(f"{self.stack} / {self.ax}")
7. 주석과 코드가 일치하지 않습니다. 코드 베이스로 업데이트할 주석을 요청합니다.
class StackMachine:
"""
PUSH <value>: Push a value onto the stack. e.g., PUSH 10
POP: Remove and return the top value from the stack.
ADD: Remove the top two values from the stack, calculate their sum, and push the result onto the stack.
SUB: Remove the top two values from the stack, calculate their difference, and push the result onto the stack.
MUL: Remove the top two values from the stack, calculate their product, and push the result onto the stack.
DIV: Remove the top two values from the stack, calculate their division, and push the result onto the stack.
MOD: Remove the top two values from the stack, calculate their remainder, and push the result onto the stack.
DUP: Copy the top value from the stack and push it onto the stack.
SWAP: Swap the top two values on the stack.
JMP <label>: Move program execution to the given label. e.g., JMP LOOP
JG <label>: If the top value on the stack is greater than 0, move program execution to the given label.
JL <label>: If the top value on the stack is less than 0, move program execution to the given label.
JZ <label>: If the top value on the stack is 0, move program execution to the given label.
JNZ <label>: If the top value on the stack is not 0, move program execution to the given label.
CMP: Compare the top two values on the stack and push the result onto the stack.
(-1: First value is smaller, 0: Both values are equal, 1: First value is larger)
MOV <register>: Move the top value from the stack to the specified register (AX, BX, CX, or DX).
NOP: Perform no operation. This command is ignored in the program.
HALT: Stop program execution.
"""
def __init__(self):
self.stack = ()
self.program = ()
self.labels = {}
self.register = {'AX': 0, 'BX': 0, 'CX': 0, 'DX': 0}
self.ip = 0
def load_program(self, program):
self.program = program
for i, line in enumerate(program):
if line.endswith(':'):
self.labels(line(:-1)) = i
def run(self):
count = 20000
while self.ip < len(self.program) and count > 0:
count -= 1
cmd = self.program(self.ip).split()
op = cmd(0).upper()
if op == 'PUSH':
if 'X' in cmd(1):
self.stack.append(int(self.register(cmd(1))))
else:
self.stack.append(int(cmd(1)))
elif op == 'POP':
self.stack.pop()
elif op == 'MOV':
self.register(cmd(1)) = self.stack(-1)
elif op == 'ADD':
self.stack.append(self.stack.pop() + self.stack.pop())
elif op == 'SUB':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append(a - b)
elif op == 'MUL':
self.stack.append(self.stack.pop() * self.stack.pop())
elif op == 'DIV':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append(a // b)
elif op == 'MOD':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append(a % b)
elif op == 'DUP':
self.stack.append(self.stack(-1))
elif op == 'SWAP':
self.stack(-1), self.stack(-2) = self.stack(-2), self.stack(-1)
elif op == 'JMP':
self.ip = self.labels(cmd(1))
continue
elif op == 'JG':
if self.stack.pop() == 1:
self.ip = self.labels(cmd(1))
continue
elif op == 'JL':
if self.stack.pop() == -1:
self.ip = self.labels(cmd(1))
continue
elif op == 'JZ':
if self.stack.pop() == 0:
self.ip = self.labels(cmd(1))
continue
elif op == 'JNZ':
if self.stack.pop() != 0:
self.ip = self.labels(cmd(1))
continue
elif op == 'CMP':
b, a = self.stack.pop(), self.stack.pop()
self.stack.append((a > b) - (a < b))
elif op == 'NOP':
pass
elif op == 'HALT':
break
self.ip += 1
# print(f"{self.stack} / {self.ax}")
3부에서 계속됩니다.
