TurkuPythonExercises / Week 7 Libraries and More Python /[FIXED]20. Own programming language, Part 3: Jump command
KaiquanMah's picture
[FIX] store labels found, GOTO label linenumber
22b578d verified
raw
history blame
6.03 kB
'''Jump command
Implement the function
execute(code: str) -> str
in addition to the properties of the previous functions, the following additional commands:
LABEL location
The command adds the named location to the code.
The command does not by itself cause any changes in the code execution.
The given location may be any STRING of letters and numbers.
GOTO place
Code execution continues from the given named location.
The location must be named by the LABEL instruction.
The location may be in the code before or after the jump instruction.
The program need not worry about possible eternal loops, this is left to the programmer.
Example programs for testing instructions:
Program:
LET a=29
GOTO end
INC a 10 # SKIP THIS LINE
INC a 20 # SKIP THIS LINE
LABEL end
PRINT a
The program returns the printout:
29
Program:
LET a=88
GOTO point1
INC a 10 # SKIP THIS LINE
INC a 20 # SKIP THIS LINE
LABEL point1
PRINT a
GOTO per2
DEC a 20 # SKIP THIS LINE
DEC a 30 # SKIP THIS LINE
LABEL per2
PRINT a
The program returns the result:
88
88
Program:
GOTO point1
LABEL point3 # from below
PRINT a
GOTO end # go to 'end' on the last line
LABEL point2 # from below
DEC a 10
GOTO point3 # go up to point3
LABEL point1 # From line 1
LET a=53
GOTO point2 # them go up to point2
LABEL end # from above
The program returns the result:
43
'''
def execute(code: str) -> str:
variables = {'a': 0, 'b': 0, 'c': 0, 'd': 0}
output = []
###################
# Refactored for this exercise to keep track of line number for LABEL
###################
# Split the code into lines and strip whitespace
lines = [line.strip() for line in code.split('\n')]
# Track labels and their corresponding line numbers
labels = {}
for i, line in enumerate(lines):
if line.startswith('LABEL'):
_, location = line.split()
labels[location] = i # Store the line number of the label
i = 0
while i < len(lines):
line = lines[i]
# Skip empty lines
if not line:
i += 1
continue
###################
if line.startswith('LET'):
_, assignment = line.split(' ', 1)
var, value = assignment.split('=')
if var in variables:
variables[var] = int(value)
i += 1
else:
raise ValueError(f"Invalid variable name: {var}")
elif line.startswith('PRINT'):
_, var = line.split()
if var in variables:
output.append(str(variables[var]))
i += 1
else:
raise ValueError(f"Undefined variable: {var}")
##########################################
# 19. part 2
##########################################
elif line.startswith('INC') or line.startswith('DEC'):
# Handle INC and DEC commands
parts = line.split()
command = parts[0]
var1 = parts[1]
if var1 not in variables:
raise ValueError(f"Invalid variable name: {var1}")
if len(parts) == 3:
# Check if parts[2] is an integer
try:
value = int(parts[2]) # Try to convert parts[2] to an integer
# If conversion succeeds
# INC/DEC variable number
if command == 'INC':
variables[var1] += value
elif command == 'DEC':
variables[var1] -= value
i += 1
# parts[2] is NOT an integer
except ValueError:
# INC/DEC variable1 variable2
var2 = parts[2]
if var2 not in variables:
raise ValueError(f"Invalid variable name: {var2}")
if command == 'INC':
variables[var1] += variables[var2]
elif command == 'DEC':
variables[var1] -= variables[var2]
i += 1
else:
raise ValueError(f"Invalid command format: {line}")
##########################################
##########################################
# 20. part 3
##########################################
elif line.startswith('LABEL'):
# Labels are already processed, so just 'skip' the line
i += 1
elif line.startswith('GOTO'):
_, location = line.split()
if location in labels:
i = labels[location] # Jump to the line number of the label
else:
raise ValueError(f"Undefined label: {location}")
##########################################
else:
raise ValueError(f"Invalid command: {line}")
joined_output = '\n'.join(output)
joined_output+='\n'
return joined_output
eg1='''LET a=29
GOTO end
INC a 10
INC a 20
LABEL end
PRINT a'''
print(execute(eg1))
29
eg2='''LET a=88
GOTO point1
INC a 10
INC a 20
LABEL point1
PRINT a
GOTO per2
DEC a 20
DEC a 30
LABEL per2
PRINT a'''
print(execute(eg2))
88
88
eg3='''GOTO point1
LABEL point3
PRINT a
GOTO end
LABEL point2
DEC a 10
GOTO point3
LABEL point1
LET a=53
GOTO point2
LABEL end'''
print(execute(eg3))
43
'''autograder actual, expected output
Testing code:
LET a=96
GOTO end
INC a 10
INC a 20
LABEL end
PRINT a
Program outputs:
96
Testing code:
LET a=58
GOTO spot1
INC a 10
INC a 20
LABEL spot1
PRINT a
GOTO spot2
DEC a 20
DEC a 30
LABEL spot2
PRINT a
Program outputs:
58
58
Testing code:
GOTO spot1
LABEL spot3
PRINT a
GOTO end
LABEL spot2
DEC a 10
GOTO spot3
LABEL spot1
LET a=80
GOTO spot2
LABEL end
Program outputs:
70
'''