# Copyright (c) 2026 weimofei
# telus is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON‑INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
import sys,subprocess,time
from dataclasses import dataclass
from collections import deque
outputs=[]
verbose=0
__version__="telus v1.5.12,patch +275"
class TelusException(Exception):
    pass
class TelusVMStackIsEmptyError(TelusException):
    pass
class TelusVMUnknownOpError(TelusException):
    pass
class TelusVMDivisionZeroError(TelusException):
    pass
class Estack:
    def __init__(self):
        self.stktop=0
        self.array=[-1]*1048576
    def __getitem__(self,index):
        if (not isinstance(index,slice)) and index>=self.stktop:
            raise Exception("index too long")
        val=self.array[index]
        return val
    def append(self,val):
        self.stktop+=1
        self.array[self.stktop]=val
    def pop(self):
        val=self.array[self.stktop]
        self.array[self.stktop]=-1
        self.stktop-=1
        return val
def Een(estack):
    if isinstance(estack,list):
        print(estack)
    else:return estack.stktop
the_prompt = [
    "=====  T e l u s  =====",
    "The Telus",
    "",
    "词元流淌，拆解每一行人间字句",
    "FIRST集合拦截非法的开篇符号",
    "嵌套深度锁住递归无尽的梦魇",
    "残缺的括号化作普通报错的呢喃",
    "",
    "方括号之内，可栖if辗转的枝干",
    "负索引回溯字符串末尾的星斑",
    "下标越界，抛出温柔的警戒呼喊",
    "不必崩溃，会话依旧可以扬帆",
    "",
    "万物皆对象，是馈赠也是劫难",
    "内置函数伫立在作用域的此岸",
    "倘若强行改写，赋值为数字空元", 
    "Fatal红色警告撕碎整片终端",
    "进程就此落幕，一切归于尘烟",
    "",
    "解析器游走在每一处边界考验",
    "无数畸形输入尽数化为轻谈",
    "多数错误仅仅是可恢复的羁绊",
    "唯有篡改内置，招来死亡的审判",
    "",
    "在字节与符号之间慢慢生长",
    "于漏洞与防护之中奔赴万丈星光",
    "自由从不代表肆意的疯狂",
    "每一行代码，皆是灵魂的回响",
    "",
    "======== END ========",
    "Author:weimofei",
    "..........",
    ".........",
    "........",
    ".......",
    "......",
    ".....",
    "....",
    "...",
    "..",
    ".",
]
def scroll_output():
    begin=0
    end=0
    window=3
    while end<len(the_prompt):
        try:
            subprocess.call("cls",shell=True)
            for i in range(begin,end+1):
                print(the_prompt[i])
            end+=1
            if end-begin==window:
                begin+=1
            time.sleep(0.7)
        except KeyboardInterrupt:
            print("按下Ctrl+C,停止播放Telus之诗《The Telus》")
            break
    subprocess.call("cls",shell=True)
    begin+=1
    print(the_prompt[begin])
    subprocess.call("cls",shell=True)
def custom_(x):
    if x=="The Telus":scroll_output()
    outputs.append(x) 
def totype(tp,data):
    if tp=="float":return float(data)
    if tp=="int":return int(data)
    if tp=="str":return str(data)
follow_factor=["PLUS","MINUS","MUL","DIV",0x0b,"FLOORDIV","AND","OR","RPAREN","EOF"]
follow_begin_factor=["IF","NAME","NOT","LPAREN","EOF","MINUS"]
allow_chars=["+","-","*","/","&","|","_","[","]","(",")","%","{","}"]
for charascii in range(65,65+26):
    allow_chars.append(chr(charascii))
for charascii in range(97,97+26):
    allow_chars.append(chr(charascii))
for charascii in range(48,48+10):
    allow_chars.append(chr(charascii))
def raiseExc(info):
    raise Exception(f"人为触发的错误:{info}")
assign_flag=1
global_cache_tokens={} 
class Lexer:
    def __init__(self,text):
        self.text=text.strip()
        self.pos=0
        self.saved_token=[]
        self.current_char=self.text[self.pos] if self.text else None
    def advance(self):
        self.pos+=1
        if self.pos>=len(self.text):
            self.current_char=None
        else:
            self.current_char=self.text[self.pos]
    def skip_whitespace(self):
        while self.current_char is not None and (self.current_char.isspace() and (self.current_char!="\n")):
            self.advance() 
    def integer(self):
        result=""
        while self.current_char is not None and self.current_char.isdigit():
            result+=self.current_char
            self.advance()
        return result
    def identifier(self):
        result=""
        while self.current_char is not None and self.current_char.isalpha() or self.current_char=="_":
            result+=self.current_char
            self.advance()
        return result
    def get_string_content(self,is_db):
        result=""
        while self.current_char is not None and self.current_char!=("\"" if is_db else "'"):
            if self.current_char=="\\":
                self.advance()
                if self.current_char=="n":
                    result+="\n"
                if self.current_char=="\"":
                    result+="\""
                if self.current_char=="'":
                   result+="'"
                self.advance()
                continue 
            result+=self.current_char
            self.advance()
        self.advance()
        return result
    def get_next_token(self):
        while self.current_char is not None:
            if self.current_char.isspace() and (self.current_char!="\n"):
                self.skip_whitespace()
                continue
            if self.current_char=="\"" or self.current_char=="'":
                char=self.current_char
                self.advance()
                return ("STRING",self.get_string_content(char=="\""))
            if self.current_char.isdigit():
                num=int(self.integer())
                if self.current_char==".":
                    self.advance()
                    num=float(str(num)+"."+self.integer())
                return ("NUMBER",num)
            if self.current_char=="<":
                self.advance()
                if self.current_char=="=":
                    self.advance()
                    return ("LESS_OR_EQUAL","<=")
                else:
                    return ("LESS","<")
            if self.current_char==">":
                self.advance()
                if self.current_char=="=":
                    self.advance()
                    return ("GREATER_OR_EQUAL",">=")
                else:
                    return ("GREATER",">")
            if self.current_char=="!":
                self.advance()
                if self.current_char=="=":
                    self.advance()
                    return ("NOT_EQUAL","!=")
                return ("NOT","!")
            if self.current_char=="&":
                self.advance()
                return "AND","&"
            if self.current_char=="|":
                self.advance()
                return "OR","|"
            
            if self.current_char.isalpha() or self.current_char=="_":
                ident=self.identifier()
                if ident=="if":
                    return "IF",None
                if ident=="else":
                    return "ELSE",None
                if ident=="wloop":
                    return "WLOOP",None
                if ident=="true":
                    return "BOOLEAN",1
                if ident=="false":
                    return "BOOLEAN",0
                if ident in ["int","str","float"]:
                    return "STATIC_TYPE",ident
                return "NAME",ident
            if self.current_char=="/":
                self.advance()
                if self.current_char=="/":
                    self.advance()
                    return "FLOORDIV","//"
                return "DIV","/"

            if self.current_char=="=":
                self.advance()
                if self.current_char=="=":
                    self.advance()
                    return "EQUAL","=="
                else:
                    return "ASSIGN","="
           
            opers={"+":("PLUS","+"),
                "-":("MINUS","-"),
                "*":("MUL","*"),
                "%":(0x0b,"%"),
                "(":("LPAREN","("),
                ")":("RPAREN",")"),
                "[":("LBRACK","["),
                "]":("RBRACK","]"),
                "{":("LBRACE","{"),
                "}":("RBRACE","}"),
                "\n":("NEWLINE","\n"),
                ";":("SEMI",";")
            }
            char=self.current_char
            if self.current_char in opers.keys():
                self.advance()
                return opers[char]
            if self.current_char not in allow_chars:
                raise Exception("不合法的字符")
        return ("EOF",None)
bytearr=[]
class Parser:
    def __init__(self,lexer:Lexer):
        self.lexer=lexer
        self.buffer=deque()
    def pulltoken(self):
        tok=self.lexer.get_next_token()
        self.buffer.append(tok)
    def peek(self,offset=0,is_cur=False):

        while len(self.buffer)<=offset:
            self.pulltoken()
        return self.buffer[offset]
    @property
    def current_token(self):
        return self.peek(0,True)
    def skip_newlines(self):
        while True:
            tok=self.current_token
            if tok[0]=="NEWLINE":
                self.eat("NEWLINE")
            else:
                break
    def eat(self,token_type):
        #避免eat前还没有加入缓冲去的元素
        if len(self.buffer)==0:
            # print("Warning:缓冲区长度为零,将自动填充")
            self.peek(0)
        #修复了一堆问题
        x=self.buffer[0]
        if x[0]==token_type:
            self.buffer.popleft()
        else:
            raise Exception("无法消费token")
    def call(self,name):
        self.eat("LPAREN")
        node=self.equality()
        if verbose:print("CALL-FUNCTION!")
        self.eat("RPAREN")
        return ("CALL",name,node)
    def block(self):
        if verbose:print("Parse Block!")
        self.skip_newlines()
        self.eat("LBRACE")
        block_body=["BLOCK",]
        while self.current_token[0]!="RBRACE":
            self.skip_newlines()
            if self.current_token[0]=="RBRACE":break
            node=self.parse()
            block_body.append(node)
            if self.current_token[0]=="SEMI":
                self.eat("SEMI")
        self.eat("RBRACE")
        return tuple(block_body)
    def factor(self):
        token=self.current_token
        if verbose:print("factor",token)
        if token[0]=="NUMBER":
            self.eat("NUMBER")
            return ("NUM",token[1])
        if token[0]=="BOOLEAN":
            self.eat("BOOLEAN")
            return ("BOOL",token[1])
        if token[0]=="STRING":
            self.eat("STRING")
            if self.current_token[0]=="LBRACK":
                if verbose:
                    print("subscript!")
                self.eat("LBRACK")
                node=self.expr()
                self.eat("RBRACK")
                return ("SUBSCRIPT",("STR",token[1]),node)
            return ("STR",token[1])
        if token[0]=="NAME":
            self.eat("NAME") 
            if token[1]=="f" and self.current_token[0]=="STRING":
                newtoken=self.current_token
                self.eat("STRING")
                if verbose:print("F-STRING!")
                return "FSTR",newtoken[1]
            if token[1]=="n" and self.current_token[0]=="NUMBER":
                newtoken=self.current_token
                self.eat("NUMBER")
                if verbose:print("N-NUMBER!")
                return "NUM",-newtoken[1]
            if self.current_token[0]=="ASSIGN":
                self.eat("ASSIGN")
                if verbose:print("assignment!")
                return "ASSIGN",token[1],self.equality()
            if self.current_token[0]=="LBRACK":
                
                self.eat("LBRACK")
                node=self.equality()
                if verbose:print("subscript!")
                self.eat("RBRACK")
                return ("SUBSCRIPT",("VAR",token[1]),node)
            if self.current_token[0]=="LPAREN":
                return self.call(token[1])
           
            if self.current_token[0] in follow_factor:
                return ("VAR",token[1])
            else:
                raise Exception(f"当前{self.current_token}不在{token}的合法终结符里")
        if token[0]=="LPAREN":
            self.eat("LPAREN")        
            node=self.equality()
            if verbose:print("normal parenexpr!")
            self.eat("RPAREN")
            return node
        if token[0]=="IF":
            if verbose:print("IF!")
            self.eat("IF")
            self.eat("LPAREN")
            node=self.equality()
            self.eat("RPAREN")
            exp1=self.block()
            if self.current_token[0]!="ELSE":
                return ("IF",node,exp1)
            self.eat("ELSE")
            exp2=self.block()
            return ("IF",node,exp1,exp2)
        if token[0]=="LOOP":
            self.eat("LOOP")
            self.eat("LPAREN")
            node=self.equality()
            self.eat("RPAREN")
            exp=self.block()
            return ("LOOP",node,exp)
        if token[0]=="NOT":
            self.eat("NOT")
            if verbose:print("NOT!")
            node=self.expr()
            return ("NOT",node)
        if token[0] not in follow_begin_factor:
            raise Exception(f"{token[0]}不允许出现在开头")
    def term(self):
        if verbose:print("term...")
        node=self.unary()
        while self.current_token[0] in ("MUL","DIV","FLOORDIV",0x0b):
            token=self.current_token
            if token[0]=="MUL":
                self.eat("MUL")
            if token[0]=="DIV":
                self.eat("DIV")
            if token[0]=="FLOORDIV":
                self.eat("FLOORDIV")
            if token[0]==0x0b:
                self.eat(0x0b)
            node=(token[0],node,self.unary())
        return node
    def expr(self):
        if verbose:print("expr...")
        node=self.term()
        while self.current_token[0] in ("PLUS","MINUS","AND","OR"):
            token=self.current_token
            if token[0]=="PLUS":
                self.eat("PLUS")
            if token[0]=="MINUS":
                self.eat("MINUS")
            if token[0]=="AND":
                self.eat("AND")
            if token[0]=="OR":
               self.eat("OR")
            node=(token[0],node,self.term())
        return node
    def postfix(self):
        if verbose:print("postfix...")
        node=self.factor()
        while self.current_token[0] in ("LPAREN","LBRACK"):
            if self.current_token[0]=="LPAREN":
                if node[0]=="VAR":
                    node=self.call(node[1])
                else:
                    raise Exception("不能调用非标识符")
            elif self.current_token[0]=="LBRACK":
                self.eat("LBRACK")
                ind=self.equality()
                self.eat("RBRACK")
                node=("SUBSCRIPT",node,ind)
        return node
    def unary(self):
        oplist=[]
        while self.current_token[0] in ("NOT","PLUS","MINUS"):
            optype=self.current_token[0]
            oplist.append(optype)
            self.eat(optype)
        node=self.postfix()
        for op in oplist[::-1]:
            node=(op,node)
        return node
    def compare(self):
        node=self.expr()
        while self.current_token[0] in ("GREATER","GREATER_OR_EQUAL","LESS","LESS_OR_EQUAL"):
            token=self.current_token
            if token[0]=="GREATER_OR_EQUAL":
                self.eat("GREATER_OR_EQUAL")
            if token[0]=="LESS_OR_EQUAL":
                self.eat("LESS_OR_EQUAL")
            if token[0]=="GREATER":
                self.eat("GREATER")
            if token[0]=="LESS":
                self.eat("LESS")
            node=(token[0],node,self.expr())
        return node 
    def equality(self):
        node=self.compare()
        while self.current_token[0] in ("NOT_EQUAL","EQUAL"):
            token=self.current_token
            if token[0]=="NOT_EQUAL":
                self.eat("NOT_EQUAL")
            if token[0]=="EQUAL":
                self.eat("EQUAL")
            node=(token[0],node,self.compare())
        return node
    def parse(self):
        x=self.equality()
        return x
class SemanticAnalyzer:
    def __init__(self):
        self.parsed_ast=[]
    def semantic_analyze(self,node):
        if not isinstance(node,tuple):
            return node
        if node[0]=="FTSTR":
            parts=[]
            raw=node[1]
            pos=0
            n=len(raw)
            while pos<n:
                if raw[pos]!="{":
                    pos+=1
                    continue
                pos+=1
                stack=1
                start=pos
                in_string=0
                
                while pos<n and stack>0:
                    if raw[pos]=="\"" and (pos==0 or raw[pos-1]=="\\"):
                        in_string=not in_string
                    if raw[pos]=="{":
                        if in_string:
                            pos+=1
                            continue
                        stack+=1
                    elif raw[pos]=="}": 
                        if in_string:
                            pos+=1
                            continue
                        stack-=1
                        if stack<0:
                            raise Exception("f-string内有未匹配的}")
                    pos+=1
                if stack<0:
                    raise Exception("f-string内有未匹配的}")
                if stack>0:
                    raise Exception("f-string内有未匹配的{")
                expst=raw[start:pos-1]
                parts.append(expst)
            self.parsed_ast=["FSTR",parts]
            return ("FSTR",parts)
        result=[node[0]]
        for lastnode in node[1:]:
            result.append(self.semantic_analyze(lastnode))
        self.parsed_ast=result
        return tuple(result)
class BytecodeCompiler:
    def __init__(self):
        self.code=[]
        self.labelcnt=0

    def addlabel(self):
        self.labelcnt+=1
        return f"L{self.labelcnt}"
    def visit(self,node):
        if verbose==1:
            print("visit...",node)
        global assign_flag
        if node==None:
            return ""
        if node[0]=="BLOCK":
            count=len(node)-1
            for index,code in enumerate(node[1:]):
                self.visit(code)
                if index!=count-1:
                    self.code.append((0x06,))
            return

        if node[0]=="NUM":
            self.code.append((0x01,node[1]))
            return
        if node[0]=="STR":
            self.code.append((0x02,node[1]))
            return
        if node[0]=="FSTR":
            raw=node[1]
            parts=[]
            text=""
            pos=0
            n=len(raw)
            while pos<n:
                if raw[pos]!="{":
                    text+=raw[pos]
                    pos+=1
                    continue
                if text:
                    parts.append(("TEXT",text))
                    text=""
                pos+=1
                stack=1
                start=pos
                while pos<n and stack>0:
                    if raw[pos]=="{":
                        stack+=1
                    elif raw[pos]=="}":
                        stack-=1
                    pos+=1
                if stack<0 or stack>0:
                    raise Exception("f-string内有未匹配的{}")
                parts.append(("EXPR",raw[start:pos-1]))
            if text:
                parts.append(("TEXT",text))
            if not parts:
                self.code.append((0x02,""))
                return
            for i,(kind,content) in enumerate(parts):
                if kind=="TEXT":
                    self.code.append((0x02,content))
                else:
                    lex=Lexer(content)
                    p=Parser(lex)
                    self.visit(p.expr())
                    self.code.append((0x10,"str",1))
                if i>0:
                    self.code.append((0x07,))
            return
        if node[0]=="BOOL":
            self.code.append((0x0d,node[1]))
            return
        if node[0]=="VAR":
            self.code.append((0x03,node[1]))
            return
        if node[0]=="CALL":
            funcname=node[1]
            arg=node[2]
            self.visit(node[2])
            self.code.append((0x10,funcname,1))
            return
        if node[0]=="SUBSCRIPT":
            string=node[1]
            index=node[2]
            self.visit(string)
            self.visit(index)
            self.code.append((0x13,))
            return 
        if node[0]=="IF":
            cond=node[1]
            leftv=node[2]
            rlabel=self.addlabel()
            endlb=self.addlabel()
            self.visit(cond)
            self.code.append((0x0f,rlabel))
            self.visit(leftv)
            self.code.append((0x0c,endlb))
            self.code.append(("LABEL",rlabel))
            if len(node)==4:
                self.visit(node[3])
            self.code.append(("LABEL",endlb))
            return
        if node[0]=="WHILE":
            cond=node[1]
            leftv=node[2]
            rlabel=self.addlabel()
            endlb=self.addlabel()
            self.visit(cond)
            self.code.append((0x0f,rlabel))
            self.visit(leftv)
            self.code.append((0x0c,endlb))
            self.code.append(("LABEL",rlabel))
            if len(node)==4:
                self.visit(node[3])
            self.code.append(("LABEL",endlb))
            return
        
        if node[0] in ("PLUS","MINUS","MUL","DIV","FLOORDIV","MOD",0x0b,"NOT","EQUAL","NOT_EQUAL","LESS","GREATER","LESS_OR_EQUAL","GREATER_OR_EQUAL"):
            op_map={
                "PLUS":0x07,"MINUS":0x08,"MUL":0x09,"DIV":0x0a,"MOD":0x0b,"FLOORDIV":0x1b,"EQUAL":0x11,"NOT_EQUAL":0x12,"LESS":0x14,"GREATER":0x15,"LESS_OR_EQUAL":0x16,"GREATER_OR_EQUAL":0x17,0x0b:0x0b
            }
            unary_op_map={
                "PLUS":0x18,"MINUS":0x19,"NOT":0x1A
            }
            if len(node)==2:
                oper=node[1]
                self.visit(oper)
                self.code.append((unary_op_map[node[0]],))
                return
            left_val=node[1]
            right_val=node[2]
            self.visit(left_val)
            self.visit(right_val)
            self.code.append((op_map[node[0]],))
            return
        if node[0]=="AND":
            end_label=self.addlabel()
            after_label=self.addlabel()
            self.visit(node[1])
            self.code.append((0x0f,end_label))
            self.visit(node[2])
            self.code.append((0x0c,after_label))
            self.code.append(("LABEL",end_label))
            self.code.append((0x01,0))
            self.code.append(("LABEL",after_label))
            return
        if node[0]=="OR":
            end_label=self.addlabel()
            after_label=self.addlabel()
            self.visit(node[1])
            self.code.append((0x0e,end_label))
            self.visit(node[2])
            self.code.append((0x0c,after_label))
            self.code.append(("LABEL",end_label))
            self.code.append((0x0d,1))
            self.code.append(("LABEL",after_label))
            return
        if node[0]=="ASSIGN":
            varname=node[1]
            varvalue=node[2]
            self.visit(node[2])
            self.code.append((0x05,))
            self.code.append((0x04,varname))
            return
    def finalize(self):
        label_table={}
        temp=[]
        output=[]
        for instr in self.code:
            if instr[0]=="LABEL":
                label_table[instr[1]]=len(temp)
            else:
                temp.append(instr)
        for instr in temp:
            if instr[0] in (0x0c,0x0e,0x0f):
                target_pos=label_table[instr[1]]
                output.append((instr[0],target_pos))
            else:
                output.append(instr)
        self.code=output
    def serialize(self):
        buf=bytearray()
        for op,args in self.code:
            if op==0x01:
                buf.append(op)
                buf.extend(args.to_bytes(4,byteorder="little",signed=True))
            elif op==0x02:
                buf.append(op)
                strbyt=args.encode("utf-8")
                buf.extend(len(strbyt).to_bytes(2,byteorder="little",signed=False))
                buf.extend(strbyt)
            elif op==0x0D:
                buf.append(op)
                buf.append(hex(arg&0x01))
            else:
                raise TelusVMUnknownOpError("未知Opcode")
class TelusVM:
    def __init__(self):
        self.heap=[]
        self.stack=Estack()
        self.env={}
        self.ptr=0
        self.callpool={"print":custom_,"input":input,"len":len,"str":str}
    def addheap(self,val):
        heap_top=len(self.heap)
        self.heap.append(val)
        return heap_top

    def run(self,instr_list):
        
        ptr=0
        while ptr<len(instr_list):
            instr=instr_list[ptr]
            op=instr[0]
            
            if op==0x01:
                number=instr[1]
                handle=self.addheap(number)
                self.stack.append(handle)
                ptr+=1
            elif op==0x02:
                string=instr[1]
                handle=self.addheap(string)
                self.stack.append(handle)
                ptr+=1
            elif op==0x03:
                var_name=instr[1]
                if var_name not in self.env:
                    raise TelusException(f"未知变量:{var_name}")
                val=self.env[var_name]
                self.stack.append(val)
                ptr+=1
            elif op==0x04:
                var_name=instr[1]
                if not self.stack:
                    raise TelusVMStackIsEmptyError("栈是空的")
                top=self.stack.pop()
                self.env[var_name]=top
                ptr+=1
            elif op==0x05:
                if not self.stack:
                    raise TelusVMStackIsEmptyError("栈是空的")
                top=self.stack[-1]
                self.stack.append(top)
                ptr+=1
            elif op==0x06:
                if not self.stack:
                    raise TelusVMStackIsEmptyError("栈是空的")
                self.stack.pop()
                ptr+=1
            elif op==0x07:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                handle1=self.stack.pop()
                handle2=self.stack.pop()
                val1=self.heap[handle1]
                val2=self.heap[handle2]
                handle3=self.addheap(val2+val1)
                self.stack.append(handle3)
                ptr+=1
            elif op==0x08:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                handle1=self.stack.pop()
                handle2=self.stack.pop()
                val1=self.heap[handle1]
                val2=self.heap[handle2]
                handle3=self.addheap(val2-val1)
                self.stack.append(handle3)
                ptr+=1
            elif op==0x09:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                handle1=self.stack.pop()
                handle2=self.stack.pop()
                val1=self.heap[handle1]
                val2=self.heap[handle2]
                handle3=self.addheap(val1*val2)
                self.stack.append(handle3)
                ptr+=1
            elif op==0x0A:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                handle1=self.stack.pop()
                handle2=self.stack.pop()
                val1=self.heap[handle1]
                val2=self.heap[handle2]
                if val1==0:
                    raise TelusVMDivisionZeroError("不能除以零")
                handle3=self.addheap(val2/val1)
                self.stack.append(handle3)
                ptr+=1
            elif op==0x0B:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                handle1=self.stack.pop()
                handle2=self.stack.pop()
                val1=self.heap[handle1]
                val2=self.heap[handle2]
                if val1==0:
                    raise TelusVMDivisionZeroError("不能模零")
                handle3=self.addheap(val2%val1)
                self.stack.append(handle3)
                ptr+=1
            elif op==0x0C:
                ptr=instr[1]
            elif op==0x0D:
                boolean=instr[1]
                handle=self.addheap(boolean)
                self.stack.append(handle)
                ptr+=1
            elif op==0x0E:
                top=self.heap[self.stack[-1]]
                self.stack.pop()
                if top:
                    ptr=instr[1]
                else:
                    ptr+=1
            elif op==0x0F:
                top=self.heap[self.stack[-1]]
                self.stack.pop()
                if top:
                    ptr+=1
                else:
                    ptr=instr[1]
            elif op==0x10:
                
                if Een(self.stack)<instr[2]:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                if instr[1] not in self.callpool:
                    raise TelusException(f"未知函数:{instr[1]}")
                args=map(lambda idx:self.heap[idx],self.stack[-instr[2]:])
                for _ in range(instr[2]):
                    self.stack.pop()

                handle=self.addheap(self.callpool[instr[1]](*args))
                self.stack.append(handle)
                ptr+=1
            elif op==0x11:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                val2=self.stack.pop()
                val1=self.stack.pop()
                handle=self.addheap(self.heap[val1]==self.heap[val2])
                self.stack.append(handle)
                ptr+=1
            elif op==0x12:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                val2=self.stack.pop()
                val1=self.stack.pop()
                handle=self.addheap(self.heap[val1]!=self.heap[val2])
                self.stack.append(handle)
                ptr+=1
            elif op==0x13:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                val2=self.stack.pop()
                val1=self.stack.pop()
                p=self.heap[val1]
                q=self.heap[val2]
                if q>=len(p) or q<-len(p):
                    raise TelusException(f"下标{q}越界")
                handle=self.addheap(p[q])
                self.stack.append(handle)
                ptr+=1
            elif op==0x14:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                val2=self.stack.pop()
                val1=self.stack.pop()
                handle=self.addheap(self.heap[val1]<self.heap[val2])
                self.stack.append(handle)
                ptr+=1
            elif op==0x15:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                val2=self.stack.pop()
                val1=self.stack.pop()
                handle=self.addheap(self.heap[val1]>self.heap[val2])
                self.stack.append(handle)
                ptr+=1
            elif op==0x16:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                val2=self.stack.pop()
                val1=self.stack.pop()
                handle=self.addheap(self.heap[val1]<=self.heap[val2])
                self.stack.append(handle)
                ptr+=1
            elif op==0x17:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                val2=self.stack.pop()
                val1=self.stack.pop()
                handle=self.addheap(self.heap[val1]>=self.heap[val2])
                self.stack.append(handle)
                ptr+=1
            elif op==0x18:
                ptr+=1
            elif op==0x19:
                handle=self.stack.pop()
                val=self.heap[handle]
                handle_result=self.addheap(-val)
                self.stack.append(handle_result)
                ptr+=1
            elif op==0x1A:
                handle=self.stack.pop()
                val=self.heap[handle]
                handle_result=self.addheap(not val)
                self.stack.append(handle_result)
                ptr+=1
            elif op==0x1B:
                if Een(self.stack)<2:
                    raise TelusVMStackIsEmptyError("栈元素太少")
                handle1=self.stack.pop()
                handle2=self.stack.pop()
                val1=self.heap[handle1]
                val2=self.heap[handle2]
                if val1==0:
                    raise TelusVMDivisionZeroError("不能除以零")
                handle3=self.addheap(val2//val1)
                self.stack.append(handle3)
                ptr+=1
            else:raise TelusVMUnknownOpError("未知OpCode")
bytecodecompiler=BytecodeCompiler()
VM=TelusVM()
def run(code):
    global outputs
    assign_flag=0
    outputs=[]
    VM.stack=Estack()
    lexer=Lexer(code)
    parser=Parser(lexer)
    ast=parser.parse()
    if verbose:print("ast",ast)
    bytecodecompiler.code=[]
    bytecodecompiler.visit(ast)
    bytecodecompiler.finalize()
    bytecode=bytecodecompiler.code
    VM.run(bytecode)
    return outputs       
    # token=lexer.get_next_token()
    # while token!=("EOF",None):   
    #     print(token)
    #     token=lexer.get_next_token()
if __name__=="__main__":
    if len(sys.argv)>1 and "--verbose" in sys.argv:
        verbose=1
    if len(sys.argv)>1 and "--version" in sys.argv:
        print(__version__)
        sys.exit(0)
    while True:
        try:
            code=input(f">")
            output=run(code)
            print("".join(map(str,output)))
        except KeyboardInterrupt:
            print("程序退出")
            break
        except RecursionError:
            print("代码嵌套过于长,请使用变量分段存储")
        # except Exception as e:
        #     print("程序报错,报错原因:",end="")
        #     print("\033[91m",end="")
        #     print(e)
        #     print("\033[0m",end="")