Compare commits

...

3 Commits

Author SHA1 Message Date
BodgeMaster 31981b541e Add UI 2022-11-30 15:16:15 +01:00
BodgeMaster f1f271abbe Enforce command/condition whitelist 2022-11-26 15:19:02 +01:00
BodgeMaster 7ed9e8cc4f Check if the goal has been reached after interpreting code 2022-11-26 15:05:52 +01:00
1 changed files with 45 additions and 11 deletions

View File

@ -53,8 +53,7 @@ cursor_position = [0, 0]
command_delay = 0.3 command_delay = 0.3
def clear_field(): empty_field = [
field = [
" _________________ ", " _________________ ",
"| |", "| |",
"| |", "| |",
@ -304,9 +303,13 @@ def parse_condition(condition_code, allowed_conditions):
else: else:
debug_message(" Unknown condition: "+condition_code) debug_message(" Unknown condition: "+condition_code)
return [condition, inverted, "Unknown condition: "+condition_code] return [condition, inverted, "Unknown condition: "+condition_code]
if not condition_code in allowed_conditions:
return [condition, inverted, "Condition is not allowed here: "+condition_code]
return [condition, inverted, ""] return [condition, inverted, ""]
# returns [[functions], [arguments], -1, ""] or [[], [], error_position, "error message"] # returns [[functions], [arguments], -1, "", "formatted code"] or [[], [], error_position, "error message", "formatted code"]
def parse_code(code, allowed_commands, allowed_conditions, unformatted_code=True): def parse_code(code, allowed_commands, allowed_conditions, unformatted_code=True):
if unformatted_code: if unformatted_code:
code = format_code(code) code = format_code(code)
@ -328,15 +331,22 @@ def parse_code(code, allowed_commands, allowed_conditions, unformatted_code=True
debug_message("Next command is: "+next_command) debug_message("Next command is: "+next_command)
parsed_code[1].append(()) parsed_code[1].append(())
#TODO: add function to to the function list
if next_command == "step": if next_command == "step":
parsed_code[0].append(command_step) parsed_code[0].append(command_step)
if not next_command in allowed_commands:
return [[], [], parse_position, "Command is not allowed here: "+next_command, code]
elif next_command == "left": elif next_command == "left":
parsed_code[0].append(command_left) parsed_code[0].append(command_left)
if not next_command in allowed_commands:
return [[], [], parse_position, "Command is not allowed here: "+next_command, code]
elif next_command == "right": elif next_command == "right":
parsed_code[0].append(command_right) parsed_code[0].append(command_right)
if not next_command in allowed_commands:
return [[], [], parse_position, "Command is not allowed here: "+next_command, code]
elif next_command == "take": elif next_command == "take":
parsed_code[0].append(command_take) parsed_code[0].append(command_take)
if not next_command in allowed_commands:
return [[], [], parse_position, "Command is not allowed here: "+next_command, code]
elif next_command == "repeat": elif next_command == "repeat":
return [[], [], next_space, "Syntax error: Number of repetitions missing", code] return [[], [], next_space, "Syntax error: Number of repetitions missing", code]
elif next_command == "while": elif next_command == "while":
@ -354,6 +364,10 @@ def parse_code(code, allowed_commands, allowed_conditions, unformatted_code=True
control_structure = code[parse_position:next_condition] control_structure = code[parse_position:next_condition]
if control_structure == "repeat": if control_structure == "repeat":
debug_message(" Type: repeat loop") debug_message(" Type: repeat loop")
# This is checked here because otherwise it would throw a bogus error message for unknown control structures.
if not control_structure in allowed_commands:
return [[], [], parse_position, "Command is not allowed here: "+control_structure, code]
parse_position = next_condition parse_position = next_condition
repetitions_length = get_length_of_condition(code[parse_position:]) repetitions_length = get_length_of_condition(code[parse_position:])
if repetitions_length == -2: if repetitions_length == -2:
@ -387,6 +401,10 @@ def parse_code(code, allowed_commands, allowed_conditions, unformatted_code=True
continue continue
elif control_structure == "if": elif control_structure == "if":
debug_message(" Type: if statement") debug_message(" Type: if statement")
# This is checked here because otherwise it would throw a bogus error message for unknown control structures.
if not control_structure in allowed_commands:
return [[], [], parse_position, "Command is not allowed here: "+control_structure, code]
parse_position = next_condition parse_position = next_condition
condition_length = get_length_of_condition(code[parse_position:]) condition_length = get_length_of_condition(code[parse_position:])
if condition_length == -2: if condition_length == -2:
@ -432,6 +450,10 @@ def parse_code(code, allowed_commands, allowed_conditions, unformatted_code=True
continue continue
elif control_structure == "while": elif control_structure == "while":
debug_message(" Type: while loop") debug_message(" Type: while loop")
# This is checked here because otherwise it would throw a bogus error message for unknown control structures.
if not control_structure in allowed_commands:
return [[], [], parse_position, "Command is not allowed here: "+control_structure, code]
parse_position = next_condition parse_position = next_condition
condition_length = get_length_of_condition(code[parse_position:]) condition_length = get_length_of_condition(code[parse_position:])
if condition_length == -2: if condition_length == -2:
@ -477,16 +499,28 @@ def evaluate_parser_result(parsed_code):
# runtime error # runtime error
# TODO: pass back information about where the error occurred # TODO: pass back information about where the error occurred
return outcome return outcome
#TODO: check if goal reached if condition_goal_reached(False):
return "Success!" return "Success!"
else:
return "Goal not reached!"
def setup_and_run_task(start_field, start_position, start_heading, text, allowed_commands, allowed_conditions):
global cursor_position
cursor_position = start_position
global cursor_current
cursor_current = start_heading
global field
field = start_field
draw_field()
print("\n"+text)
print("\nAllowed commands: "+" ,".join(allowed_commands))
print("\nAvailable conditions: "+" ,".join(allowed_conditions))
print(evaluate_parser_result(parse_code(input("\nCode: "), allowed_commands, allowed_conditions)))
#TODO: return information about success or failure
def debug_setup(): def debug_setup():
global cursor_position setup_and_run_task(empty_field, [1,1], cursor_east, "Debug mode", ["step", "left", "right", "take", "repeat", "while", "if"], ["facing north", "facing south", "facing east", "facing west", "in front of wall", "goal reached", "on apple"])
cursor_position = [1,1]
global cursor_current
cursor_current = cursor_south
draw_field()
if __name__ == "__main__": if __name__ == "__main__":
pass pass