Advertisement
Guest User

WyvernSL - V5

a guest
Apr 18th, 2015
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.10 KB | None | 0 0
  1. import os,re,sys,string,random
  2.  
  3. _synerr = 'error: invalid syntax'
  4. _generr = lambda x,y,z: '%s: %s (in line: \'%s\')'%(type(x).__name__, y, z)
  5. _alterr = lambda x,y: 'error: %s (in line: \'%s\')'%(x,y)
  6. _plnerr = lambda x: 'error: %s'%x
  7.  
  8. reserved = list(string.printable[26+26+10:-7])
  9. nums = list(range(10))
  10. var = {}
  11.  
  12. def mexp(s,eval_s=None): # Take string, return bool
  13.     if type(s) != str: return False
  14.     s = s.strip(' ')
  15.     l = []
  16.     for x in list(s.replace(' ','')):
  17.         if (x in (list(str(y) for y in range(9)))) or (x in ['+','-','*','/','(',')']):
  18.             l.append(x)
  19.     if ''.join(l) == s.replace(' ','') and (l[0].isdigit() if len(l) != 0 else False): a = True
  20.     else: a = False
  21.     return a
  22.  
  23. def issym(s):
  24.     if type(s) != str: return False
  25.     c = 0
  26.     for x in list(str(s)):
  27.         if x in reserved: c = c+1
  28.     if c == len(s): return True
  29.     return False
  30.  
  31. def isint(s):
  32.     if not type(s) in [int,str]: return False
  33.     try: int(s)
  34.     except: return False
  35.     return True
  36. isqstr = lambda x: ((True if x.startswith('"') and x.endswith('"') else False) if isinstance(x, str) else False)
  37. issstr = lambda x: ((True if x.startswith("'") and x.endswith("'") else False) if isinstance(x, str) else False)
  38. isproc = lambda x: ((True if x.startswith('(') and x.endswith(')') else False)  if isinstance(x, str) else False)
  39. write = lambda x: sys.stderr.write('%s\n'%str(x))
  40.  
  41. def symbol():
  42.     global _s,_dqs,_i,_p,_sym,_mxp,_bool,_none,_stack,commands,procs,o_types,\
  43.            o_s,o_dqs,o_i,o_p,o_sym,o_mxp,o_bool,o_stack,o_none
  44.     _s = 'string'; o_s = "optional %s"%_s
  45.     _dqs = 'double-quoted string'; o_dqs = "optional %s"%_dqs
  46.     _i = 'int'; o_i = "optional %s"%_i
  47.     _sym = 'symbol'; o_sym = "optional %s"%_sym
  48.     _bool = 'bool'; o_bool = "optional %s"%_bool
  49.     _stack = 'stack'; o_stack = "optional %s"%_stack
  50.     _none = 'none'; o_none = "optional %s"%_none
  51.     types = [_s,_dqs,_i,_sym,_bool,_stack,_none]
  52.     o_types = [o_s,o_dqs,o_i,o_sym,o_bool,o_stack,o_none]
  53.     commands = {'if':[
  54.             [_dqs,_i,_bool], # first comparison
  55.             [_sym],
  56.             [_dqs,_i,_bool], # second comparison
  57.             [_sym]
  58.         ], # end of the "if" parsing tree
  59.         'print':[
  60.             [o_dqs,o_i,o_bool,o_none,_dqs,_i,_bool,_none]
  61.         ], # end of "print" parsing tree
  62.         'def':[
  63.             [_s],
  64.             [_dqs,_i,_bool,o_dqs,o_i,o_bool]
  65.         ], # end of def parsing tree
  66.         'input':[
  67.             [_s],
  68.             [o_dqs,_dqs]
  69.         ],
  70.         'push':[
  71.             [_s],
  72.             [_dqs,_i,_bool,_stack]
  73.         ] # end of push parsing tree
  74.         }
  75.     procs = { # define global procedure calls for use by
  76.     'eval':lambda x: _eval(tokenize(x)),\
  77.     'null?':lambda x: x==None or x==[] or x=='' or x=='Null',\
  78.     'var?':lambda x: (True if x in var.keys() else False),\
  79.     'proc?': lambda x: (True if x in procs.keys() else False),\
  80.     'bool?': lambda x: (True if (x == True or 'True') or (x == False or 'False') else False),\
  81.     'return': lambda x: (x if not mexp(x) else eval(x)),\
  82.     'equ': lambda x: compact_if('==',x),\
  83.     'neq': lambda x: compact_if('!=',x),\
  84.     'geq': lambda x: compact_if('>=',x),\
  85.     'leq': lambda x: compact_if('<=',x),\
  86.     'aneq': lambda x: compact_if('<>',x),\
  87.     'type': lambda x: gettype(x),\
  88.     'random':lambda x: abs(random.randrange(int(x.split()[0]),int(x.split()[1]))),\
  89.     'math':lambda x: (eval(x) if mexp(x) else x),\
  90.     'convert': lambda x: converttype(x),\
  91.     'valueof': lambda x: getvar(x),\
  92.     }
  93. symbol()
  94.  
  95. def gettype(arg):
  96.     if arg in var.keys(): return
  97.  
  98. def getvar(arg):
  99.     if arg in var.keys(): return var[arg]
  100.     else:
  101.         write(_plnerr('unknown variable name "%s" given to valueof'%arg))
  102.         return ''
  103.  
  104. def converttype(args):
  105.     args = tokenizer(args.replace(';;',' '))
  106.     transferables = {_i:[_dqs,_i,_bool],_dqs:[_dqs,_i,_bool],_bool:[_i,_dqs,_bool]}
  107.     if args[1] == _i and isint(args[0]): return [_i,args[0]]
  108.     elif args[1] == _dqs and isqstr(args[0]): return [_dqs,args[0]]
  109.     elif args[1] == _bool and args[0] in ['true','false']: return [_bool,{'true':True,'false':False}[args[0]]]
  110.     elif args[1] == _stack:
  111.         write(_plnerr('can\'t change from stack type using convert, use join instead'))
  112.         return ''
  113.     else:
  114.         write(_plnerr('can\'t change type of value %s from %s to %s'%(args[0],atomizer(args[0])[0],args[1])))
  115.         return ''
  116.    
  117.  
  118. def compact_if(comp,args):
  119.     orig = args
  120.     args = args.split(';;')
  121.     if len(args) != 2:
  122.         print 'error: invalid amount of arguments provided'
  123.         return False
  124.     try:
  125.         exps = {
  126.             '==':(True if args[0].rstrip().lstrip()==args[1].rstrip().lstrip() else False),
  127.             '!=':(True if args[0].rstrip().lstrip()!=args[1].rstrip().lstrip() else False),
  128.             '<>':(True if args[0].rstrip().lstrip()!=args[1].rstrip().lstrip() else False),
  129.             '>=':(True if args[0].rstrip().lstrip()>=args[1].rstrip().lstrip() else False),
  130.             '<=':(True if args[0].rstrip().lstrip()<=args[1].rstrip().lstrip() else False)}
  131.         return exps[comp]
  132.     except Exception as e: write(_generr(type(e).__name__, e, orig)); return False
  133.  
  134. def getprocs(s): # Takes string, tokenizes it and yea
  135.     if not isproc(s): return _alterr('process isn\'t correctly defined', s)
  136.     s = s[1:-1] #del s[0];del s[-1]
  137.     l = tokenizer(s)
  138.     n = []
  139.     for x in l:
  140.         if isproc(x):
  141.             n.append(getprocs(x))
  142.         elif mexp(x):
  143.             n.append(eval(x))
  144.         else: n.append(x)
  145.     l = n
  146.     if l[0] in procs.keys(): return procs[s.split()[0]](' '.join(s.split()[1:]))
  147.     else: print _alterr('unknown process name', ' '.join(l))
  148.     return '#no-op'
  149.  
  150. def tokenizer(s): # Take string, return tokenized list
  151.     if isinstance(s, list): s = ' '.join(s)
  152.     t = []
  153.     tokenizer_ = r'''\s*(,@|\((?:[\\].|[^\\"])*?\)|[('`,)]|"(?:[\\].|[^\\"])*"|;.*|[^\s('"`,)]*)(.*)'''
  154.     inline = lambda x: list(re.match(tokenizer_, x).groups())
  155.     a = inline(s)
  156.     b = [a[0]]
  157.     for _ in range(len(s.split())):
  158.         a = inline(a[1])
  159.         b.append(a[0])
  160.     while '' or ' ' in b:
  161.         b = b.remove('')
  162.         try: b = b.remove(' ')
  163.         except: pass
  164.     return b
  165.  
  166. def atomizer(l): # Return atomized list
  167.     n = []
  168.     if isinstance(l, str): l = [l]
  169.     for x in l:
  170.         if isint(x): n.append([_i, int(x)])
  171.         elif isqstr(x): n.append([_dqs, x.replace('"','')])
  172.         elif issstr(x): n.append([_sqs, x.replace("'",'')])
  173.         elif isproc(x): n.append(atomizer([getprocs(x)])[0])
  174.         elif x in var.keys():
  175.             n.append(var[x])
  176.         elif issym(x): n.append([_sym, x])
  177.         elif mexp(x): n.append([_i, eval(x)])
  178.         elif x == 'true' or x == True: n.append([_bool, True])
  179.         elif x == 'false' or x == False: n.append([_bool, False])
  180.         elif x == 'nul': n.append([_none, ""])
  181.         else: n.append([_s, x])
  182.     return n
  183.  
  184. def r_sub(arg, lst): # internal module: arg = str, lst = list
  185.     # so i made the mistake of not commenting what this does... i'll just leave it here...
  186.     for x in lst:
  187.         if x == arg[0]: return True
  188.     return False
  189.  
  190. def mkl_printable(l):
  191.     n = []
  192.     for x in l: n.append(str(x))
  193.     return n
  194.  
  195. def requires(l,mode='loud'): # Return boolean if l matches command definition
  196.     order,tokens = [],[]
  197.     _l = l
  198.     c = -1
  199.     returner = [l[0][1]]
  200.     for x in l:
  201.         order.append(x[0])
  202.         tokens.append(x[1])
  203.     if not order[0] == _s:
  204.         if not mode == 'silent': write(_plnerr('unknown command token: %s (typeof %s)'%(tokens[0],order[0])))
  205.         return False
  206.     elif tokens[0] not in commands.keys():
  207.         if not mode == 'silent': write(_plnerr('unknown command: %s'%tokens[0]))
  208.         return False
  209.     retain = tokens[:]
  210.     keyword = tokens[0]; del tokens[0]; del order[0]
  211.     for _ in commands[keyword]:
  212.         c = c+1
  213.         try:
  214.             if order[c] in _: pass
  215.             else:
  216.                 if not mode == 'silent':
  217.                     print 1
  218.                     write(_plnerr('unknown token in line: "%s"'%' '.join(mkl_printable(retain))))
  219.                     write('token: %s (position in string: %d)'%(tokens[c],c+1))
  220.                     write('type : %s (expected %s)'%(order[c],' or '.join(_)))
  221.                 return False
  222.         except IndexError:
  223.             if _ in o_types:
  224.                 _l.append([_none, ""])
  225.                 tokens.append("blank")
  226.             else:
  227.                 if not mode == 'silent':
  228.                     print 2
  229.                     write(_plnerr('missing token in line: "%s"'%' '.join(mkl_printable(retain))))
  230.     return True if _l == l else [True, _l]
  231.  
  232. def cleanup(l):
  233.     n = []
  234.     for x in l:
  235.         if x != [_sym, '']: n.append(x)
  236.     return n
  237.    
  238. def preproc(l): # take list, pre-process concat's and stuff
  239.     c = -1
  240.     skip = False
  241.     n = list()
  242.     _n = list()
  243.     multiline = False
  244.     _l = l # retain l, just in case
  245.     if (l[0] == '#' or l[0] == '//' if len(l) != 0 else False): return '#no-op'
  246.     for token in l:
  247.         c = c+1
  248.         if skip != True:
  249.             if token == '+':
  250.                 if (not l[c+1] == '+' and c != 0):
  251.                     del n[c-1]
  252.                     use = l[c-1]+l[c+1]
  253.                     del l[c+1]
  254.                 else:
  255.                     write(_plnerr('unexpected concat token at position %d'%c))
  256.                     return '#no-op'
  257.                 n.append(use) # append the two tokens either side (+1 & -1) of '+' token to the list while deleting previous list element in n and deleting next element in l
  258.                 # if in the future a retained version of l is needed, see variable _l
  259.             elif token == '#': skip = True
  260. ##            elif token == '\\':
  261. ##                try:
  262. ##                    multiline = True
  263. ##                    n = [[n]]
  264. ##                    if preproc(l[c+1:])[0] == True:
  265. ##                        n.append([preproc(l[c+1:])))
  266. ##                    else:
  267. ##                        n.append(l[c+1:])
  268. ##                except RuntimeError: throw(_plnerr('maximum single-line command length exceeded'))
  269.             else:
  270.                 n.append(token)
  271.     return n
  272.  
  273. def _detyper(l):
  274.     n = {}
  275.     c = -1
  276.     for token in l:
  277.         c = c+1
  278.         n[c] = token
  279.     return n
  280.  
  281. def detyper(l,i):
  282.     n = []
  283.     for token in l: n.append(token[i] if i < len(token) and i > 0 else token[-1])
  284.     return n
  285.  
  286. def to_string(l):
  287.     converter = {
  288.         _dqs:lambda x: '"%s"'%x,
  289.         _i:lambda x: x,
  290.         _sym:lambda x: x,
  291.         _bool:lambda x: repr(x).lower(),
  292.     }
  293.     return converter[l[0]](l[1])
  294.  
  295. def throw(error):
  296.     write(error)
  297.     exit()
  298.  
  299. def _eval(l):
  300.     if isinstance(requires(l,'silent'), list):
  301.         l = requires(l)[1]
  302.     elif requires(l) != True: return ''
  303.     global var
  304.     _l = l
  305.     l = detyper(_l,1)
  306.     if l[0] == 'print': return l[1]
  307.     elif l[0] == 'if':
  308.         # if a == b: thiiiiiings
  309.         # 0  1 2  34 5
  310.         c,op,c2,blank = l[1:5]
  311.         exps = {
  312.             '==':(True if c==c2 else False),
  313.             '!=':(True if c!=c2 else False),
  314.             '<>':(True if c!=c2 else False),
  315.             '>=':(True if c>=c2 else False),
  316.             '<=':(True if c<=c2 else False)}
  317.         if exps[op] == True:
  318.             if requires(_l[5:]):
  319.                 return _eval(_l[5:])
  320.     elif l[0] == 'def': var[l[1]] = _l[2]
  321.     elif l[0] == 'input': var[l[1]] = [_dqs, '%s'%raw_input(l[2])]
  322.     elif l[0] == 'push':
  323.         if l[1] in var.keys() and isinstance(var[l[1]], list): var[l[1]] = var[l[1]].append(_l[2])
  324.         elif l[1] not in var.keys(): var[l[1]] = [_l[2]]
  325.         return
  326.     elif l[0] == 'get':
  327.         if l[1] in var.keys():
  328.             try: return var[l[1]][l[2]]
  329.             except IndexError: throw(_plnerr('stack id of %s isn\'t in stack "%s"'%(l[2],l[1])))
  330.         else: throw(_plnerr('unknown stack name "%s"'%l[1]))
  331.  
  332.  
  333. def handle(s): # take string, do all messy stuff and pass data to _eval()
  334.     s = tokenizer(s) # tokenize! str == list
  335.     s = preproc(s) # preprocess, no comments and concat'ed strs/ints are concat'd
  336. ##    if isinstance(s, list):
  337. ##        if s[0] == True:
  338. ##            l = None
  339. ##            for command in s[1:]:
  340. ##                l.append
  341.     if s == '#no-op' or s == False: return '' # if s == comment, return nothing, print nothing :)
  342.     s = atomizer(s) # make the tokenized list Wyvern-readable, helps with converting to python readable types as well
  343.     s = _eval(cleanup(s))
  344.     return (s if not s == '#no-op' else '')
  345.  
  346. def repl(input_='none',prompt='==> '):
  347.     global repl_line,mode; repl_line = 0; mode = 'repl'
  348.     while input_ != 'end':
  349.         repl_line = repl_line+1
  350.         input_ = raw_input('@%d%s'%(repl_line,prompt))
  351.         write(handle(input_))
  352.  
  353. def fepl(_file):
  354.     global line_buffer, line_id, mode; line_buffer = []; line_id = -1; mode = 'fepl'
  355.     with open(_file, 'r').readlines() as lines:
  356.         for line in lines: line_buffer.append(preproc(line))
  357.     for line in line_buffer:
  358.         line_id = line_id + 1
  359.         write(handle(line))
  360.  
  361. repl()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement