Advertisement
FuFsQ

ssj0.1optimizer

Dec 24th, 2020 (edited)
905
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.50 KB | None | 0 0
  1. simple expression2 Garry's mod analyzer
  2.  
  3. # -- main -- #
  4. import functional
  5. import cutter
  6. import anytree as an
  7.  
  8. functional.core.eol = '\n'
  9.  
  10. source_code = open("D:/inp2.txt", "r").read()
  11. source_code = functional.delete_comments(source_code)
  12. # source_code = functional.core.delete_spc(source_code)
  13. # source_code = functional.compress_inline(source_code, 140)
  14.  
  15. namespaces = functional.trace_namespaces(source_code, functional.create_prepared_ex_zones(source_code))
  16. """pos = 0
  17.  
  18. while pos < len(namespaces):
  19.    print("+ + + + + + + + + + + +")
  20.    print(source_code[namespaces[pos].beg:namespaces[pos].end+1])
  21.    print("- - - - - - - - - - - ->", namespaces[pos].level, "<- - -\n")
  22.  
  23.    pos += 1"""
  24.  
  25. tr = functional.core.structures.NamespaceTree(namespaces)
  26. for I in an.PreOrderIter(tr.tree):
  27.    b = I.name.beg
  28.    e = I.name.end
  29.  
  30.    print(source_code[b:e])
  31.    print("- - - - - - - - - - - - - - - - - - - - - - ")
  32.  
  33. file = open("D:/out.txt", "w")
  34. file.write(source_code)
  35. file.close()
  36.  
  37.  
  38. # -- functional -- #
  39. import core_functs as core
  40.  
  41. buffer_traced_code = {}
  42.  
  43.  
  44. def delete_spaces(src):
  45.    g = core.delete_spc(src, True)
  46.    return g
  47.  
  48.  
  49. def delete_comments(src):
  50.    g = core.trace_code(src)
  51.    return core.str_list_cutter(src, g["comments"] + g["multiline_comments"])
  52.  
  53.  
  54. def create_prepared_ex_zones(src):
  55.    return core.trace_code(src)["strings"]
  56.  
  57.  
  58. def set_eol(new_eol_symbol):
  59.    core.eol = new_eol_symbol
  60.  
  61.  
  62. def trace_namespaces(src, excluded_zones, brtype='{}'):
  63.    if len(src) == 0:
  64.        print("> stderr: functional/trace_namespaces called with src=''")
  65.        return []
  66.  
  67.    if len(excluded_zones) == 0:
  68.        print("> stderr: functional/trace_namespaces called with excluded_zones = []")
  69.        return []
  70.  
  71.    ret = []
  72.    pos = 0
  73.  
  74.    while True:
  75.        curr = core.safety_find(src, brtype[0], pos, excluded_zones)
  76.  
  77.        if curr != -1:
  78.            curr_end = core.trace_bracket(src, curr, brtype)
  79.  
  80.            xp = 0
  81.            level = 0
  82.            while xp < len(ret):
  83.                if ret[xp].end > curr:
  84.                    level += 1
  85.                xp += 1
  86.  
  87.            ths = core.structures.Namespace(curr, curr_end, level)
  88.            ret.append(ths)
  89.  
  90.            if curr+1 < len(src):
  91.                pos = curr+1
  92.            else:
  93.                break
  94.        else:
  95.            break
  96.  
  97.    return ret
  98.  
  99.  
  100. def get_global_vars(lined_src, srclen):
  101.    if len(lined_src) == 0:
  102.        print("> stderr: functional/get_global_vars called with lined_src = []")
  103.        return []
  104.  
  105.    persist_parser = core.structures.Persist("", "", "")
  106.    ret = []
  107.    ginit = {"inputs": [], "outputs": [], "persist": [], "trigger": []}
  108.    keys = ginit.keys()
  109.  
  110.    for I in lined_src:
  111.        for K in keys:
  112.            if I.find("@" + K) == 0:
  113.                ginit[K].append(I[len(K) + 2:])
  114.  
  115.    for I in keys:
  116.        for K in ginit[I]:
  117.            ret += persist_parser.parse_list(K, srclen, I)
  118.  
  119.    return ret
  120.  
  121.  
  122. def compress_inline(src, limiter=80):
  123.    if len(src) == 0:
  124.        print("> stderr: functional/compress_inline called with src = ''")
  125.        return src
  126.  
  127.    l = src.split(core.eol)
  128.    ret = ""
  129.  
  130.    line_len = 0
  131.    for I in l:
  132.        if len(I) != 0 and I[0] == '@':
  133.            ret += I.lstrip() + core.eol
  134.            continue
  135.  
  136.        if line_len <= limiter:
  137.            if line_len != 0:
  138.                ret += ' '
  139.            ret += I
  140.            line_len += len(I)+1
  141.        else:
  142.            ret += core.eol + I
  143.            line_len = len(I)+1
  144.  
  145.    return ret
  146.  
  147. # -- cutter -- #
  148. import functional
  149.  
  150.  
  151. class Cutter:
  152.    def __init__(self, src=""):
  153.        self.src = src
  154.        self.context_eol = functional.core.eol
  155.  
  156.        self.prepared = self.prepare_code()
  157.        self.lined_prepared = self.prepared.split(self.context_eol)
  158.  
  159.        self.excluded_zones = self.create_prepared_zones(self.prepared)
  160.        self.persist_parser = functional.core.structures.Persist("", "", "")
  161.        self.gvars = self.get_gvars()
  162.  
  163.    def prepare_code(self, **kwargs):
  164.        self.prepared = functional.delete_comments(self.src)
  165.        self.prepared = functional.delete_spaces(self.prepared)
  166.        return self.prepared
  167.  
  168.    def create_prepared_zones(self, src):
  169.        return functional.create_prepared_ex_zones(self.prepared)
  170.  
  171.    def get_gvars(self):
  172.        return functional.get_global_vars(self.lined_prepared, len(self.prepared))
  173.  
  174. # -- core_functs -- #
  175. import structures
  176.  
  177. eol = chr(10)
  178.  
  179.  
  180. def check_excluded(ind, ex_list):
  181.    for I in ex_list:
  182.        if I[0] <= ind <= I[1]:
  183.            return False
  184.    return True
  185.  
  186.  
  187. def safety_find(src, pattern, start, zones):
  188.    pos = start
  189.    while True:
  190.        ans = src.find(pattern, pos)
  191.        if ans != -1:
  192.            if check_excluded(ans, zones):
  193.                return ans
  194.            else:
  195.                pos = ans+1
  196.        else:
  197.            return -1
  198.  
  199.  
  200. def advfind(src, spos, nf, f):
  201.    pos = spos
  202.  
  203.    while True:
  204.        a = src.find(f, pos)
  205.  
  206.        if a != -1:
  207.            sum = 0
  208.            ctr = 0
  209.  
  210.            for I in range(a - len(nf), a):
  211.                if src[I] == nf[ctr]:
  212.                    ctr += 1
  213.                    sum += 1
  214.                else:
  215.                    break
  216.  
  217.            if sum != len(nf):
  218.                return a
  219.            else:
  220.                pos = a+1
  221.        else:
  222.            return -1
  223.  
  224.  
  225. def trace_code(src, end_of_line=eol, fullwrap_string=True):
  226.    ret = {"strings": [], "multiline_comments": [], "comments": []}
  227.  
  228.    pos = 1
  229.    while pos < len(src):
  230.        if src[pos] == '"' and src[pos-1] != '\\':  # code_line "<THIS TEXT WILL BE CAPTURED WITHOUT ">"
  231.             spos = pos
  232.             epos = advfind(src, spos+1, '\\', '"') + 1
  233.  
  234.             if epos == -1:
  235.                 break
  236.  
  237.             pos = epos+1
  238.             if fullwrap_string:
  239.                 ret["strings"].append([spos, epos])
  240.             else:
  241.                 ret["strings"].append([spos+1, epos-1])
  242.  
  243.         elif src[pos-1] == '#' and src[pos] != '[':
  244.             spos = pos-1
  245.             epos = spos+1
  246.  
  247.             if epos == -1:
  248.                 break
  249.  
  250.             while src[epos] != end_of_line and epos < len(src):
  251.                 epos += 1
  252.  
  253.             pos = epos+1
  254.             ret["comments"].append([spos, epos])
  255.         elif src[pos-1] == "#" and src[pos] == '[':
  256.             spos = pos-1
  257.             epos = src.find("]#", spos) + 2
  258.  
  259.             if epos == -1:
  260.                 break
  261.  
  262.             pos = epos+1
  263.             ret["multiline_comments"].append([spos, epos])
  264.         else:
  265.             pos += 1
  266.  
  267.     return ret
  268.  
  269.  
  270. def cut_from_string(src, f, t):
  271.     return src[:f] + src[t:]
  272.  
  273.  
  274. def str_list_cutter(src, listof: list):
  275.     if len(listof) == 0:
  276.         print("> stderr: str_list_cutter called with listof = []")
  277.         return src
  278.  
  279.     listof.sort()
  280.     ret = ""
  281.  
  282.     pos = 0
  283.     for I in listof:
  284.         ret += src[pos:I[0]]
  285.         pos = I[1]
  286.     ret += src[listof[-1][1]:]
  287.  
  288.     return ret
  289.  
  290.  
  291. def delete_spc(src, del_endls=True):
  292.     symbs = [' ', ',', '.', '+', '-', '=', '/', '%', '^', '!', '*', '{', '}', '&', '|', '$', '?']
  293.     lenght = len(src)
  294.     pos = 1
  295.     ret = "" + src[0]
  296.  
  297.     while pos < lenght-1:
  298.         if src[pos] == ' ':
  299.             is_skip = False
  300.  
  301.             if src[pos-1] in symbs or src[pos+1] in symbs:
  302.                 is_skip = True
  303.  
  304.             if is_skip:
  305.                 pos += 1
  306.                 continue
  307.             else:
  308.                 ret += src[pos]
  309.         else:
  310.             ret += src[pos]
  311.  
  312.         pos += 1
  313.  
  314.     ret += src[-1]
  315.  
  316.     if del_endls:
  317.         lines = ret.split(eol)
  318.         ret = ""
  319.         for I in lines:
  320.             if I != '':
  321.                 ret += I+eol
  322.  
  323.         pos = 1
  324.         src = '' + ret[0]
  325.         while pos < len(ret)-1:
  326.             if ret[pos] == eol:
  327.                 is_skip = False
  328.  
  329.                 if ret[pos-1] in ['(', '{', '[', ')', '}', ']'] and ret[pos+1] in ['(', '{', '[', ')', '}', ']']:
  330.                     is_skip = True
  331.  
  332.                 if is_skip:
  333.                     pos += 1
  334.                     continue
  335.                 else:
  336.                     src += ret[pos]
  337.                     pos += 1
  338.                     continue
  339.  
  340.             src += ret[pos]
  341.             pos += 1
  342.  
  343.         src += ret[-1]
  344.         return src
  345.     return ret
  346.  
  347.  
  348. def trace_bracket(src, pos, brtype="{}"):
  349.     cntr = 0
  350.  
  351.     while pos < len(src):
  352.         if src[pos] == brtype[0]:
  353.             cntr += 1
  354.  
  355.         if src[pos] == brtype[1]:
  356.             cntr -= 1
  357.  
  358.         if cntr == 0:
  359.             return pos
  360.  
  361.         pos += 1
  362.  
  363.     print("> stderr: core_functs/trace_brackets couldn't find closer-bracket, returned -1")
  364.     return -1
  365.  
  366.  
  367. def trace_brackets_rev(src, pos, brtype=")("):
  368.     cntr = 0
  369.  
  370.     while pos > 0:
  371.         if src[pos] == brtype[0]:
  372.             cntr += 1
  373.  
  374.         if src[pos] == brtype[1]:
  375.             cntr -= 1
  376.  
  377.         if cntr == 0:
  378.             return pos
  379.  
  380.         pos -= 1
  381.  
  382.     print("> stderr: core_functs/trace_brackets_rev couldn't find opener-bracket, returned -1")
  383.     return -1
  384.  
  385.  
  386. def find_nearest(src, pos, symb, direction):
  387.     it = 0
  388.  
  389.     if direction >= 1:
  390.         it = 1
  391.         while src[pos] != symb and pos < len(src):
  392.             pos += it
  393.     else:
  394.         it = -1
  395.         while src[pos] != symb and pos > -1:
  396.             pos += it
  397.  
  398.     if src[pos] != symb:
  399.         print("> stderr: core_functs/find_nearest couldn't find nearest symbol to", symb, "from pt =", pos)
  400.         return -1
  401.  
  402.     return pos
  403.  
  404.  
  405. def get_word(src, pos, direction):
  406.     if direction >= 1:
  407.         it = 1
  408.         while (not src[pos].isspace()) and (pos < len(src)):
  409.             pos += it
  410.  
  411.         while src[pos].isspace() and (pos < len(src)):
  412.             pos += it
  413.  
  414.         sp = pos
  415.  
  416.         while (not src[pos].isspace()) and (pos < len(src)):
  417.             pos += it
  418.  
  419.         return [pos, src[sp:pos+1]]
  420.     else:
  421.         it = -1
  422.  
  423.         while (not src[pos].isspace()) and pos > -1:
  424.             pos += it
  425.  
  426.         while src[pos].isspace() and (pos > -1):
  427.             pos += it
  428.  
  429.         sp = pos
  430.  
  431.         while (not src[pos].isspace()) and (pos > -1):
  432.             pos += it
  433.         print(">>>>>", pos, sp, src[pos:sp+1].strip())
  434.         return [pos, src[pos:sp+1].strip()]
  435.  
  436. # -- structures -- #
  437. import anytree as an
  438.  
  439. allowed_types = ["quaternion", "vector", "vector4", "vector2", "array", "table", "string", "number", "ranger", "bone", "wirelink", "gtable", "angle", "entity"]
  440.  
  441.  
  442. class Namespace:
  443.     def __init__(self, beginning, ending, level=0):
  444.         self.beg = abs(beginning)
  445.         self.end = abs(ending)
  446.         self.level = abs(level)
  447.         self.content = ""
  448.         self.header = ''
  449.         # function abs(A,B,C) - header
  450.         # if (STATE_A ^ STATE_B) - header
  451.  
  452.     def set_content(self, src, hed=''):
  453.         self.content = src
  454.         self.header = hed
  455.  
  456.  
  457. class NamespaceTree:
  458.     def __init__(self, traced):
  459.         pos = 0
  460.         self.tree = an.Node(Namespace(0, 0, -1))
  461.         ptr = self.tree
  462.         prev_level = -1
  463.  
  464.         while pos < len(traced):
  465.             if prev_level < traced[pos].level:
  466.                 adder = an.Node(traced[pos], ptr)
  467.                 ptr = adder
  468.                 prev_level = traced[pos].level
  469.             elif prev_level == traced[pos].level:
  470.                 ptr = ptr.parent
  471.                 adder = an.Node(traced[pos], ptr)
  472.                 ptr = adder
  473.             else:
  474.                 for I in range(abs(prev_level - traced[pos].level) + 1):
  475.                     ptr = ptr.parent
  476.                 adder = an.Node(traced[pos], ptr)
  477.                 ptr = adder
  478.                 prev_level = traced[pos].level
  479.  
  480.             pos += 1
  481.  
  482.         print(an.RenderTree(self.tree, style=an.AsciiStyle()).by_attr())
  483.  
  484.  
  485. class Persist:
  486.     def __init__(self, name: str, logic_type: str, param_type: str, namespace=Namespace(0, 0)):
  487.         if not name[0].isupper():
  488.             print("> stderr: object core_functs/Persist created with arg<name> =", name, "but "
  489.                   "persist name must begin with a capital letter, a parsing error is possible!")
  490.  
  491.         if logic_type not in allowed_types:
  492.             print("> stderr: object core_functs/Persist created with arg<logic_type> =", logic_type, "but "
  493.                   "allowed only " + ", ".join(sorted(allowed_types)), ", a parsing error is possible!")
  494.  
  495.         self.name = name
  496.         self.logic_type = logic_type
  497.         self.param_type = param_type
  498.         self.namespace_limits = namespace
  499.         self.defined_name = name
  500.  
  501.     def parse_list(self, src_line, src_len, param_type="persist"):
  502.         ret = []
  503.         src_line = src_line.strip()
  504.         pos = 0
  505.  
  506.         while pos < len(src_line):
  507.             if src_line[pos] not in ['[', ']', ' ']:
  508.                 end = src_line.find(' ', pos)
  509.                 if end == -1:
  510.                     end = len(src_line)
  511.  
  512.                 ths = src_line[pos:end]
  513.                 tpos = ths.find(':')
  514.                 ths_type = ""
  515.  
  516.                 if tpos == -1:
  517.                     ths_type = "number"
  518.                 else:
  519.                     ths_type = ths[tpos+1:]
  520.  
  521.                 if tpos != -1:
  522.                     ths_name = ths[:tpos]
  523.                 else:
  524.                     ths_name = ths
  525.  
  526.                 ret.append(Persist(ths_name, ths_type, param_type, namespace=Namespace(0, src_len)))
  527.                 pos = end
  528.             elif src_line[pos] == '[':
  529.                 end = src_line.find(']', pos)
  530.                 closed_names = src_line[pos+1:end].split(' ')
  531.                 ends = src_line.find(' ', end)
  532.                 ths_type = ''
  533.  
  534.                 if src_line[end+1] != ':':
  535.                     ths_type = "number"
  536.                 else:
  537.                     if ends != -1:
  538.                         ths_type = src_line[end+2:ends]
  539.                     else:
  540.                         ths_type = src_line[end+2:]
  541.  
  542.                 for I in closed_names:
  543.                     ret.append(Persist(I, ths_type, param_type, namespace=Namespace(0, src_len)))
  544.  
  545.                 pos = ends
  546.                 if pos == -1:
  547.                     break
  548.             pos += 1
  549.         return ret
  550.  
  551.     def debug_out(self):
  552.         print("> stderr: name =", self.name)
  553.         print("> stderr: self.logic_type =" + self.logic_type + "\n"
  554.               "self.param_type =" + self.param_type + "\n"
  555.               "self.defined_name =" + self.name + "\n"
  556.               )
  557.  
  558. # -- END -- #
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement