A port of my language (https://github.com/ChickChicky/eegggg/) for the numworks calculator
def tokenize(source): tokens=[];token='';skip=0;instr=False for c in source: if skip>0:skip-=1 token+=c if not instr: if c in ' +-*/$&^|}{;?<>!,%~@#=:\n': l=(tokens[-1]if len(tokens)>0 else'')+c if l in['>#','<#','>:','<:','>::','<::','>>','<<']:tokens.pop();tokens.append(l);token='' else:token=token[:-1];tokens.append(token);tokens.append(c);token='' if c=='"'and len(token)==1:instr = True else: if skip==0: if c=='"':instr = False if c=='\\':skip = 2 if token:tokens.append(token) return list(filter(lambda tk:len(tk.strip()),tokens)) class EggScript: def __init__(self,tokens,functions):self.tokens=tokens;self.functions=functions;self.contexts=[tokens]+list(functions.values()) def parse(source): tokens:list[str]=[];functions={};ctx=tokens;fnname=False;ctx.append(ctx) for tk in source: if tk=='f':fnname=True;continue elif tk=='end':ctx=ctx[0] elif fnname:functions[tk]=ctx=[];ctx.append(tokens);fnname=False elif isidentifier(tk[:-1])and tk[-1]==':':vars[tk[:-1]]=len(ctx)-1 else:ctx.append(tk) return EggScript(tokens,functions) def isfloatstr(s): try:float(s);return True except:return False def isidentifier(s): for c in s: if ord(c.upper())not in range(65,90)and s!='_':return False return True class EggRunner: ExecContinue=0 ExecDone=1 def __init__(self,source): self.source=source;self.script=parse(tokenize(self.source));self.stacks=[[]] for ctx in self.script.contexts:ctx.insert(1,0);ctx.insert(2,None) self.ctx=self.script.tokens;self.ctx[0]=self.ctx;self.ctx[2]=self.ctx;self.done=False def step(self): if self.done:return EggRunner.ExecDone done=False while len(self.ctx) < self.ctx[1]+4: if self.ctx[0]==self.ctx:done=True;break self.ctx[1]=0;self.ctx=self.ctx[2];self.stacks.pop() if done:self.done=True;return EggRunner.ExecDone stack=self.stacks[-1];tk=self.ctx[self.ctx[1]+3] if isfloatstr(tk):stack.append(float(tk)) if isidentifier(tk):self.ctx[1]+=1;octx=self.ctx;self.ctx=self.script.functions[tk];self.ctx[2]=octx;self.stacks.append([]);return EggRunner.ExecContinue if tk[:1]=='"'and tk[-1:]=='"':stack.append(tk[1:-1]) if tk=='>#':stack.append(self.stacks[-2].pop()) if tk=='<#':self.stacks[-2].append(stack.pop()) if tk=='<<':self.stacks[-2].extend(stack) if tk=='>>':stack.extend(self.stacks[-2]) if tk=='>:': it=int(stack.pop()) for i in range(it):stack.append(self.stacks[-2][-it+i]) for i in range(it):self.stacks[-2].pop() if tk=='<:': it=int(stack.pop()) for i in range(it):self.stacks[-2].append(stack[-it+i]) for i in range(it):stack.pop() if tk=='>::': for i in range(stack.pop()):stack.append(self.stacks[-2].pop()) if tk=='<::': for i in range(stack.pop()):self.stacks[-2].append(stack.pop()) if tk=='#':stack.append(stack[-1]) if tk==':':stack[len(stack):]=stack[-int(stack.pop()):] if tk=='::': it=int(stack.pop());rep=int(stack.pop());val=stack[-it:] for i in range(rep):stack[len(stack):]=val if tk=='~#':stack[-2:]=reversed(stack[-2:]) if tk == '~:':sz=stack.pop();stack[-sz:]=reversed(stack[-sz]) if tk=='=':self.ctx[1]=float('inf') if tk in('+','-','*','/','%','**','<','>','==','>=','<='): b = stack.pop() a = stack.pop() if tk=='+':stack.append(a+b) if tk=='-':stack.append(a-b) if tk=='*':stack.append(a*b) if tk=='/':stack.append(a/b) if tk=='%':stack.append(a%b) if tk=='**':stack.append(a**b) if tk=='<':stack.append(float(a<b)) if tk=='>':stack.append(float(a>b)) if tk=='<=':stack.append(float(a<=b)) if tk=='>=':stack.append(float(a>=b)) if tk=='==':stack.append(float(a==b)) if tk=='?': dest=stack.pop();cond=stack.pop()if len(stack)else 0 if cond>0:self.ctx[1]=int(dest-1) if tk=='!':self.ctx[1]=int(stack.pop()-1) if tk=='@':print('\t'.join(map(str,stack))) if tk=='{':self.stacks.append([]) if tk=='}':self.stacks.pop() if tk==';':stack.clear() self.ctx[1]+=1 def run(self): while self.step()!=EggRunner.ExecDone:pass