TurkuPythonExercises / Week 7 Libraries and More Python /[FIXED]21. Own programming language, Part 4: Condition clause
KaiquanMah's picture
[FIX] split JUMP into parts, match condition, jump_to_locationname
16c3393 verified
raw
history blame
7.16 kB
'''Condition clause
Implement the function
execute(code: str) -> str
in addition to the properties of the previous functions:
JUMP place IF variable==value
Code execution will continue from the named location after the command if the value of the given variable satisfies the condition.
You can assume that the value is a CONSTANT VALUE (not another variable).
Also, the program does not need to understand anything other than the equality operator.
Example programs for testing instructions:
Program:
LET a=13
JUMP end IF a==13 # if variable matches the condition, JUMP to the 'end' LABEL
INC a 10 # SKIP THIS LINE if JUMP. It is in between the JUMP and LABEL end lines
INC a 15 # SKIP THIS LINE if JUMP. It is in between the JUMP and LABEL end lines
LABEL end # JUMP here
PRINT a
Execution of the program returns:
13
Program:
LET a=27
LABEL start # from below
PRINT a
INC a 1
JUMP end IF a==32 # if variable matches the condition, JUMP to the 'end' LABEL
GOTO start # SKIP THIS LINE if JUMP. It is in between the JUMP and LABEL end lines. If not JUMPing, go up to 'start' LABEL
LABEL end
Program execution returns:
27
28
29
30
31
Programme:
LET c=12
LET d=1
LABEL loop
PRINT c
DEC c d
JUMP continue IF c==1 # if variable matches the condition, JUMP to the 'continue' LABEL
GOTO loop # SKIP THIS LINE if JUMP. It is in between the JUMP and LABEL end lines. If not JUMPing, go up to 'loop' LABEL
LABEL continue
Program execution returns:
12
11
10
9
8
7
6
5
4
3
2
'''
def execute(code: str) -> str:
variables = {'a': 0, 'b': 0, 'c': 0, 'd': 0}
output = []
# 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}")
##########################################
##########################################
# 21. part 4
##########################################
elif line.startswith('JUMP'):
parts = line.split()
# eg JUMP end IF a==13 --becomes--> ['JUMP','end','IF','a==13']
# Format: JUMP jump_to_locationname IF variable==value
jump_to_locationname = parts[1]
condition = parts[3]
var, value = condition.split('==')
# Check if the variable exists
if var not in variables:
raise ValueError(f"Undefined variable: {var}")
# Check the condition
if variables[var] == int(value):
# Jump to the specified label
if jump_to_locationname in labels:
i = labels[jump_to_locationname]
else:
raise ValueError(f"Undefined label: {jump_to_locationname}")
else:
# Continue to the next line
i += 1
##########################################
else:
raise ValueError(f"Invalid command: {line}")
joined_output = '\n'.join(output)
joined_output+='\n'
return joined_output
eg1='''LET a=13
JUMP end IF a==13
INC a 10
INC a 15
LABEL end
PRINT a'''
print(execute(eg1))
13
eg2='''LET a=27
LABEL start
PRINT a
INC a 1
JUMP end IF a==32
GOTO start
LABEL end'''
print(execute(eg2))
27
28
29
30
31
eg3='''LET c=12
LET d=1
LABEL loop
PRINT c
DEC c d
JUMP continue IF c==1
GOTO loop
LABEL continue'''
print(execute(eg3))
12
11
10
9
8
7
6
5
4
3
2
'''Autograder actual, expected output (53 lines)
Testing code:
LET a=25
JUMP end IF a==25
INC a 10
INC a 15
LABEL end
PRINT a
Program outputs:
25
Testing code:
LET a=62
LABEL start
PRINT a
INC a 1
JUMP end IF a==67
GOTO start
LABEL end
Program outputs:
62
63
64
65
66
Testing code:
LET c=13
LET d=1
LABEL loop
PRINT c
DEC c d
JUMP continue IF c==1
GOTO loop
LABEL continue
Program outputs:
13
12
11
10
9
8
7
6
5
4
3
2
'''