# Pythonista 3.5 # Grawlix Programming Language # Last update: 2017 from array import array p = 0 # data pointer high_p = 0 # highest value of p pc = 0 # program counter top = 0 # top of the stack top_max = 0 # highest value of top tc = 0 # total command count steps = 0 # number of execution steps command_set = "><+-,.[];:?(){}@/|=^!#" prog_mem = "" nextch = "" key_press = "" input_buffer = "" data_mem = array('B') data_mem = [0] * 100000 stack = array('I') stack = [0] * 100000 bracket_check = "" bracket_counter = 0 bc_counter = 0 #bracket_check counter nesting_levels = 0 # for brackets open_bracket = array('I') open_bracket = [0] * 100000 close_bracket = array('I') close_bracket = [0] * 100000 paren_check = "" paren_counter = 0 paren_check_counter = 0 paren_nesting_levels = 0 open_paren = array('I') open_paren = [0] * 100000 close_paren = array('I') close_paren = [0] * 100000 brace_check = "" brace_counter = 0 brace_check_counter = 0 brace_nesting_levels = 0 function_call_number = 0 number_of_functions = 0 open_brace = array('I') open_brace = [0] * 100000 close_brace = array('I') close_brace = [0] * 100000 function_return_stack = array('I') function_return_stack = [0] * 256 function_return_top = 0 # define functions def printable(n): if((n>31 and n<127) or n == 10): return(True) else: return(False) def find_open_bracket(x): return(open_bracket[close_bracket.index(x)]) def find_close_bracket(x): return(close_bracket[open_bracket.index(x)]) def find_open_paren(x): return(open_paren[close_paren.index(x)]) def find_close_paren(x): return(close_paren[open_paren.index(x)]) def find_open_brace(x):# functions return(open_brace[close_brace.index(x)]) def find_close_brace(x): return(close_brace[open_brace.index(x)]) def dump(x): # x should only be current value of p format_count = 0 print() for i in range(high_p + 1): if(i == x): left_cc = "{" right_cc = "}" else: left_cc = " " right_cc = " " if(printable(data_mem[i])): print("|" + left_cc + "%05d" % i + chr(data_mem[i]) + "%03d" % data_mem[i], end = right_cc) format_count += 1 if(format_count % 8 == 0): print("|") else: print("|" + left_cc + "%05d" % i + " " + "%03d" % data_mem[i], end = right_cc) format_count += 1 if(format_count % 8 == 0): print("|") print("|") # print out stack if(top > 0): print() for i in range(top): print('{:03d}'.format(i), '{:03d}'.format(stack[i])) def prog_data(): print("\ntotal commands: ", tc - prog_mem.count("!")) print("total steps: ", steps) print("bracket nesting levels: ", nesting_levels) print("total bracket pairs: ", bracket_counter) print("parenthesis nesting levels: ", paren_nesting_levels) print("total parenthesis pairs: ", paren_counter) print("number of functions: ", number_of_functions) f = open(input("file name:"), 'r') while True: nextch = f.read(1) if(not nextch): f.close() break if(nextch in command_set): prog_mem += (nextch) tc = len(prog_mem) #Pre-Processing################################################# #print(prog_mem) ####################Brackets#################################### # check bracket integrity for i in range(tc): if(prog_mem[i] == "["): bc_counter += 1 nesting_levels = max(bc_counter, nesting_levels) elif(prog_mem[i] == "]"): bc_counter -= 1 if(bc_counter < 0): print("Grawlix Error: Bracket mismatch") quit() if(bc_counter != 0): print("Grawlix Error: Bracket mismatch") quit() # calculate bracket locations for i in range(tc): if(prog_mem[i] == '['): top += 1 stack[top] = i elif(prog_mem[i] == ']'): close_bracket[bracket_counter] = i open_bracket[bracket_counter] = stack[top] top -= 1 bracket_counter += 1 # print out arrays of open/close bracket locations (debugging) ''' for i in range(bracket_counter): print(i, ": ", open_bracket[i], close_bracket[i]) ''' ###################Parenthesis################################## # check parenthesis integrity for i in range(tc): if(prog_mem[i] == "("): paren_check_counter += 1 paren_nesting_levels = max(paren_check_counter, paren_nesting_levels) elif(prog_mem[i] == ")"): paren_check_counter -= 1 if(paren_check_counter < 0): print("Grawlix Error: Parenthesis mismatch") quit() if(paren_check_counter != 0): print("Grawlix Error: Parenthesis mismatch") quit() # calculate parenthesis locations for i in range(tc): if(prog_mem[i] == '('): top += 1 stack[top] = i elif(prog_mem[i] == ')'): close_paren[paren_counter] = i open_paren[paren_counter] = stack[top] top -= 1 paren_counter += 1 # print out arrays of open/close parenthesis locations (debugging) ''' for i in range(paren_counter): print(i, ": ", open_paren[i], close_paren[i]) ''' ###################Functions#################################### # check function integrity for i in range(tc): if(prog_mem[i] == "{"): number_of_functions += 1 brace_check_counter += 1 brace_nesting_levels = max(brace_check_counter, brace_nesting_levels) elif(prog_mem[i] == "}"): brace_check_counter -= 1 if(brace_check_counter < 0): print("Grawlix Error: Brace mismatch") quit() if(brace_check_counter != 0): print("Grawlix Error: Parenthesis mismatch") quit() # calculate function locations for i in range(tc): if(prog_mem[i] == '{'): top += 1 stack[top] = i elif(prog_mem[i] == '}'): close_brace[brace_counter] = i open_brace[brace_counter] = stack[top] top -= 1 brace_counter += 1 # print out open/close brace arrays (debugging) for i in range(brace_counter): print(i, ": ", open_brace[i], close_brace[i]) # run program ################################################# while(pc < len(prog_mem)): if(prog_mem[pc] == "+"): data_mem[p] = (data_mem[p] + 1) % 256 pc += 1 steps += 1 elif(prog_mem[pc] == "-"): data_mem[p] = (data_mem[p] - 1) % 256 pc += 1 steps += 1 elif(prog_mem[pc] == ">"): p += 1 high_p = max(p, high_p) pc += 1 steps += 1 elif(prog_mem[pc] == "<"): p -= 1 if(p < 0): print("Grawlix Error: Data Pointer Underflow") quit() pc += 1 steps += 1 elif(prog_mem[pc] == "."): if(printable(data_mem[p])): print(chr(data_mem[p]), end = "") pc += 1 steps += 1 # enter one char at a time, or several # they will be used as needed # use one more prompt to enter (cr) for EOF elif(prog_mem[pc] == ","): if(input_buffer == ""): input_buffer = input(": ") if(input_buffer == ""):# still empty - (cr) entered data_mem[p] = 0 else: key_press = input_buffer[0] input_buffer = input_buffer[1:] data_mem[p] = ord(key_press) pc += 1 steps += 1 elif(prog_mem[pc] == "["): steps += 1 if(data_mem[p] == 0): pc = close_bracket[open_bracket.index(pc)] + 1 else: pc += 1 elif(prog_mem[pc] == "]"): steps += 1 pc = open_bracket[close_bracket.index(pc)] # Grawlix commands ############################################# elif(prog_mem[pc] == "|"):# left shift data_mem[p] = (data_mem[p] << 1) % 256 pc += 1 steps += 1 elif(prog_mem[pc] == "/"):# right shift data_mem[p] = data_mem[p] >> 1 pc += 1 steps += 1 elif(prog_mem[pc] == ":"):# push stack[top] = data_mem[p] top += 1 top_max = max(top, top_max) pc += 1 steps += 1 elif(prog_mem[pc] == ";"):# pop top -= 1 if(top < 0): print("Grawlix Error: Stack Underflow") quit() data_mem[p] = stack[top] pc += 1 steps += 1 elif(prog_mem[pc] == "?"):# input decimal number data_mem[p] = int(input("Enter Decimal Number: ")) % 256 pc += 1 steps += 1 elif(prog_mem[pc] == "="):# output decimal number print('{:03d}'.format(data_mem[p]), end = "") pc += 1 steps += 1 elif(prog_mem[pc] == "^"):# stop print("\nGrawlix Command Stop") pc += 1 steps += 1 dump(p) prog_data() quit() elif(prog_mem[pc] == "("): steps += 1 if(data_mem[p] == 0): pc += 1 else: pc = close_paren[open_paren.index(pc)] + 1 elif(prog_mem[pc] == ")"): steps += 1 pc = open_paren[close_paren.index(pc)] elif(prog_mem[pc] == "{"):# skip function code pc = close_brace[open_brace.index(pc)] + 1 steps += 1 elif(prog_mem[pc] == "}"): function_return_top -= 1 pc = function_return_stack[function_return_top] steps += 1 elif(prog_mem[pc] == "@"): steps += 1 function_return_stack[function_return_top] = pc + 1 function_return_top += 1 top -= 1 function_call_number = stack[top] if(function_call_number > (number_of_functions - 1)): print("Grawlix Error: No Function", function_call_number) quit() else: pc = open_brace[function_call_number] + 1 elif(prog_mem[pc] == "!"): pc += 1 dump(p) elif(prog_mem[pc] == "#"): pc += 1 dump(p) temp = input("Pause") # print out program data prog_data()