Execode/Original implementation

From Esolang
Jump to navigation Jump to search
Back to Execode

Warning: this may not yet be completely bug-free.

import sys
program = input("Program: ")
while program[-3:] != 'ter':
   program += '\n' + input()
program = program.split('\n')
inpt = [int(st) if st else 0 for st in input("Input: ").split(',')]
variables = {}
stax = {}
functions = {}
index = 0
def execode(ind):
   global program, inpt, variables, stax, functions, index
   try:
       comm = program[ind]
   except IndexError:
       sys.exit()
   repeatimes = 1
   if 'rpt' in comm:
       rptindex = comm.index('rpt')
       repeatimes = int(comm[rptindex + 4:])
       comm = comm[:rptindex]
   for n in range(repeatimes):
       corecomm = comm[:3]
       if corecomm == 'def':
           if comm[4:7] == 'fnc':
               functions[int(comm[8:])] = ind + 1
               index += 1
               while program[index] != 'end':
                   index += 1
           elif comm[4:7] == 'var':
               variables[int(comm[8:])] = 0
           elif comm[4:7] == 'stk':
               stax[int(comm[8:])] = []
       elif corecomm == 'pop':
           if 'to' in comm:
               toindex = comm.index('to')
               varid = int(comm[toindex + 3:])
               comm = comm[:toindex]
               try:
                   variables[varid] = stax[int(comm[4:])].pop()
               except IndexError: ...
           else:
               try:
                   stax[int(comm[4:])].pop()
               except IndexError: ...
       elif corecomm == 'out':
           if comm[3:6] == 'str':
               stackstr = stax[int(comm[7:])]
               for value in stackstr:
                   print(chr(value), end="")
           elif comm[3:6] == 'stk':
               stackout = stax[int(comm[7:])]
               for value in stackout:
                   print(value, end=",")
               print()
           elif comm[3:6] == 'chr':
               print(chr(variables[int(comm[7:])]), end="")
           else:
               print(variables[int(comm[4:])])
       elif corecomm == 'psh':
           toindex = comm.index('to')
           stkid = int(comm[toindex + 3:])
           comm = comm[:toindex]
           stax[stkid].append(variables[int(comm[4:])])
       elif corecomm == 'rev':
           stax[int(comm[4:])].reverse()
       elif corecomm == 'inp':
           try:
               variables[int(comm[4:])] = inpt.pop(0)
           except IndexError: ...
       elif corecomm == 'con':
           operator = None
           if 'eq' in comm:
               operator = 'eq'
           elif 'ne' in comm:
               operator = 'ne'
           elif 'gt' in comm:
               operator = 'gt'
           if operator:
               opindex = comm.index(operator)
               var2 = variables[int(comm[opindex + 3:])]
               comm = comm[:opindex]
               var1 = variables[int(comm[4:])]
               statement = str(var1) + ' ' + operator + ' ' + str(var2)
           else:
               statement = str(variables[int(comm[4:])])
           statement = statement.replace('eq', '==').replace('ne', '!=').replace('gt', '>')
           if not eval(statement):
               index += 1
       elif corecomm == 'inc':
           variables[int(comm[4:])] += 1
       elif corecomm == 'dec':
           variables[int(comm[4:])] -= 1
       elif corecomm == 'cll':
           index_ = index + 1 - 1
           call_function(variables[int(comm[4:])])
           index = index_
       elif corecomm == 'ter':
           index = 1000000
def call_function(fncid):
   global index
   index = functions[fncid]
   while program[index] != 'end':
       execode(index)
       index += 1
while True:
   try: execode(index)
   except RecursionError:
       print("Function call limit reached", file=sys.stderr)
   except:
       print("Error at line %d" % index) if index != 1000001 else ...
       sys.exit(1)
   index += 1

A major problem with this interpreter is the inevitable Recursion Error which occurs at about the 500th function call.

Exechars interpreter

Back to Exechars

Note: The input is still entered as decimal.
Warning: this may not yet be completely bug-free.
An interpreter for Exechars modified from the above:

import sys
program = input("Program: ")
inpt = [int(st) if st else 0 for st in input("Input: ").split(',')]
variables = {}
stax = {}
functions = {}
index = 0
repeatimes = 1
commlist = ['(', ')', '+', '-', 'r', '^', '*', '&', 'i', 'o', 'n', 's', 'l', '?', '=', '!', '<', 'v', '>', '/', 't']
temp = []
def get_number(ind):
   ind += 1
   while program[ind] not in commlist:
       ind += 1
   if program[ind] == 'v':
       return variables[int(program[index+1:ind], 16)]
   else:
       return int(program[index+1:ind], 16)
def execode(ind):
   global program, inpt, variables, stax, functions, index, repeatimes, temp
   try:
       comm = program[ind]
   except IndexError:
       sys.exit()
   if comm not in commlist:
       return
   elif comm == 'r':
       repeatimes = get_number(ind)
       return
   elif comm == 'v':
       return
   for n in range(repeatimes):
       if comm == '(':
           functions[get_number(ind)] = ind + 1
           index += 1
           while program[index] != ')':
               index += 1
       elif comm == '*':
           temp = ['*', get_number(ind)]
       elif comm == '^':
           temp = ['^', get_number(ind)]
       elif comm == 's':
               stackstr = stax[get_number(ind)]
               for value in stackstr:
                   print(chr(value), end="")
       elif comm == 'l':
               stackout = stax[get_number(ind)]
               for value in stackout:
                   print(value, end=",")
               print()
       elif comm == 'o':
               print(chr(variables[get_number(ind)]), end="")
       elif comm == 'n':
               print(variables[get_number(ind)], end="")
       elif comm == '&':
           stax[get_number(ind)].reverse()
       elif comm == 'i':
           try:
               variables[get_number(ind)] = inpt.pop(0)
           except IndexError:
               variables[get_number(ind)] = 65535
       elif comm == '?':
           temp = ['?', get_number(ind)]
       elif comm == '+':
           try:
               variables[get_number(ind)] += 1
           except KeyError:
               variables[get_number(ind)] = 1
       elif comm == '-':
           try:
               variables[get_number(ind)] -= 1
           except KeyError:
               variables[get_number(ind)] = -1
       elif comm == '/':
           index_ = index + 1 - 1
           call_function(get_number(ind))
           index = index_
       elif comm == '>':
           if temp[0] == '*':
               try:
                   variables[get_number(ind)] = stax[temp[1]].pop()
               except IndexError:
                   variables[get_number(ind)] = 65535
               except KeyError:
                   stax[temp[1]] = []
           elif temp[0] == '^':
               try:
                   stax[get_number(ind)].append(variables[temp[1]])
               except KeyError:
                   try:
                       stax[get_number(ind)].append(0)
                       variables[temp[1]] = 0
                   except KeyError:
                       try:
                           stax[get_number(ind)] = [variables[temp[1]]]
                       except KeyError:
                           variables[temp[1]] = 0
                           stax[get_number(ind)] = [variables[temp[1]]]
           temp = []
       elif comm == '<':
           if variables[temp[1]] >= variables[get_number(ind)]:
               index += 1
               while program[index] not in commlist or program[index] == 'v':
                   index += 1
               index += 1
           temp = []
       elif comm == '=':
           if variables[temp[1]] != variables[get_number(ind)]:
               index += 1
               while program[index] not in commlist or program[index] == 'v':
                   index += 1
               index += 1
           temp = []
       elif comm == '!':
           if variables[temp[1]] == variables[get_number(ind)]:
               index += 1
               while program[index] not in commlist or program[index] == 'v':
                   index += 1
               index += 1
           temp = []
       elif comm == 't':
           index = 1000000
   repeatimes = 1
def call_function(fncid):
   global index
   index = functions[fncid]
   while program[index] != ')':
       try: execode(index)
       except RecursionError:
           print("Function call limit reached", file=sys.stderr)
           sys.exit(1)
       except:
           print("Error at program index %d" % index, file=sys.stderr) if index != 1000001 else ...
           sys.exit(1)
       index += 1
while True:
   try: execode(index)
   except RecursionError:
       print("Function call limit reached", file=sys.stderr)
       sys.exit(1)
   except:
       print("Error at program index %d" % index, file=sys.stderr) if index != 1000001 else ...
       sys.exit(1)
   index += 1

Like the above, a major problem with this interpreter is the inevitable Recursion Error which occurs at about the 500th function call.