staffehn

Better Functions Python compiler script V0.2

May 20th, 2017
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.52 KB | None | 0 0
  1. '''
  2.  
  3. =============================================
  4. =============================================
  5. NEWEST VERSION: https://pastebin.com/0KHCV7LU
  6. =============================================
  7. =============================================
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15. next iteration of still very simple skript: reworked file structure
  16.  
  17. you now need in "wordsaveXYZ/data/functions/src" subdirectory your ".mcfun" files
  18. i.e. in ".../src/testNamespace/testFunction.mcfun" the example from last time -- compare https://pastebin.com/8Xcv3M7b
  19.  
  20. examples for "testFunction.mcfun":
  21. ==============================================================================================================
  22. # simple introdution example
  23.  
  24. say 123
  25.  
  26. execute @s ~ ~ ~ #{
  27.   say 1
  28.   say 2
  29.   say 3
  30.   execute @a ~ ~ ~ #{ say hi
  31.                       say ho }# if @s[type=Player]
  32. }#
  33.  
  34. say hello bye
  35.  
  36. =======================================  OUTPUT:
  37. Successfully reloaded loot tables, advancements and
  38. functions
  39. [staffehn] 123
  40. [staffehn] 1
  41. [staffehn] 2
  42. [staffehn] 3
  43. [staffehn] hi
  44. [staffehn] ho
  45. [staffehn] hello bye
  46. Executed 11 command(s) from function 'testNamespace:testFunction'
  47.  
  48. ==============================================================================================================
  49.  
  50. # the old example - for reference
  51.  
  52. say hi
  53. execute @a ~ ~ ~ #{
  54.    
  55.    say ho
  56.    tp ~ ~1 ~
  57.    execute @e[r=10,type=!Player] ~ ~ ~ #{  #nesting is okay
  58.        say I AM CLOSE
  59.        scoreboard players add @s objxyz 1
  60.    }#
  61.    
  62.    # Basically every "#{...}#" will be replaced by "function namespaceABC:compiled/XYZ" and
  63.    # the file XYZ will be created, containing all of "...", but processed the same
  64.    # way recursively. "function ... if/unless @.." is not supported yet.
  65.    
  66. }#
  67. ==============================================================================================================
  68.  
  69. then you compile.py from the same location as before (I mean the location of compile.py, namely "%appdata%/.minecraft/saves/wordsaveXYZ/data/functions/compile.py"
  70.  
  71. then the converted files will for example be "wordsaveXYZ/data/functions/testNamespace/testFunction.mcfunction"
  72.  
  73. so you can call it by "function testNamespace:testFunction"
  74.  
  75. also the compiled extra files will now be in their namespaces.. very important for sharing your compiled results as a library
  76. with other mapmakers: for example if theres at least one "#{...}#" block in the testFunction the file
  77. "wordsaveXYZ/data/functions/testNamespace/compiled/0.mcfunction" will be created and used.
  78.  
  79. Have fun, give me feedback ;-)
  80. I'm planning on changing the syntax in the future and add features, probably the "#"s will go somehow and we'll get first class "if/unless" support
  81. right now you can already do "#{...}# unless @s[...]" constructs, as came to mind to me today
  82.  
  83. now onto the script:
  84. ===============================================================================================================
  85. '''
  86.  
  87. import os
  88. import errno
  89. import collections
  90. import shutil
  91.  
  92. nameCounter = collections.defaultdict(lambda:0)
  93. nextToWrite = collections.defaultdict(lambda:0)
  94. funsToWrite = collections.defaultdict(list)
  95.  
  96. def match(str):
  97.     res = [-1]
  98.     depth = 0
  99.     for i, c in enumerate(str):
  100.       if c == "#":
  101.         if i+1 < len(str) and str[i+1] == "{":
  102.             if depth == 0: res.append(i)
  103.             depth += 1
  104.         elif i > 0 and str[i-1] == "}":
  105.             depth -= 1
  106.             if depth == 0: res.append(i)
  107.     res.append(len(str))
  108.     return res            
  109.  
  110. def createFile(k,name,content):
  111.     global nameCounter
  112.     global funsToWrite
  113.     try:
  114.         os.makedirs(os.path.dirname(name))
  115.     except OSError as e:
  116.         if e.errno != errno.EEXIST:
  117.           raise
  118.     with open(name, "w") as f:
  119.         f.write("# DON'T EDIT TIS FILE, OR CHANGES MIGHT BE LOST ON RECOMPILATION!\n\n")
  120.         ixs = match(content)
  121.         out = 1
  122.         for i,j in zip(ixs, ixs[1:]):
  123.             if out == 1:
  124.                 out = 0
  125.                 f.write(content[i+1:j])
  126.             elif out == 0:
  127.                 out = 1
  128.                 funsToWrite[k].append(content[i+2:j-1])
  129.                 f.write("function "+k+":compiled/"+str(nameCounter[k]))
  130.                 nameCounter[k] += 1
  131.                
  132.  
  133.  
  134. top = os.getcwd()
  135.  
  136. dirs = [f for f in os.listdir(top) if not os.path.isfile(f)]
  137. for d in dirs:
  138.     for d1 in [d2 for d2 in os.listdir(os.path.join(top,d)) if (not os.path.isfile(d2)) and d2 == "compiled"]:
  139.         shutil.rmtree(os.path.join(top,d,d1))
  140.  
  141. if "src" in dirs:
  142.     for root, dirs, filenames  in os.walk(os.path.join(top,"src")):
  143.         for name in filenames:
  144.             space = ""
  145.             rest, next = os.path.split(root)
  146.             pathnew = next
  147.             while next != "src":
  148.               path = pathnew
  149.               space = next
  150.               rest, next = os.path.split(rest)
  151.               pathnew = os.path.join(next,pathnew)
  152.  
  153.             sth, ext = os.path.splitext(name)
  154.             if ext == ".mcfun":
  155.                 file = open(os.path.join(root, name),'r')
  156.                 content=file.read()
  157.                 file.close()
  158.                 newname = os.path.join(top,path, name+"ction") # TODO
  159.                 createFile(space,newname,content)
  160.         for k in funsToWrite:
  161.             while (len(funsToWrite[k]) != 0):
  162.                 fun = funsToWrite[k][0]
  163.                 funsToWrite[k] = funsToWrite[k][1:]
  164.                 createFile(k,os.path.join(top,space,"compiled",str(nextToWrite[k])+".mcfunction"),fun)
  165.                 nextToWrite[k] += 1
Advertisement
Add Comment
Please, Sign In to add comment