Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Mik-2 Interpreter
- # by Ido Gendel, 2020
- # Work in progress, of course...
- # How to program in Mik-2:
- # The character '#' marks a comment to end-of-line
- # First line is the memory initialization:
- # [addr1]=value1, [addr2]=value2 ...
- # Addresses are 0-based, values are signed integers
- # Following lines are commands:
- # cmd param
- # Available commands:
- # RD [addr] # Read value in memory address addr to register
- # WR [addr] # Write value from register to memory address addr
- # SU [addr] # Subtract value in memory address addr from value in register
- # JZ line # If value in register is 0, set program counter to line
- #
- # Command/line numbers are implicit, 0-based
- # WR to address [-1] will output the register value as ASCII to the terminal
- # JZ to a line number beyond the actual program will end the program
- # RD from an address not previously defined will return 0
- COMMENT_IDENTIFIER = "#"
- PROGRAM_FILE = "program1.mik2"
- memory = {}
- program_counter = 0
- register = 0
- def addr_str_to_number(addr_str):
- b1 = addr_str.find("[")
- if b1 < 0:
- return "Missing '['"
- b2 = addr_str.find("]")
- if b2 < b1:
- return "Missing/misplaced ']'"
- try:
- value = int(addr_str[b1+1:b2])
- if value < -1:
- return "Illegal address"
- else:
- return value
- except ValueError:
- return "Address Error"
- def initialize_memory(memory_string):
- global memory
- assign_list = memory_string.split(",")
- index = 0
- for assign_str in assign_list:
- eq = assign_str.find("=")
- if eq <= 0:
- return "Missing/misplaced '=' in item " + str(index)
- addr = addr_str_to_number(assign_str[0:eq])
- if type(addr) == str:
- return "Address error in item '" + str(index) + "' : " + addr
- try:
- value = int(assign_str[eq + 1:])
- except ValueError:
- return "Value error in item " + str(index)
- memory[addr] = value
- index += 1
- return ""
- def memory_write(key, value):
- memory[key] = value
- if -1 == key:
- print(chr(value), end="")
- def memory_read(key):
- if not (key in memory.keys()):
- memory[key] = 0
- return memory[key]
- # command_str is stripped of all spaces
- def run_command(command_str):
- global program_counter
- global register
- cmd = command_str[:2]
- value_str = command_str[2:]
- addr = addr_str_to_number(value_str)
- program_counter += 1
- if cmd == "RD":
- if type(addr) == str:
- return addr
- else:
- register = memory_read(addr)
- elif cmd == "WR":
- if type(addr) == str:
- return addr
- else:
- memory_write(addr, register)
- elif cmd == "SU":
- if type(addr) == str:
- return addr
- else:
- register -= memory_read(addr)
- elif cmd == "JZ":
- try:
- next_line = int(value_str)
- if 0 == register:
- program_counter = next_line
- except ValueError:
- return "line value"
- else:
- return "Unknown command"
- return ""
- print("Mik-2 interpreter by Ido Gendel, 2020")
- # Read entire program from file
- try:
- code_file = open(PROGRAM_FILE, "r")
- except FileNotFoundError:
- print("File not found!")
- exit()
- raw_code_lines = code_file.readlines()
- # Remove comments, newline characters and spaces
- code_lines = []
- for line in raw_code_lines:
- comment_index = line.find(COMMENT_IDENTIFIER)
- if comment_index >= 0:
- line = line[:comment_index]
- if len(line) > 0:
- if line[-1] == "\n":
- line = line[:-1]
- code_lines.append(line.replace(" ", ""))
- # Parse and execute memory initialization line
- mem_issue = initialize_memory(code_lines[0])
- if mem_issue != "":
- print("Error in line 0 (memory setup): " + mem_issue)
- print(code_lines[0])
- exit()
- del code_lines[0]
- print("Memory: ", memory);
- print("Program started, press Ctrl+C to break...")
- print("----------")
- while True:
- if (program_counter < 0):
- print("\n----------\nIllegal line number: " + str(program_counter))
- break
- if program_counter >= len(code_lines):
- print("\n----------\nProgram completed.")
- break
- command = code_lines[program_counter]
- cmd_issue = run_command(command)
- if cmd_issue != "":
- print("\n----------\nCommand error in '" + command + "' : " + cmd_issue)
- break
- print("Memory:", memory)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement